gridsmith-ui 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -1
- package/dist/charts.d.ts +2 -2
- package/dist/charts.js +2 -2
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +5 -5
- package/dist/chat.js.map +1 -1
- package/dist/{chunk-64TXZ4L7.js → chunk-2ROVDVLZ.js} +3 -3
- package/dist/{chunk-64TXZ4L7.js.map → chunk-2ROVDVLZ.js.map} +1 -1
- package/dist/chunk-66JJCQU3.js +46 -0
- package/dist/chunk-66JJCQU3.js.map +1 -0
- package/dist/chunk-7RKC5C7G.js +35 -0
- package/dist/chunk-7RKC5C7G.js.map +1 -0
- package/dist/{chunk-OTCEJN64.js → chunk-BRAXJEEP.js} +7 -6
- package/dist/chunk-BRAXJEEP.js.map +1 -0
- package/dist/{chunk-IXR4UEF4.js → chunk-DQCHCLEJ.js} +9 -8
- package/dist/chunk-DQCHCLEJ.js.map +1 -0
- package/dist/{chunk-5TUVX4B2.js → chunk-EIWXVICU.js} +3 -3
- package/dist/{chunk-5TUVX4B2.js.map → chunk-EIWXVICU.js.map} +1 -1
- package/dist/{chunk-SFY2KMHG.js → chunk-FD4YED7O.js} +5 -4
- package/dist/chunk-FD4YED7O.js.map +1 -0
- package/dist/{chunk-MD2EFMES.js → chunk-GXMTS3YD.js} +3 -3
- package/dist/{chunk-MD2EFMES.js.map → chunk-GXMTS3YD.js.map} +1 -1
- package/dist/chunk-HTXP5BMM.js +38 -0
- package/dist/chunk-HTXP5BMM.js.map +1 -0
- package/dist/{chunk-R5NFCEZ3.js → chunk-OPFJEL3Z.js} +52 -24
- package/dist/chunk-OPFJEL3Z.js.map +1 -0
- package/dist/{chunk-EKBWWA6P.js → chunk-R4GXKH4U.js} +7 -7
- package/dist/chunk-R4GXKH4U.js.map +1 -0
- package/dist/{chunk-PO65I3MQ.js → chunk-TRDXWHD2.js} +6 -6
- package/dist/chunk-TRDXWHD2.js.map +1 -0
- package/dist/{chunk-2CKSSWYG.js → chunk-YUTF2X6B.js} +39 -20
- package/dist/chunk-YUTF2X6B.js.map +1 -0
- package/dist/data-grid.js +18 -11
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.js +2 -2
- package/dist/editor.js +44 -24
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +46 -24
- package/dist/index.js +404 -295
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +18 -11
- package/dist/kanban.js.map +1 -1
- package/dist/resizable.js +20 -15
- package/dist/resizable.js.map +1 -1
- package/dist/roots.css +91 -15
- package/dist/tokens.css +111 -26
- package/dist/utils.d.ts +47 -5
- package/dist/utils.js +15 -5
- package/dist/utils.js.map +1 -1
- package/dist/virtualized.js +17 -11
- package/dist/virtualized.js.map +1 -1
- package/dist-static/tokens.css +111 -26
- package/package.json +2 -2
- package/dist/chunk-2CKSSWYG.js.map +0 -1
- package/dist/chunk-EKBWWA6P.js.map +0 -1
- package/dist/chunk-IXR4UEF4.js.map +0 -1
- package/dist/chunk-M2QRNBDQ.js +0 -42
- package/dist/chunk-M2QRNBDQ.js.map +0 -1
- package/dist/chunk-OTCEJN64.js.map +0 -1
- package/dist/chunk-PO65I3MQ.js.map +0 -1
- package/dist/chunk-R5NFCEZ3.js.map +0 -1
- package/dist/chunk-SFY2KMHG.js.map +0 -1
package/dist/charts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/lib/chart-utils.ts","../../../showcase/src/lib/chart-categories.ts","../../../showcase/src/components/charts/ChartWrapper.tsx","../../../showcase/src/components/charts/value-format.ts","../../../showcase/src/components/charts/ChartPrimitives.tsx","../../../showcase/src/components/charts/BarChart.tsx","../../../showcase/src/components/charts/LineChart.tsx","../../../showcase/src/components/charts/AreaChart.tsx","../../../showcase/src/components/charts/PieChart.tsx","../../../showcase/src/components/charts/CompositeChart.tsx","../../../showcase/src/components/charts/ScatterChart.tsx","../../../showcase/src/components/charts/RadarChart.tsx","../../../showcase/src/components/charts/RadialBarChart.tsx","../../../showcase/src/components/charts/FunnelChart.tsx","../../../showcase/src/lib/token-algorithms.ts","../../../showcase/src/components/charts/TreemapChart.tsx","../../../showcase/src/components/charts/SankeyChart.tsx","../../../showcase/src/components/charts/Sparkline.tsx","../../../showcase/src/components/ChartContainer.tsx"],"names":["k","ChartWrapper","categoryKind","useState","useLayoutEffect","useContext","jsxs","jsx","useMemo","useEffect","forwardRef","BarChart","useRef","RechartsBarChart","Fragment","LineChart","ResponsiveContainer","RechartsLineChart","CartesianGrid","XAxis","YAxis","Tooltip","AreaChart","RechartsAreaChart","PieChart","RechartsPieChart","CompositeChart","values","lineValues","Bar","Line","ScatterChart","RechartsScatterChart","RadarChart","RechartsRadarChart","RadialBarChart","RechartsRadialBarChart","FunnelChart","RechartsFunnelChart","TreemapChart","SankeyChart","RechartsSankey","Sparkline","useId","Area"],"mappings":";;;;;;;;;;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,iBAAA,GAAoB;AAAA,EACxB,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,eAAA,GAA0C;AAAA,EAC9C,cAAA,EAAgB,SAAA;AAAA,EAChB,cAAA,EAAgB,SAAA;AAAA,EAChB,cAAA,EAAgB,SAAA;AAAA,EAChB,cAAA,EAAgB,SAAA;AAAA,EAChB,cAAA,EAAgB,SAAA;AAAA,EAChB,cAAA,EAAgB,SAAA;AAAA,EAChB,mBAAA,EAAqB,yBAAA;AAAA,EACrB,mBAAA,EAAqB,wBAAA;AAAA,EACrB,mBAAA,EAAqB,wBAAA;AAAA,EACrB,mBAAA,EAAqB,wBAAA;AAAA,EACrB,mBAAA,EAAqB,wBAAA;AAAA,EACrB,mBAAA,EAAqB,yBAAA;AAAA,EACrB,iBAAA,EAAmB,SAAA;AAAA,EACnB,oBAAA,EAAsB,SAAA;AAAA,EACtB,mBAAA,EAAqB,SAAA;AAAA,EACrB,qBAAA,EAAuB,SAAA;AAAA,EACvB,iBAAA,EAAmB;AACrB,CAAA;AAIA,IAAI,WAAA,GAAc,CAAA;AAClB,IAAM,WAAA,uBAAkB,GAAA,EAAgB;AACxC,IAAI,gBAAA,GAAmB,KAAA;AAEvB,SAAS,cAAA,GAAiB;AACxB,EAAA,IAAI,gBAAA,IAAoB,OAAO,QAAA,KAAa,WAAA,EAAa;AACzD,EAAA,gBAAA,GAAmB,IAAA;AAEnB,EAAA,MAAM,QAAA,GAAW,IAAI,gBAAA,CAAiB,CAAC,SAAA,KAAc;AACnD,IAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,MAAA,IAAI,CAAA,CAAE,kBAAkB,WAAA,EAAa;AACnC,QAAA,WAAA,EAAA;AACA,QAAA,KAAA,MAAW,GAAA,IAAO,aAAa,GAAA,EAAI;AACnC,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,QAAA,CAAS,OAAA,CAAQ,SAAS,eAAA,EAAiB;AAAA,IACzC,UAAA,EAAY,IAAA;AAAA,IACZ,eAAA,EAAiB,CAAC,WAAW;AAAA,GAC9B,CAAA;AACH;AAEA,SAAS,UAAU,EAAA,EAAgB;AACjC,EAAA,cAAA,EAAe;AACf,EAAA,WAAA,CAAY,IAAI,EAAE,CAAA;AAClB,EAAA,OAAO,MAAM;AAAE,IAAA,WAAA,CAAY,OAAO,EAAE,CAAA;AAAA,EAAG,CAAA;AACzC;AAEA,SAAS,WAAA,GAAc;AACrB,EAAA,OAAO,WAAA;AACT;AAEA,SAAS,iBAAA,GAAoB;AAC3B,EAAA,OAAO,CAAA;AACT;AAEO,SAAS,aAAa,KAAA,EAAuB;AAClD,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,eAAA,CAAgB,KAAK,CAAA,IAAK,SAAA;AACtE,EAAA,MAAM,GAAA,GAAM,iBAAiB,QAAA,CAAS,eAAe,EAAE,gBAAA,CAAiB,KAAK,EAAE,IAAA,EAAK;AACpF,EAAA,OAAO,GAAA,IAAO,eAAA,CAAgB,KAAK,CAAA,IAAK,SAAA;AAC1C;AAEO,SAAS,cAAA,CAAe,KAAA,EAAe,IAAA,GAAO,KAAA,EAAiB;AACpE,EAAA,MAAM,OAAA,GAAU,oBAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,iBAAiB,CAAA;AAC9E,EAAA,MAAM,CAAC,QAAQ,SAAS,CAAA,GAAI,SAAmB,MAAM,cAAA,CAAe,KAAA,EAAO,IAAI,CAAC,CAAA;AAKhF,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,SAAA,CAAU,aAAA,CAAc,KAAA,EAAO,IAAI,CAAC,CAAA;AAAA,EACtC,CAAA,EAAG,CAAC,KAAA,EAAO,IAAA,EAAM,OAAO,CAAC,CAAA;AAGzB,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,cAAA,CAAe,OAAe,IAAA,EAAyB;AAC9D,EAAA,MAAM,MAAA,GAAS,OAAO,iBAAA,GAAoB,YAAA;AAC1C,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAM,CAAA;AACtC,IAAA,MAAA,CAAO,IAAA,CAAK,eAAA,CAAgB,KAAK,CAAA,IAAK,SAAS,CAAA;AAAA,EACjD;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,aAAA,CAAc,OAAe,IAAA,EAAyB;AAC7D,EAAA,MAAM,MAAA,GAAS,OAAO,iBAAA,GAAoB,YAAA;AAC1C,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAM,CAAA;AACtC,IAAA,MAAA,CAAO,IAAA,CAAK,YAAA,CAAa,KAAK,CAAC,CAAA;AAAA,EACjC;AACA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,iBAAiB,KAAA,EAAuB;AACtD,EAAA,MAAM,OAAA,GAAU,oBAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,iBAAiB,CAAA;AAC9E,EAAA,MAAM,CAAC,OAAO,QAAQ,CAAA,GAAI,SAAS,MAAM,eAAA,CAAgB,KAAK,CAAA,IAAK,SAAS,CAAA;AAG5E,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,QAAA,CAAS,YAAA,CAAa,KAAK,CAAC,CAAA;AAAA,EAC9B,CAAA,EAAG,CAAC,KAAA,EAAO,OAAO,CAAC,CAAA;AAGnB,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,gBAAA,GAA4B;AAC1C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,MAAM;AAC3C,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,IAAA,OAAO,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AAAA,EAC/D,CAAC,CAAA;AAED,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA;AAChE,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAA2B,UAAA,CAAW,EAAE,OAAO,CAAA;AAChE,IAAA,GAAA,CAAI,gBAAA,CAAiB,UAAU,OAAO,CAAA;AACtC,IAAA,OAAO,MAAM,GAAA,CAAI,mBAAA,CAAoB,QAAA,EAAU,OAAO,CAAA;AAAA,EACxD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,OAAA;AACT;AAEO,IAAM,iBAAA,GAAoB,CAAC,QAAA,KAAgC;AAChE,EAAA,MAAM,UAAU,gBAAA,EAAiB;AACjC,EAAA,OAAO,QAAA,KAAa,SAAS,CAAC,OAAA;AAChC,CAAA;;;ACzIA,IAAM,cAAA,GAAiB;AAAA,EACrB,SAAA;AAAA,EAAW,UAAA;AAAA,EAAY,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,QAAA;AAAA,EAAU,WAAA;AAAA,EAAa,SAAA;AAAA,EAAW,UAAA;AAAA,EAAY,UAAA;AAAA,EAC9G,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO;AAChF,CAAA;AACA,IAAM,gBAAA,GAAmB;AAAA,EACvB,QAAA;AAAA,EAAU,SAAA;AAAA,EAAW,WAAA;AAAA,EAAa,UAAA;AAAA,EAAY,QAAA;AAAA,EAAU,UAAA;AAAA,EAAY,QAAA;AAAA,EACpE,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,OAAA;AAAA,EAAS,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO;AACrE,CAAA;AAEA,IAAM,SAAS,CAAC,CAAA,KAAc,CAAA,CAAE,OAAA,CAAQ,uBAAuB,MAAM,CAAA;AACrE,IAAM,KAAA,GAAQ,CAAC,CAAA,KAAc,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAErE,SAAS,SAAA,CAAU,QAAgB,IAAA,EAAqC;AACtE,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,IAAI;AACF,IAAA,KAAA,MAAW,KAAA,IAAS,CAAC,OAAA,EAAS,MAAM,CAAA,EAAY;AAC9C,MAAA,MAAM,MAAM,IAAI,IAAA,CAAK,eAAe,MAAA,EAAQ,IAAA,KAAS,UAAU,EAAE,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU,OAAM,GAAI,EAAE,SAAS,KAAA,EAAO,QAAA,EAAU,OAAO,CAAA;AAEtI,MAAA,MAAM,KAAA,GAAQ,IAAA,KAAS,OAAA,GAAU,EAAA,GAAK,CAAA;AACtC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,QAAA,MAAM,IAAA,GAAO,SAAS,OAAA,GAAU,IAAI,KAAK,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,EAAG,EAAE,CAAC,CAAA,GAAI,IAAI,KAAK,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AACnG,QAAA,GAAA,CAAI,KAAK,KAAA,CAAM,GAAA,CAAI,MAAA,CAAO,IAAI,CAAC,CAAC,CAAA;AAAA,MAClC;AAAA,IACF;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,GAAA;AACT;AAOA,SAAS,QAAQ,KAAA,EAA0B;AACzC,EAAA,MAAM,GAAA,mBAAM,IAAI,GAAA,CAAY,CAAC,IAAI,CAAC,CAAA;AAClC,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,GAAA,CAAI,IAAI,KAAK,CAAA;AACb,IAAA,OAAO,CAAC,GAAG,GAAG,CAAA;AAAA,EAChB;AACA,EAAA,IAAI;AAAE,IAAA,GAAA,CAAI,IAAI,IAAI,IAAA,CAAK,gBAAe,CAAE,eAAA,GAAkB,MAAM,CAAA;AAAA,EAAG,CAAA,CAAA,MAAQ;AAAA,EAAuB;AAClG,EAAA,IAAI,OAAO,cAAc,WAAA,IAAe,SAAA,CAAU,UAAU,GAAA,CAAI,GAAA,CAAI,UAAU,QAAQ,CAAA;AACtF,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,QAAA,CAAS,eAAA,EAAiB,MAAM,GAAA,CAAI,GAAA,CAAI,QAAA,CAAS,eAAA,CAAgB,IAAI,CAAA;AAC5G,EAAA,OAAO,CAAC,GAAG,GAAG,CAAA;AAChB;AAGA,IAAI,MAAA,GAA0B,IAAA;AAE9B,SAAS,SAAS,KAAA,EAA0B;AAC1C,EAAA,MAAM,IAAA,GAAO,QAAQ,KAAK,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA;AACzB,EAAA,IAAI,MAAA,EAAQ,GAAA,KAAQ,GAAA,EAAK,OAAO,MAAA;AAChC,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,cAAc,CAAA;AACrC,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,gBAAgB,CAAA;AACzC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,KAAA,MAAW,CAAA,IAAK,UAAU,GAAA,EAAK,OAAO,GAAG,IAAI,CAAA,EAAG,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA;AAC5D,IAAA,KAAA,MAAW,CAAA,IAAK,UAAU,GAAA,EAAK,SAAS,GAAG,IAAI,CAAA,EAAG,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA;AAAA,EAClE;AAEA,EAAA,MAAM,GAAA,GAAM,CAAC,GAAA,KAAqB,CAAC,GAAG,GAAG,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,MAAA,GAAS,EAAE,MAAM,CAAA,CAAE,IAAI,MAAM,CAAA,CAAE,KAAK,GAAG,CAAA;AACnG,EAAA,MAAM,CAAA,GAAI,CAAA,GAAA,EAAM,GAAA,CAAI,MAAM,CAAC,CAAA,KAAA,CAAA;AAC3B,EAAA,MAAM,CAAA,GAAI,CAAA,GAAA,EAAM,GAAA,CAAI,QAAQ,CAAC,CAAA,KAAA,CAAA;AAC7B,EAAA,MAAM,MAAM,MAAA,CAAO,GAAA,CAAA,0BAAA,CAAA;AACnB,EAAA,MAAM,OAAO,MAAA,CAAO,GAAA,CAAA,SAAA,CAAA;AACpB,EAAA,MAAM,IAAA,GAAO;AAAA;AAAA,IAEX,sCAAA;AAAA,IACA,wCAAA;AAAA,IACA,kFAAA;AAAA;AAAA,IAEA,IAAI,OAAO,CAAA,CAAA,EAAI,GAAG,OAAO,CAAC,CAAA,SAAA,EAAY,IAAI,CAAA,GAAA,CAAA,EAAO,IAAI,CAAA;AAAA,IACrD,IAAI,OAAO,CAAA,CAAA,EAAI,CAAC,OAAO,GAAG,CAAA,SAAA,EAAY,IAAI,CAAA,GAAA,CAAA,EAAO,IAAI,CAAA;AAAA,IACrD,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,CAAC,CAAA,OAAA,EAAU,IAAI,OAAO,IAAI,CAAA;AAAA;AAAA,IAEzC,qCAAA;AAAA,IACA,wBAAA;AAAA,IACA,2CAAA;AAAA;AAAA,IAEA,+CAAA;AAAA,IACA,uBAAA;AAAA,IACA,yCAAA;AAAA,IACA,2BAAA;AAAA;AAAA,IAEA,kBAAA;AAAA,IACA,2CAAA;AAAA,IACA,gDAAA;AAAA;AAAA,IAEA,qDAAA;AAAA,IACA,6BAAA;AAAA;AAAA,IAEA,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,CAAC,KAAK,IAAI,CAAA;AAAA;AAAA,IAEzB,gDAAA;AAAA,IACA,0BAAA;AAAA,IACA,uBAAA;AAAA;AAAA,IAEA,yGAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAA,GAAS,EAAE,KAAK,IAAA,EAAK;AACrB,EAAA,OAAO,MAAA;AACT;AAOO,SAAS,YAAA,CAAa,QAAgC,MAAA,EAA+B;AAC1F,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,QAAA,CAAS,MAAM,CAAA;AAChC,EAAA,KAAA,MAAW,OAAO,MAAA,EAAQ;AACxB,IAAA,IAAI,OAAO,IAAA,EAAM;AACjB,IAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAAE,MAAA,IAAI,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,EAAG;AAAU,MAAA,OAAO,OAAA;AAAA,IAAS;AACnF,IAAA,IAAI,eAAe,IAAA,EAAM;AACzB,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,EAAK;AAC9B,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,IAAI,CAAC,IAAA,CAAK,IAAA,CAAK,CAAC,EAAA,KAAO,GAAG,IAAA,CAAK,IAAI,CAAC,CAAA,EAAG,OAAO,OAAA;AAAA,EAChD;AACA,EAAA,OAAO,OAAA;AACT;AAKO,SAAS,iBAAiB,EAAA,EAA2C;AAC1E,EAAA,MAAM,MAAM,EAAA,CAAG,aAAA;AACf,EAAA,MAAM,OAAO,GAAA,CAAI,WAAA;AACjB,EAAA,IAAI,KAAA,GAAQ,EAAA,CAAG,aAAA,CAA2B,oBAAoB,CAAA;AAC9D,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,KAAA,GAAQ,GAAA,CAAI,cAAc,MAAM,CAAA;AAChC,IAAA,KAAA,CAAM,YAAA,CAAa,eAAe,MAAM,CAAA;AACxC,IAAA,KAAA,CAAM,MAAM,OAAA,GAAU,6IAAA;AACtB,IAAA,EAAA,CAAG,YAAY,KAAK,CAAA;AACpB,IAAA,SAAA,GAAY,IAAA;AAAA,EACd;AACA,EAAA,MAAM,EAAA,GAAK,IAAA,EAAM,gBAAA,CAAiB,KAAK,CAAA;AACvC,EAAA,MAAM,EAAA,GAAK,UAAA,CAAW,EAAA,EAAI,QAAA,IAAY,EAAE,CAAA,IAAK,EAAA;AAC7C,EAAA,MAAM,MAAA,GAAA,CAAU,EAAA,EAAI,UAAA,IAAc,EAAA,EAAI,MAAK,IAAK,YAAA;AAChD,EAAA,MAAM,KAAA,GAAQ,IAAI,SAAA,IAAa,EAAA,CAAG,cAAc,QAAA,GAAW,CAAA,EAAG,EAAA,CAAG,SAAS,CAAA,CAAA,CAAA,GAAM,EAAA;AAChF,EAAA,MAAM,MAAA,GAAS,EAAA,EAAI,UAAA,IAAc,EAAA,CAAG,UAAA,KAAe,KAAA,IAAS,EAAA,CAAG,UAAA,KAAe,QAAA,GAAW,CAAA,EAAG,EAAA,CAAG,UAAU,CAAA,CAAA,CAAA,GAAM,EAAA;AAC/G,EAAA,IAAI,SAAA,QAAiB,MAAA,EAAO;AAC5B,EAAA,OAAO,EAAE,IAAA,EAAM,CAAA,EAAG,KAAK,CAAA,EAAG,MAAM,CAAA,EAAG,EAAE,CAAA,GAAA,EAAM,MAAM,CAAA,CAAA,EAAI,EAAA,EAAG;AAC1D;AAGA,IAAI,MAAA,GAA+E,IAAA;AAEnF,SAAS,aAAA,GAAiD;AACxD,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA;AAC5C,EAAA,MAAM,UAAA,GAAc,UAAA,CAA+E,iBAAA,EAAmB,SAAA,CAAU,UAAA;AAChI,EAAA,IAAI,MAAA,IAAU,MAAA,CAAO,UAAA,KAAe,UAAA,SAAmB,MAAA,CAAO,GAAA;AAC9D,EAAA,IAAI,GAAA,GAAuC,IAAA;AAC3C,EAAA,IAAI;AAAE,IAAA,GAAA,GAAM,SAAS,aAAA,CAAc,QAAQ,CAAA,CAAE,UAAA,GAAa,IAAI,CAAA,IAAK,IAAA;AAAA,EAAM,CAAA,CAAA,MAAQ;AAAE,IAAA,GAAA,GAAM,IAAA;AAAA,EAAM;AAC/F,EAAA,MAAA,GAAS,EAAE,YAAY,GAAA,EAAI;AAC3B,EAAA,OAAO,GAAA;AACT;AAMO,SAAS,mBAAmB,EAAA,EAAoE;AACrG,EAAA,MAAM,MAAM,aAAA,EAAc;AAC1B,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,MAAM,EAAE,IAAA,EAAM,EAAA,EAAG,GAAI,iBAAiB,EAAE,CAAA;AACxC,EAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,MAAM,OAAA,GAAmB,CAAC,IAAA,KAAS;AACjC,IAAA,IAAI,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AACvB,IAAA,IAAI,MAAM,MAAA,EAAW;AAEnB,MAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,MAAA,CAAA,GAAI,GAAA,CAAI,WAAA,CAAY,IAAI,CAAA,CAAE,KAAA;AAC1B,MAAA,MAAA,CAAO,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA,IACpB;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AACA,EAAA,OAAO,EAAE,OAAA,EAAS,EAAA,EAAI,IAAA,EAAK;AAC7B;AAIO,IAAM,QAAA,GAAW,QAAA;AAUxB,IAAM,OAAA,GAAU,CAAC,CAAA,KAAc,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,EAAE,CAAA,CAAE,MAAA;AAGvE,SAAS,cAAA,CAAe,IAAA,EAAc,KAAA,EAAe,OAAA,EAAkB,SAAS,EAAA,EAAY;AAC1F,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,KAAK,IAAA,CAAK,MAAA;AACd,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,OAAO,MAAM,EAAA,EAAI;AACf,IAAA,MAAM,GAAA,GAAO,KAAK,EAAA,IAAO,CAAA;AACzB,IAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,EAAE,OAAA,EAAQ,GAAI,MAAM,CAAA,IAAK,KAAA,EAAO;AAAE,MAAA,IAAA,GAAO,GAAA;AAAK,MAAA,EAAA,GAAK,GAAA,GAAM,CAAA;AAAA,IAAG,CAAA,WAAY,GAAA,GAAM,CAAA;AAAA,EAC7G;AACA,EAAA,OAAO,IAAA;AACT;AAOO,SAAS,QAAA,CAAS,IAAA,EAAc,KAAA,EAAe,OAAA,EAAsC;AAC1F,EAAA,MAAM,OAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,GAAG,EAAE,IAAA,EAAK;AAC5C,EAAA,IAAI,CAAC,WAAW,CAAC,IAAA,IAAQ,SAAS,CAAA,IAAK,OAAA,CAAQ,IAAI,CAAA,IAAK,KAAA,SAAc,EAAE,KAAA,EAAO,CAAC,IAAI,CAAA,EAAG,KAAK,KAAA,EAAO,KAAA,EAAO,OAAA,CAAQ,IAAI,CAAA,EAAE;AACxH,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC5B,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,IAAI,UAAA,GAAa,EAAA;AACjB,EAAA,IAAI,IAAA,GAAO,EAAA;AACX,EAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,YAAY,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA,CAAE,KAAK,GAAG,CAAA;AAC5C,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,IAAK,KAAA,EAAO;AAAE,MAAA,KAAA,GAAQ,UAAA,GAAa,SAAA;AAAW,MAAA,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG,CAAA;AAAG,MAAA;AAAA,IAAO;AAAA,EAC7G;AACA,EAAA,IAAI,CAAC,KAAA,EAAO;AAEV,IAAA,MAAMA,EAAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,eAAe,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,GAAG,CAAC,CAAA;AAC/D,IAAA,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,CAAA,EAAGA,EAAC,EAAE,OAAA,EAAQ;AACtC,IAAA,IAAA,GAAO,IAAA,CAAK,KAAA,CAAMA,EAAC,CAAA,CAAE,SAAA,EAAU;AAC/B,IAAA,KAAA,GAAQ,IAAA,IAAQ,CAAC,IAAA,CAAK,KAAA,CAAMA,KAAI,CAAA,EAAGA,EAAAA,GAAI,CAAC,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,GAAI,CAAA,EAAG,UAAU,CAAA,CAAA,CAAA,GAAM,UAAA;AAAA,EAC/E;AACA,EAAA,IAAI,CAAC,IAAA,EAAM,OAAO,EAAE,KAAA,EAAO,CAAC,KAAK,CAAA,EAAG,GAAA,EAAK,KAAA,EAAO,KAAA,EAAO,OAAA,CAAQ,UAAU,CAAA,EAAE;AAC3E,EAAA,IAAI,QAAQ,IAAI,CAAA,IAAK,OAAO,OAAO,EAAE,OAAO,CAAC,KAAA,EAAO,IAAI,CAAA,EAAG,GAAA,EAAK,OAAO,KAAA,EAAO,OAAA,CAAQ,UAAU,CAAA,GAAI,OAAA,CAAQ,IAAI,CAAA,EAAE;AAClH,EAAA,MAAM,CAAA,GAAI,cAAA,CAAe,IAAA,EAAM,KAAA,EAAO,SAAS,QAAQ,CAAA;AACvD,EAAA,MAAM,IAAA,GAAO,IAAI,CAAA,GAAI,IAAA,CAAK,MAAM,CAAA,EAAG,CAAC,CAAA,CAAE,OAAA,EAAQ,GAAI,EAAA;AAClD,EAAA,OAAO,EAAE,KAAA,EAAO,CAAC,KAAA,EAAO,OAAO,QAAQ,CAAA,EAAG,GAAA,EAAK,IAAA,EAAM,OAAO,OAAA,CAAQ,UAAU,CAAA,GAAI,OAAA,CAAQ,IAAI,CAAA,EAAE;AAClG;AAGO,IAAM,cAAA,GAAiB,CAAA;AAGvB,SAAS,aAAA,CAAc,KAAA,EAA8B,KAAA,EAAe,OAAA,EAA2B;AACpG,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM;AACvB,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,CAAA,EAAG,KAAA,EAAO,OAAO,CAAA;AACtC,IAAA,OAAO,GAAA,CAAI,GAAA,IAAO,GAAA,CAAI,KAAA,GAAQ,cAAA;AAAA,EAChC,CAAC,CAAA;AACH;AC3PO,IAAM,aAAA,GAAgB;AAAA,EAC3B,EAAA,EAAI,2BAAA;AAAA,EACJ,EAAA,EAAI,2BAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAGO,IAAM,SAAA,GAAY,2BAAA;AAGlB,SAAS,iBAAiB,MAAA,EAA8D;AAC7F,EAAA,IAAI,OAAO,MAAA,KAAW,QAAA,EAAU,OAAO,GAAG,MAAM,CAAA,EAAA,CAAA;AAChD,EAAA,IAAI,MAAA,KAAW,QAAQ,MAAA,KAAW,IAAA,IAAQ,WAAW,IAAA,EAAM,OAAO,cAAc,MAAM,CAAA;AACtF,EAAA,OAAO,MAAA;AACT;AAcA,IAAM,KAAK,aAAA,CAAc,EAAA;AACzB,IAAM,KAAK,aAAA,CAAc,EAAA;AAQlB,SAAS,YAAA,CAAa,MAAiB,KAAA,EAA0C;AACtF,EAAA,IAAI,IAAA,CAAK,UAAU,QAAA,EAAU;AAC3B,IAAA,OAAO,EAAE,QAAQ,KAAA,IAAS,CAAA,MAAA,EAAS,EAAE,CAAA,UAAA,EAAa,EAAE,CAAA,CAAA,CAAA,EAAK,IAAA,EAAM,UAAA,EAAW;AAAA,EAC5E;AACA,EAAA,IAAI,IAAA,CAAK,UAAU,MAAA,EAAQ;AACzB,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,GAAQ,CAAA,GAAA,EAAM,IAAA,CAAK,KAAK,CAAA,gCAAA,CAAA,GAAqC,EAAA;AAChF,IAAA,MAAM,MAAA,GAAS,KAAA,IAAS,CAAA,IAAA,EAAO,EAAE,UAAU,IAAA,CAAK,KAAK,CAAA,GAAA,EAAM,SAAS,CAAA,EAAG,KAAK,CAAA,GAAA,EAAM,IAAA,CAAK,QAAQ,SAAS,CAAA,EAAA,CAAA;AACxG,IAAA,OAAO,EAAE,MAAA,EAAQ,SAAA,EAAW,YAAY,MAAM,CAAA,CAAA,CAAA,EAAK,MAAM,UAAA,EAAW;AAAA,EACtE;AACA,EAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,IAAS,CAAA,MAAA,EAAS,EAAE,CAAA,SAAA,EAAY,EAAE,CAAA,CAAA,CAAA,EAAK,SAAA,EAAW,CAAA,IAAA,EAAO,KAAA,IAAS,EAAE,CAAA,SAAA,CAAA,EAAa,MAAM,UAAA,EAAW;AACrH;AASO,IAAM,UAAA,mBAA4B,MAAA,CAAO,GAAA,CAAI,iBAAiB,CAAA;AAE9D,SAAS,UAA4B,SAAA,EAAiB;AAC3D,EAAA,MAAA,CAAO,OAAO,SAAA,EAAW,EAAE,CAAC,UAAU,GAAG,MAAM,CAAA;AAC/C,EAAA,OAAO,SAAA;AACT;AAGO,SAAS,eAAe,QAAA,EAA8B;AAC3D,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,OAAA,CAAQ,QAAQ,CAAA;AACtC,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AAC9B,EAAA,MAAM,IAAA,GAAO,KAAK,CAAC,CAAA;AACnB,EAAA,IAAI,CAAC,cAAA,CAAe,IAAI,CAAA,EAAG,OAAO,KAAA;AAClC,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAClC,EAAA,OAAO,CAAC,CAAC,IAAA,IAAQ,OAAO,SAAS,QAAA,IAAY,IAAA,CAAK,UAAU,CAAA,KAAM,IAAA;AACpE;AAaO,IAAM,qBAAA,GAAwB,cAA0C,IAAI,CAAA;AAE5E,SAAS,uBAAA,GAAmC;AACjD,EAAA,OAAO,UAAA,CAAW,qBAAqB,CAAA,KAAM,IAAA;AAC/C;AAUO,IAAM,oBAAoB,aAAA,CAA0B,EAAE,QAAQ,IAAA,EAAM,IAAA,EAAM,MAAM,CAAA;AAIvF,IAAM,QAAA,uBAAe,OAAA,EAAe;AAMpC,SAAS,aAAa,CAAA,EAAkC;AACtD,EAAA,IAAI,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AACjC,EAAA,MAAM,IAAA,GAAO,CAAA,CAAE,GAAA,KAAQ,WAAA,IAAe,EAAE,GAAA,KAAQ,YAAA;AAChD,EAAA,MAAM,QAAA,GAAW,CAAA,CAAE,GAAA,KAAQ,SAAA,IAAa,EAAE,GAAA,KAAQ,WAAA;AAClD,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,QAAA,EAAU;AACxB,EAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,GAAU,mBAAmB,CAAA,EAAG;AAC5C,EAAA,CAAA,CAAE,cAAA,EAAe;AACjB,EAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,aAAA,CAAc,WAAA,IAAe,MAAA;AACjD,EAAA,MAAM,KAAA,GAAQ,IAAI,IAAA,CAAK,aAAA,CAAc,WAAW,EAAE,GAAA,EAAK,IAAA,GAAO,WAAA,GAAc,YAAA,EAAc,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,MAAM,CAAA;AAC3H,EAAA,QAAA,CAAS,IAAI,KAAK,CAAA;AAClB,EAAA,MAAA,CAAO,cAAc,KAAK,CAAA;AAC5B;AAgCO,IAAM,YAAA,GAAe,UAAA,CAA8C,SAASC,aAAAA,CAAa;AAAA,EAC9F,MAAA,GAAS,MAAA;AAAA,EACT,IAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA,EAAAC,aAAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA,EAAc;AAChB,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,SAAA,GAAY,WAAW,qBAAqB,CAAA;AAClD,EAAA,MAAM,OAAA,GAAU,OAA8B,IAAI,CAAA;AAClD,EAAA,MAAM,OAAA,GAAU,OAA8B,IAAI,CAAA;AAClD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,SAAgC,IAAI,CAAA;AAChE,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,SAAgC,IAAI,CAAA;AAC5D,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAoB,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,WAAA,EAAY,CAAA,EAAI,CAAC,MAAA,EAAQ,IAAA,EAAM,WAAW,CAAC,CAAA;AAKpG,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,SAAmD,IAAI,CAAA;AACjF,EAAAC,gBAAgB,MAAM;AACpB,IAAA,MAAM,OAAO,OAAA,CAAQ,OAAA;AACrB,IAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,cAAA,KAAmB,WAAA,EAAa;AACpD,IAAA,MAAM,QAAA,GAAW,IAAI,cAAA,CAAe,CAAC,OAAA,KAAY;AAC/C,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,EAAG,WAAA;AACzC,MAAA,IAAI,CAAC,GAAA,IAAO,GAAA,CAAI,SAAS,CAAA,IAAK,GAAA,CAAI,UAAU,CAAA,EAAG;AAC/C,MAAA,QAAA,CAAS,CAAC,IAAA,KAAU,IAAA,IAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAA,GAAQ,GAAA,CAAI,KAAK,CAAA,GAAI,GAAA,IAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,GAAS,GAAA,CAAI,MAAM,CAAA,GAAI,GAAA,GAAM,IAAA,GAAO,EAAE,KAAA,EAAO,GAAA,CAAI,KAAA,EAAO,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAS,CAAA;AAAA,IACnK,CAAC,CAAA;AACD,IAAA,QAAA,CAAS,QAAQ,IAAI,CAAA;AACrB,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,IAAA,GAAO,WAAW,QAAA,KAAa,IAAA;AACrC,EAAA,MAAM,KAAA,GAAQ,SAAA,EAAW,MAAA,IAAU,gBAAA,CAAiB,MAAM,CAAA;AAC1D,EAAA,MAAM,SAAA,GAA2B,IAAA,GAAO,EAAE,IAAA,EAAM,QAAA,EAAU,WAAW,CAAA,EAAE,GAAI,YAAA,CAAa,IAAA,EAAM,KAAK,CAAA;AAGnG,EAAA,MAAM,QAAQ,SAAA,GACV,EAAE,IAAA,EAAM,KAAA,EAAO,cAAc,SAAA,EAAU,GACvC,SAAA,EAAW,OAAA,GACT,EAAE,IAAA,EAAM,KAAA,EAAO,mBAAmB,SAAA,CAAU,OAAA,KAC5C,EAAC;AAGP,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,OAAO,OAAA,CAAQ,OAAA;AACrB,IAAA,MAAM,OAAO,OAAA,CAAQ,OAAA;AACrB,IAAA,IAAI,CAAC,QAAQ,CAAC,IAAA,IAAQ,CAAC,YAAA,IAAgB,OAAO,qBAAqB,WAAA,EAAa;AAChF,IAAA,MAAM,QAAA,GAAW,aAAa,YAAY,CAAA,oDAAA,CAAA;AAC1C,IAAA,MAAM,QAAQ,MAAM;AAClB,MAAA,MAAM,SAAS,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,gBAAA,CAAiB,QAAQ,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,QAAQ,EAAA,CAAG,WAAA,IAAe,EAAA,EAAI,IAAA,OAAW,EAAE,CAAA;AAC9G,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA;AAClC,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,CAAC,EAAA,KAAO,EAAA,CAAG,YAAA,CAAa,UAAU,CAAC,CAAA,CAAE,MAAM,CAAA;AAC5E,MAAA,IAAI,IAAA,CAAK,aAAa,mBAAmB,CAAA,KAAM,OAAO,IAAA,CAAK,YAAA,CAAa,qBAAqB,KAAK,CAAA;AAClG,MAAA,IAAI,IAAA,CAAK,aAAa,iBAAiB,CAAA,KAAM,KAAK,IAAA,CAAK,YAAA,CAAa,mBAAmB,GAAG,CAAA;AAAA,IAC5F,CAAA;AACA,IAAA,KAAA,EAAM;AACN,IAAA,MAAM,QAAA,GAAW,IAAI,gBAAA,CAAiB,KAAK,CAAA;AAC3C,IAAA,QAAA,CAAS,OAAA,CAAQ,IAAA,EAAM,EAAE,OAAA,EAAS,MAAM,SAAA,EAAW,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,YAAY,IAAA,EAAM,eAAA,EAAiB,CAAC,UAAU,GAAG,CAAA;AAC/H,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAEjB,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,SAAA,CAAU,GAAA,EAAyB,OAA2B,CAAA;AAAA,MACnE,eAAA,EAAe,KAAA;AAAA,MACf,oBAAA,EAAoBF,aAAAA;AAAA,MACpB,iBAAA,EAAiB,UAAA;AAAA,MACjB,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,IAAA,IAAQ,UAAU,SAAS,CAAA;AAAA,MAC1E,KAAA,EAAO,EAAE,aAAA,EAAe,aAAA,EAAe,aAAA,EAAe,kBAAA,EAAoB,GAAI,IAAA,GAAO,EAAC,GAAI,EAAE,IAAA,EAAM,YAAW,EAAG;AAAA,MAEhH,QAAA,EAAA;AAAA,wBAAA,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,OAAA;AAAA,YACL,iBAAA,EAAgB,EAAA;AAAA,YAChB,SAAA,EAAU,iBAAA;AAAA,YACV,KAAA,EAAO,SAAA;AAAA,YACP,gBAAA,EAAkB,WAAW,YAAA,GAAe,MAAA;AAAA,YAC3C,GAAG,KAAA;AAAA,YAEH,QAAA,EAAA;AAAA,cAAA,SAAA,wBACE,MAAA,EAAA,EAAK,uBAAA,EAAsB,EAAA,EAAG,SAAA,EAAU,qIACtC,QAAA,EAAA,SAAA,EACH,CAAA;AAAA,8BAEF,GAAA,CAAC,SAAI,SAAA,EAAU,kBAAA,EAAmB,OAAO,KAAA,GAAQ,EAAE,QAAA,EAAU,KAAA,CAAM,KAAA,EAAO,SAAA,EAAW,MAAM,MAAA,EAAO,GAAI,QACpG,QAAA,kBAAA,GAAA,CAAC,iBAAA,CAAkB,UAAlB,EAA2B,KAAA,EAAO,KAAA,EAAQ,QAAA,EAAS,CAAA,EACtD;AAAA;AAAA;AAAA,SACF;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,SAAA,EAAW,qBAAkB,EAAA,EAAG,CAAA;AAAA,wBAC1C,GAAA,CAAC,SAAI,GAAA,EAAK,OAAA,EAAS,MAAK,QAAA,EAAS,WAAA,EAAU,QAAA,EAAS,SAAA,EAAU,SAAA,EAAU,CAAA;AAAA,wBAExE,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,kBAAA,EAAiB,EAAA;AAAA,YACjB,aAAA,EAAY,MAAA;AAAA,YACZ,SAAA,EAAU,qDAAA;AAAA,YACV,KAAA,EAAO,EAAE,QAAA,EAAU,wBAAA,EAA0B,YAAY,qBAAA,EAAuB,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAO,CAAA;AAAE;AAAA;AAC9G;AAAA;AAAA,GACF;AAEJ,CAAC,CAAA;AClQD,IAAM,UAAA,GAAa,CAAA;AAEnB,IAAM,aAAgD,CAAC,CAAC,MAAA,EAAQ,IAAS,GAAG,CAAC,QAAA,EAAU,GAAM,CAAA,EAAG,CAAC,QAAA,EAAU,GAAK,GAAG,CAAC,aAAA,EAAe,CAAC,CAAC,CAAA;AACrI,IAAM,UAAA,GAAmD,CAAC,CAAC,UAAA,EAAY,IAAI,GAAG,CAAC,UAAA,EAAY,IAAI,CAAA,EAAG,CAAC,UAAA,EAAY,GAAG,CAAA,EAAG,CAAC,UAAA,EAAY,GAAG,CAAA,EAAG,CAAC,UAAA,EAAY,GAAG,CAAA,EAAG,CAAC,MAAA,EAAQ,CAAC,CAAC,CAAA;AAGtK,IAAM,YAAA,GAAe,EAAA;AAQrB,SAAS,KAAA,CAAM,MAAA,EAAoC,SAAA,GAAY,YAAA,EAAsB;AACnF,EAAA,KAAA,IAAS,MAAA,GAAS,CAAA,EAAG,MAAA,GAAS,SAAA,EAAW,MAAA,EAAA,EAAU;AACjD,IAAA,MAAM,KAAA,GAAQ,OAAO,MAAM,CAAA;AAC3B,IAAA,IAAI,KAAA,KAAU,MAAA,CAAO,MAAA,GAAS,CAAC,GAAG,OAAO,KAAA;AAAA,EAC3C;AACA,EAAA,OAAO,OAAO,SAAS,CAAA;AACzB;AAEA,IAAM,UAAA,GAAa,CAAC,IAAA,EAAc,KAAA,EAAe,WAA+B,CAAC,MAAA,KAC/E,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ,EAAE,KAAA,EAAO,MAAA,EAAQ,MAAM,WAAA,EAAa,OAAA,EAAS,uBAAuB,MAAA,EAAQ,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AAE1H,IAAM,OAAA,GAAU,CAAC,MAAA,KAAsC,MAAA,KAAW,UAAU,UAAA,GAAa,UAAA;AAGzF,SAAS,WAAA,CAAY,OAAgC,KAAA,EAAiC;AACpF,EAAA,OAAO,MAAM,IAAA,CAAK,CAAC,GAAG,IAAI,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,IAAI,CAAA,IAAK,KAAA,CAAM,KAAA,CAAM,SAAS,CAAC,CAAA;AACpF;AAOA,SAAS,QAAA,CAAS,OAAgC,KAAA,EAAmC;AACnF,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,CAAA,EAAG,GAAG,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,GAAG,CAAC,CAAA;AAClD,EAAA,MAAM,UAAU,CAAC,IAAA,KAAiB,MAAM,KAAA,CAAM,CAAC,MAAM,IAAA,CAAK,GAAA,CAAK,IAAI,IAAA,GAAQ,GAAA,GAAM,KAAK,KAAA,CAAO,CAAA,GAAI,OAAQ,GAAG,CAAC,IAAI,IAAI,CAAA;AACrH,EAAA,OAAO,MAAM,IAAA,CAAK,CAAC,GAAG,IAAI,CAAA,KAAM,OAAA,GAAU,IAAA,IAAQ,CAAA,IAAK,QAAQ,IAAI,CAAC,KAAK,KAAA,CAAM,KAAA,CAAM,SAAS,CAAC,CAAA;AACjG;AAGO,SAAS,eAAe,MAAA,EAA4B;AACzD,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA;AAC5C,EAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,OAAO,EAAC;AAC5B,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAG,MAAM,CAAA;AAChC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAG,MAAM,CAAA;AAChC,EAAA,IAAI,EAAA,KAAO,EAAA,EAAI,OAAO,CAAC,EAAE,CAAA;AACzB,EAAA,OAAO,iBAAA,CAAkB,CAAC,EAAA,EAAI,EAAE,GAAG,UAAA,EAAY,IAAI,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AACjE;AAMO,SAAS,iBAAA,CAAkB,MAAA,EAAkB,MAAA,EAAiC,MAAA,EAAuD;AAC1I,EAAA,IAAI,OAAO,MAAA,KAAW,UAAA,EAAY,OAAO,MAAA;AACzC,EAAA,IAAI,MAAA,KAAW,WAAW,OAAO,CAAC,UAAU,KAAA,CAAM,CAAC,CAAA,KAAM,IAAI,IAAA,CAAK,YAAA,CAAa,QAAQ,EAAE,KAAA,EAAO,WAAW,qBAAA,EAAuB,CAAA,EAAG,CAAA,CAAE,MAAA,CAAO,KAAA,GAAQ,GAAG,CAAC,CAAA;AAC1J,EAAA,IAAI,MAAA,KAAW,cAAA,IAAkB,MAAA,KAAW,OAAA,EAAS;AACnD,IAAA,MAAM,CAAC,IAAA,EAAM,IAAI,CAAA,GAAI,QAAA,CAAS,QAAQ,MAAM,CAAA,EAAG,cAAA,CAAe,MAAM,CAAC,CAAA;AACrE,IAAA,OAAO,CAAC,UAAU,KAAA,CAAM,UAAA,CAAW,MAAM,KAAA,GAAQ,IAAA,EAAM,MAAM,CAAC,CAAA;AAAA,EAChE;AACA,EAAA,MAAM,UAAU,CAAC,KAAA,KAAkB,MAAM,CAAC,CAAA,KAAM,IAAI,IAAA,CAAK,YAAA,CAAa,QAAQ,EAAE,QAAA,EAAU,WAAW,qBAAA,EAAuB,CAAA,EAAG,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC,CAAA;AAC9I,EAAA,MAAM,QAAQ,CAAC,KAAA,KAAkB,KAAA,CAAM,CAAC,MAAM,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ,EAAE,qBAAA,EAAuB,CAAA,EAAG,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC,CAAA;AAIvH,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAG,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA,CAAE,GAAA,CAAI,IAAA,CAAK,GAAG,CAAC,CAAA;AAC3E,EAAA,OAAO,OAAA,IAAW,eAAe,OAAA,GAAU,KAAA;AAC7C;AAGA,IAAM,YAAA,GAAe,GAAA;AAGd,SAAS,kBAAA,CAAmB,QAAiC,MAAA,EAAuD;AACzH,EAAA,IAAI,OAAO,MAAA,KAAW,UAAA,EAAY,OAAO,MAAA;AACzC,EAAA,IAAI,MAAA,KAAW,UAAa,MAAA,KAAW,QAAA,SAAiB,CAAC,KAAA,KAAU,KAAA,CAAM,cAAA,CAAe,MAAM,CAAA;AAC9F,EAAA,IAAI,MAAA,KAAW,WAAW,OAAO,CAAC,UAAU,KAAA,CAAM,CAAC,CAAA,KAAM,IAAI,IAAA,CAAK,YAAA,CAAa,QAAQ,EAAE,KAAA,EAAO,SAAA,EAAW,qBAAA,EAAuB,CAAA,EAAG,EAAE,MAAA,CAAO,KAAA,GAAQ,GAAG,CAAA,EAAG,CAAC,CAAA;AAC7J,EAAA,OAAO,CAAC,KAAA,KAAU;AAChB,IAAA,MAAM,CAAC,MAAM,IAAI,CAAA,GAAI,YAAY,OAAA,CAAQ,MAAM,GAAG,KAAK,CAAA;AACvD,IAAA,OAAO,MAAM,UAAA,CAAW,IAAA,EAAM,QAAQ,IAAA,EAAM,MAAM,GAAG,CAAC,CAAA;AAAA,EACxD,CAAA;AACF;AAaO,SAAS,UAAA,CAAW,MAAiC,MAAA,EAAgC;AAC1F,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAC3B,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,MAAM,EAAA,uBAAS,GAAA,EAAoB;AACnC,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAoB;AACrC,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,CAAA,CAAE,OAAO,CAAA;AACzB,MAAA,MAAM,CAAA,GAAI,OAAO,GAAA,KAAQ,QAAA,GAAW,MAAM,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,CAAI,IAAA,EAAK,KAAM,EAAA,GAAK,MAAA,CAAO,GAAG,CAAA,GAAI,GAAA;AACvG,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,EAAG;AACzB,MAAA,IAAI,CAAA,CAAE,KAAA,IAAS,IAAA,EAAM,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,WAAA,IACtB,CAAA,IAAK,CAAA,EAAG,EAAA,CAAG,GAAA,CAAI,CAAA,CAAE,KAAA,EAAA,CAAQ,EAAA,CAAG,GAAA,CAAI,CAAA,CAAE,KAAK,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAAA,WACtD,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,KAAA,EAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,CAAE,KAAK,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAAA,IACrD;AACA,IAAA,OAAO,CAAC,GAAG,GAAA,EAAK,GAAG,EAAA,CAAG,QAAO,EAAG,GAAG,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,EAClD,CAAC,CAAA;AACH;AAGO,SAAS,YAAA,CAAa,IAAA,EAAiC,IAAA,EAAgB,OAAA,GAAU,KAAA,EAAiB;AACvG,EAAA,OAAO,UAAA,CAAW,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,CAAC,OAAA,MAAa,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,GAAU,OAAA,GAAU,IAAA,GAAO,CAAC,CAAA;AAC/F;AC1GA,IAAM,QAAA,GAAW,CAAC,KAAA,KAAmB,KAAA,IAAS,QAAQ,KAAA,KAAU,EAAA,IAAM,OAAO,KAAA,KAAU,QAAA;AAMvF,IAAM,YAAY,CAAC,KAAA,EAAqB,KAAA,KACrC,CAAC,SAAS,KAAK,CAAA,IAAK,OAAO,KAAA,CAAM,SAAS,IAAA,KAAS,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,QAAS,KAAA,CAAM,IAAA;AAE/F,IAAM,UAAA,GAAa,CAAC,KAAA,EAAqB,MAAA,EAAmE,WACzG,OAAO,KAAA,CAAM,UAAU,QAAA,GAAY,MAAA,GAAS,OAAO,KAAA,CAAM,KAAA,EAAO,MAAM,OAAO,CAAA,GAAI,MAAM,KAAA,CAAM,cAAA,CAAe,MAAM,CAAA,GAAK,KAAA,CAAM,KAAA;AAGzH,SAAS,oBAAoB,KAAA,EAAgB,OAAA,EAAqC,MAAA,EAAsD,MAAA,GAA6B,cAAa,EAAW;AAClM,EAAA,IAAI,CAAC,OAAA,EAAS,MAAA,EAAQ,OAAO,EAAA;AAC7B,EAAA,MAAM,SAAS,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,KAAU,CAAA,EAAG,UAAU,KAAA,EAAO,KAAK,CAAC,CAAA,CAAA,EAAI,UAAA,CAAW,OAAO,MAAA,EAAQ,MAAM,CAAC,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AAClH,EAAA,OAAO,QAAA,CAAS,KAAK,CAAA,GAAI,CAAA,EAAG,OAAO,KAAK,CAAC,CAAA,EAAA,EAAK,MAAM,CAAA,CAAA,GAAK,MAAA;AAC3D;AAOO,SAAS,mBAAA,CAAoB,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAM,EAA6B;AACxF,EAAA,MAAM,SAAA,GAAY,iBAAiB,iBAAiB,CAAA;AACpD,EAAA,MAAM,YAAA,GAAe,iBAAiB,oBAAoB,CAAA;AAC1D,EAAA,MAAM,WAAA,GAAc,iBAAiB,mBAAmB,CAAA;AACxD,EAAA,MAAM,aAAA,GAAgB,iBAAiB,qBAAqB,CAAA;AAC5D,EAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAY,GAAIG,WAAW,iBAAiB,CAAA;AAE1D,EAAA,MAAM,SAAS,eAAA,EAAgB;AAE/B,EAAA,MAAM,KAAK,CAAC,CAAC,MAAA,IAAU,CAAC,CAAC,OAAA,EAAS,MAAA;AAClC,EAAA,MAAM,SAAA,GAAY,SAAS,KAAK,CAAA;AAEhC,EAAA,MAAM,GAAA,GAAM,qBACVC,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,gHAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,SAAA;AAAA,QACjB,MAAA,EAAQ,gCAAgC,YAAY,CAAA,CAAA;AAAA,QACpD,OAAA,EAAS;AAAA,OACX;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,SAAA,oBACCC,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,qBAAA,EAAsB,OAAO,EAAE,KAAA,EAAO,WAAA,EAAY,EAC5D,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,QAED,OAAA,CAAS,GAAA,CAAI,CAAC,KAAA,EAAO,CAAA,KAAM;AAC1B,UAAA,MAAM,QAAA,GAAY,KAAA,CAAM,OAAA,EAAS,IAAA,IAAmB,MAAM,KAAA,IAAS,aAAA;AACnE,UAAA,uBACED,IAAAA,CAAC,KAAA,EAAA,EAAY,SAAA,EAAU,4BAAA,EAA6B,KAAA,EAAO,EAAE,SAAA,EAAW,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA,EAAE,EACpF,QAAA,EAAA;AAAA,4BAAAC,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,0CAAA;AAAA,gBACV,OAAO,EAAE,KAAA,EAAO,GAAG,MAAA,EAAQ,CAAA,EAAG,iBAAiB,QAAA;AAAS;AAAA,aAC1D;AAAA,4BACAD,IAAAA,CAAC,MAAA,EAAA,EAAK,OAAO,EAAE,KAAA,EAAO,eAAc,EAAI,QAAA,EAAA;AAAA,cAAA,SAAA,CAAU,OAAO,KAAK,CAAA;AAAA,cAAE;AAAA,aAAA,EAAC,CAAA;AAAA,4BACjEC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gBAAe,KAAA,EAAO,EAAE,KAAA,EAAO,WAAA,EAAY,EACxD,QAAA,EAAA,UAAA,CAAW,KAAA,EAAO,WAAA,EAAa,MAAM,CAAA,EACxC;AAAA,WAAA,EAAA,EARQ,CASV,CAAA;AAAA,QAEJ,CAAC;AAAA;AAAA;AAAA,GACH,GACE,IAAA;AAEJ,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,uBACED,KAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,GAAA;AAAA,MACA,YAAA,CAAa,KAAK,mBAAA,CAAoB,KAAA,EAAO,SAAS,WAAA,EAAa,MAAM,CAAA,GAAI,EAAA,EAAI,IAAI;AAAA,KAAA,EACxF,CAAA;AAAA,EAEJ;AACA,EAAA,uBACEC,GAAAA,CAAC,KAAA,EAAA,EAAI,MAAK,QAAA,EAAS,WAAA,EAAU,UAC1B,QAAA,EAAA,GAAA,EACH,CAAA;AAEJ;AAWA,SAAS,WAAW,KAAA,EAAkE;AACpF,EAAA,MAAM,MAAA,GAAU,MAAM,OAAA,EAA8C,MAAA;AACpE,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA,GAAW,MAAA,GAAS,KAAA,CAAM,KAAA;AACrD;AAEO,SAAS,kBAAA,CAAmB,EAAE,OAAA,EAAQ,EAA4B;AACvE,EAAA,MAAM,aAAA,GAAgB,iBAAiB,qBAAqB,CAAA;AAE5D,EAAA,IAAI,CAAC,OAAA,EAAS,MAAA,EAAQ,OAAO,IAAA;AAE7B,EAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sGACZ,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,EAAO,CAAA,qBACnBD,IAAAA,CAAC,KAAA,EAAA,EAAY,WAAU,8BAAA,EACrB,QAAA,EAAA;AAAA,oBAAAC,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,0CAAA;AAAA,QAEV,KAAA,EAAO,EAAE,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA,EAAI,eAAA,EAAiB,KAAA,CAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,YAAA,EAAe,UAAA,CAAW,KAAK,CAAC,CAAA,CAAA;AAAG;AAAA,KAC3G;AAAA,oBACAA,IAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,aAAA,EAAc,EAAI,QAAA,EAAA,KAAA,CAAM,KAAA,EAAM;AAAA,GAAA,EAAA,EAN5C,CAOV,CACD,CAAA,EACH,CAAA;AAEJ;AAGO,SAAS,YAAA,CAAa,KAAA,EAA8B,EAAA,GAA0B,SAAA,EAAW;AAC9F,EAAA,OAAO,CAAC,IAAA,KAAiD;AACvD,IAAA,MAAM,GAAA,GAAM,EAAA,KAAO,SAAA,GAAY,IAAA,CAAK,UAAU,IAAA,CAAK,KAAA;AACnD,IAAA,MAAM,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,GAAG,CAAC,CAAA;AACnC,IAAA,OAAO,CAAA,GAAI,CAAA,GAAI,KAAA,CAAM,MAAA,GAAS,CAAA;AAAA,EAChC,CAAA;AACF;AAOO,SAAS,WAAA,CAAY,EAAE,KAAA,EAAO,EAAA,GAAK,WAAU,EAA+D;AACjH,EAAA,MAAM,EAAE,MAAA,EAAO,GAAIF,UAAAA,CAAW,iBAAiB,CAAA;AAC/C,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,IAAA,CAAK,GAAQ,CAAA;AAEpC,EAAA,MAAM,MAAA,GAASG,OAAAA,CAAQ,MAAM,YAAA,CAAa,KAAA,EAAO,EAAE,CAAA,EAAG,CAAC,QAAA,EAAU,EAAE,CAAC,CAAA;AACpE,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,uBAAOD,GAAAA,CAAC,MAAA,EAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,yBAASA,GAAAA,CAAC,kBAAA,EAAA,EAAmB,CAAA,EAAI,YAAY,MAAA,EAAQ,YAAA,EAAc,EAAE,UAAA,EAAY,qBAAoB,EAAG,CAAA;AACzI;AAEO,SAAS,aAAA,GAAwB;AACtC,EAAA,OAAO,iBAAiB,oBAAoB,CAAA;AAC9C;AAEO,SAAS,YAAA,GAAe;AAC7B,EAAA,MAAM,SAAA,GAAY,iBAAiB,iBAAiB,CAAA;AAEpD,EAAA,OAAO;AAAA,IACL,IAAA,EAAM;AAAA,MACJ,QAAA,EAAU,wBAAA;AAAA,MACV,UAAA,EAAY,qBAAA;AAAA,MACZ,IAAA,EAAM,SAAA;AAAA;AAAA;AAAA;AAAA,MAIN,MAAA,EAAQ;AAAA;AACV,GACF;AACF;AAEO,SAAS,SAAA,GAAoB;AAClC,EAAA,MAAM,GAAA,GAAM,iBAAiB,gBAAgB,CAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,EAAK,EAAE,CAAA;AAC/B,EAAA,OAAO,KAAA,CAAM,MAAM,CAAA,GAAI,CAAA,GAAI,MAAA;AAC7B;AAMO,SAAS,UAAU,KAAA,EAAgC;AAMxD,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAO,QAAQ,iBAAA,EAAmB,MAAA,EAAQ,GAAG,IAAA,EAAK,GAAI,KAAA;AAI7E,EAAA,uBACEA,GAAAA,CAAC,IAAA,EAAA,EAAM,GAAG,IAAA,EAAM,CAAA,EAAM,CAAA,EAAM,UAAA,EAAW,QAAA,EAAS,cAAA,EAAe,OAAA,EAC5D,QAAA,EAAA,OAAA,CAAQ,KAAA,EACX,CAAA;AAEJ;AAcA,IAAM,OAAA,GAAU,GAAA;AAET,IAAM,QAAA,GAAW,CAAA;AAKjB,IAAM,iBAAA,GAAoB,EAAA;AAS1B,SAAS,SAAA,CAAU,OAAA,EAAyB,WAAA,EAAwB,MAAA,EAAiB;AAC1F,EAAA,OAAO,SAAS,UAAU,KAAA,EAAgC;AACxD,IAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAO,mBAAmB,SAAA,EAAW,IAAA,EAAM,QAAA,EAAU,UAAA,EAAW,GAAI,KAAA;AAI3F,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,EAAS,KAAA,IAAS,EAAE,CAAA;AACxC,IAAA,MAAM,IAAA,GAAO,gBAAgB,GAAA,GAAA,CACxB,MAAA,CAAO,KAAK,CAAA,IAAK,CAAA,IAAK,KAAK,GAAA,CAAI,CAAA,EAAG,OAAO,iBAAiB,CAAA,IAAK,CAAC,CAAA,GAAI,QAAA,GAAA,CACpE,WAAW,MAAA,CAAO,KAAK,KAAK,CAAA,CAAA,IAAM,iBAAA;AACvC,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,IAAA,EAAM,IAAA,EAAM,OAAO,CAAA;AACxC,IAAA,MAAM,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,UAAA,EAAY,QAAQ,MAAA,EAAO;AAE1D,IAAA,MAAM,OAAA,GAAU,gBAAgB,GAAA,GAAM,IAAA,GAAO,SAAU,GAAA,CAAI,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,OAAA,GAAW,CAAA;AAC1F,IAAA,uBACED,IAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAsB,UAAA,EAAU,GAAA,CAAI,GAAA,GAAM,EAAA,GAAK,MAAA,EAAW,YAAA,EAAY,GAAA,CAAI,KAAA,CAAM,MAAA,EACjF,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAAC,WAAO,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,MACZ,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,qBACpBA,GAAAA,CAAC,MAAA,EAAA,EAAa,CAAA,EAAM,CAAA,EAAM,EAAA,EAAI,CAAA,EAAG,UAAU,CAAA,GAAI,OAAO,CAAA,EAAA,CAAA,EAAM,UAAA,EAAY,WAAA,KAAgB,GAAA,GAAM,QAAA,GAAW,KAAA,EAAQ,GAAG,IAAA,EACjH,QAAA,EAAA,IAAA,EAAA,EADQ,CAEX,CACD;AAAA,KAAA,EACH,CAAA;AAAA,EAEJ,CAAA;AACF;AAsBO,SAAS,cAAA,CAAe,GAAA,EAAuC,OAAA,GAAU,IAAA,EAAmB;AACjG,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIJ,SAAsB,EAAE,OAAA,EAAS,IAAA,EAAM,EAAA,EAAI,EAAA,EAAI,KAAA,EAAO,EAAA,EAAI,KAAA,EAAO,GAAG,CAAA;AAC9F,EAAAC,gBAAgB,MAAM;AACpB,IAAA,MAAM,KAAK,GAAA,CAAI,OAAA;AACf,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,EAAA,EAAI;AACrB,IAAA,IAAI,IAAA,GAAO,IAAA;AACX,IAAA,IAAI,IAAA,GAAO,EAAA;AACX,IAAA,MAAM,MAAA,GAAS,CAAC,KAAA,GAAQ,KAAA,KAAU;AAChC,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,MAAM,WAAW,EAAA,CAAG,WAAA;AACpB,MAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,aAAA,CAA2B,oBAAoB,CAAA;AAChE,MAAA,MAAM,GAAA,GAAM,KAAA,EAAO,qBAAA,EAAsB,CAAE,MAAA,IAAU,CAAA;AACrD,MAAA,MAAM,IAAA,GAAO,mBAAmB,EAAE,CAAA;AAClC,MAAA,QAAA,CAAS,CAAC,IAAA,KAAS;AAEjB,QAAA,MAAM,KAAA,GAAQ,QAAA,GAAW,CAAA,GAAI,QAAA,GAAW,IAAA,CAAK,KAAA;AAC7C,QAAA,MAAM,KAAA,GAAQ,GAAA,GAAM,CAAA,GAAI,GAAA,GAAM,IAAA,CAAK,KAAA;AACnC,QAAA,IAAI,CAAC,IAAA,EAAM,OAAO,IAAA,CAAK,KAAA,KAAU,QAAQ,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,KAAA,EAAM;AACjE,QAAA,IAAI,CAAC,KAAA,IAAS,IAAA,CAAK,IAAA,KAAS,IAAA,IAAQ,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,KAAA,KAAU,KAAA,IAAS,IAAA,CAAK,KAAA,KAAU,OAAO,OAAO,IAAA;AACzG,QAAA,MAAM,OAAO,CAAC,KAAA,IAAS,IAAA,CAAK,IAAA,KAAS,QAAQ,IAAA,CAAK,OAAA;AAClD,QAAA,IAAA,GAAO,IAAA,CAAK,IAAA;AACZ,QAAA,OAAO,EAAE,OAAA,EAAS,IAAA,GAAO,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,EAAS,EAAA,EAAI,IAAA,CAAK,EAAA,EAAI,KAAA,EAAO,KAAA,EAAM;AAAA,MAClF,CAAC,CAAA;AAAA,IACH,CAAA;AACA,IAAA,MAAA,CAAO,IAAI,CAAA;AACX,IAAA,MAAM,EAAA,GAAK,OAAO,cAAA,KAAmB,WAAA,GAAc,IAAI,cAAA,CAAe,MAAM,MAAA,EAAQ,CAAA,GAAI,IAAA;AACxF,IAAA,EAAA,EAAI,QAAQ,EAAE,CAAA;AACd,IAAA,MAAM,KAAA,GAAS,OAAO,QAAA,KAAa,WAAA,GAAe,SAA4C,KAAA,GAAQ,MAAA;AACtG,IAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,IAAI,CAAA;AAChC,IAAA,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,MAAA,EAAQ,MAAM;AAAA,IAAC,CAAC,CAAA;AAClC,IAAA,KAAA,EAAO,gBAAA,GAAmB,eAAe,MAAM,CAAA;AAC/C,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,GAAO,KAAA;AACP,MAAA,EAAA,EAAI,UAAA,EAAW;AACf,MAAA,KAAA,EAAO,mBAAA,GAAsB,eAAe,MAAM,CAAA;AAAA,IACpD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,OAAO,CAAC,CAAA;AACjB,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,cAAA,CAAe,MAAA,EAAkB,OAAA,EAAkB,MAAA,GAAoC,MAAA,EAAgB;AACrH,EAAA,MAAM,KAAA,GAAQ,eAAe,MAAM,CAAA;AACnC,EAAA,IAAI,CAAC,KAAA,CAAM,MAAA,EAAQ,OAAO,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA,GAAI,CAAA;AAC1D,EAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,GAAG,MAAM,GAAA,CAAI,CAAC,CAAA,KAAM,OAAA,CAAQ,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA,GAAI,CAAA;AACxE;AAGA,IAAM,iBAAA,GAAoB,EAAA;AAOnB,SAAS,iBAAA,CAAkB,OAAA,EAAkB,KAAA,EAAiB,CAAA,EAAgB,WAAmB,WAAA,EAA8B;AACpI,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAID,SAAS,KAAK,CAAA;AAC1C,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,GAAQ,CAAA;AAC/B,EAAA,MAAM,GAAA,GAAMK,QAAQ,MAAM;AACxB,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,CAAA,CAAE,OAAA,IAAW,EAAE,KAAA,IAAS,CAAA,IAAK,KAAA,CAAM,MAAA,KAAW,GAAG,OAAO,EAAE,IAAA,EAAM,KAAA,EAAO,UAAU,KAAA,EAAM;AACxG,IAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,KAAkB,aAAA,CAAc,KAAA,EAAA,CAAQ,KAAA,GAAQ,WAAA,GAAc,SAAA,IAAa,KAAA,CAAM,MAAA,GAAS,QAAA,EAAU,CAAA,CAAE,OAAQ,CAAA;AAC7H,IAAA,OAAO,EAAE,IAAA,EAAM,KAAA,CAAM,CAAA,CAAE,KAAK,CAAA,EAAG,QAAA,EAAU,KAAA,CAAM,CAAA,CAAE,KAAA,GAAQ,iBAAiB,CAAA,EAAE;AAAA,EAE9E,CAAA,EAAG,CAAC,OAAA,EAAS,GAAA,EAAK,CAAA,CAAE,SAAS,CAAA,CAAE,KAAA,EAAO,SAAA,EAAW,WAAW,CAAC,CAAA;AAE7D,EAAA,MAAM,WAAW,MAAA,GAAS,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,WAAW,GAAA,CAAI,IAAA;AACzD,EAAA,IAAI,QAAA,KAAa,MAAA,EAAQ,SAAA,CAAU,QAAQ,CAAA;AAC3C,EAAA,OAAO,QAAA;AACT;AAGO,SAAS,UAAA,CAAW,OAAiB,CAAA,EAAoC;AAC9E,EAAA,IAAI,CAAC,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,KAAA,IAAS,GAAG,OAAO,MAAA;AACvC,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA,CAAE,QAAS,CAAA,CAAE,OAAA,CAAQ,QAAQ,GAAG,CAAA,CAAE,MAAM,CAAC,GAAG,CAAC,CAAA;AAC/F,EAAA,OAAO,KAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,GAAA,CAAI,KAAK,IAAA,CAAK,MAAM,CAAA,GAAI,iBAAA,EAAmB,KAAK,KAAA,CAAM,CAAA,CAAE,KAAA,GAAQ,CAAC,CAAC,CAAC,CAAA;AAC9F;AAGO,SAAS,YAAA,CAAa,KAAA,EAAiB,MAAA,EAA4B,CAAA,EAAwB;AAChG,EAAA,IAAI,CAAC,CAAA,CAAE,OAAA,IAAW,MAAA,KAAW,QAAW,OAAO,CAAA;AAC/C,EAAA,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,SAAS,CAAA,EAAG,MAAA,GAAS,iBAAA,EAAmB,CAAA,CAAE,OAAO,CAAA,CAAE,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,CAAE,MAAA;AAClG;AAGA,SAAS,WAAA,CAAY,IAAiB,MAAA,EAAiC;AACrE,EAAA,MAAM,QAAA,GAAW,mBAAmB,EAAE,CAAA;AACtC,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAC,GAAG,CAAC,CAAA;AACpE;AAEA,IAAM,QAAA,GAAW,EAAA;AACjB,IAAM,YAAA,GAAe,EAAA;AAcd,SAAS,iBACd,IAAA,EACA,QAAA,EACA,GAAA,EACA,QAAA,EACA,OAAqB,OAAA,EAC6C;AAClE,EAAA,MAAM,SAASA,OAAAA,CAAQ,MAAA,CAAO,QAAQ,EAAC,EAAG,IAAI,CAAC,CAAA,KAAM,OAAO,CAAA,CAAE,QAAQ,KAAK,EAAE,CAAC,GAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AACjG,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,GAAQ,CAAA;AACtC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIL,SAA+B,MAAS,CAAA;AAElE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,SAAS,CAAC,CAAA;AAI5C,EAAA,MAAM,OAAA,GAAU,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,MAAA;AAC1D,EAAA,MAAM,QAAQ,IAAA,KAAS,OAAA;AACvB,EAAAM,UAAU,MAAM;AACd,IAAA,MAAM,KAAK,GAAA,CAAI,OAAA;AACf,IAAA,IAAI,SAAS,OAAA,KAAY,MAAA,IAAa,CAAC,EAAA,IAAM,MAAA,CAAO,WAAW,CAAA,EAAG;AAClE,IAAA,IAAI,IAAA,GAAO,IAAA;AACX,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,IAAI,CAAC,IAAA,EAAM;AAEX,MAAA,IAAI,EAAA,CAAG,eAAe,CAAA,EAAG;AACzB,MAAA,MAAM,MAAA,GAAS,WAAA,CAAY,EAAA,EAAI,MAAM,CAAA;AACrC,MAAA,MAAM,IAAA,GAAO,GAAG,WAAA,GAAc,YAAA;AAC9B,MAAA,IAAI,MAAA,IAAU,IAAA,IAAQ,IAAA,IAAQ,CAAA,EAAG;AAAE,QAAA,QAAA,CAAS,MAAS,CAAA;AAAG,QAAA;AAAA,MAAQ;AAChE,MAAA,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,KAAK,MAAA,GAAS,CAAC,CAAC,CAAC,CAAA;AAC/C,MAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,IAAA,IAAQ,MAAA,GAAS,QAAA,CAAS,CAAC,CAAA;AAC/D,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,SAAS,IAAI,CAAA;AAG3C,MAAA,QAAA,CAAS,MAAA,CAAO,OAAO,CAAC,CAAA,EAAG,MAAM,CAAA,GAAI,IAAA,KAAS,CAAC,CAAC,CAAA;AAAA,IAClD,CAAA;AACA,IAAA,IAAI,OAAO,mBAAmB,WAAA,EAAa;AAC3C,IAAA,MAAM,EAAA,GAAK,IAAI,cAAA,CAAe,OAAO,CAAA;AACrC,IAAA,EAAA,CAAG,QAAQ,EAAE,CAAA;AACb,IAAA,MAAM,QAAS,QAAA,CAAgE,KAAA;AAC/E,IAAA,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,MAAM;AAAA,IAAC,CAAC,CAAA;AACnC,IAAA,OAAO,MAAM;AAAE,MAAA,IAAA,GAAO,KAAA;AAAO,MAAA,EAAA,CAAG,UAAA,EAAW;AAAA,IAAG,CAAA;AAAA,EAEhD,GAAG,CAAC,SAAA,EAAW,OAAA,EAAS,KAAA,EAAO,GAAG,CAAC,CAAA;AACnC,EAAA,IAAI,OAAO,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,WAAW,CAAA,EAAE;AAC9C,EAAA,IAAI,YAAY,MAAA,EAAW,OAAO,EAAE,QAAA,EAAU,OAAA,EAAS,WAAW,CAAA,EAAE;AACpE,EAAA,OAAO,KAAA,GAAQ,EAAE,KAAA,EAAO,QAAA,EAAU,CAAA,EAAG,SAAA,EAAU,GAAI,EAAE,QAAA,EAAU,kBAAA,EAAoB,SAAA,EAAW,CAAA,EAAE;AAClG;AClZO,SAAS,UAAA,CAAW,KAAa,OAAA,EAAsC;AAC5E,EAAA,OAAO,GAAA,CAAI,OAAA,KAAY,OAAA,GAAU,OAAA,GAAU,MAAA,CAAA;AAC7C;AAGO,SAAS,QAAA,CAAS,MAAgB,OAAA,EAA2B;AAClE,EAAA,OAAO,IAAA,CAAK,KAAK,CAAC,GAAA,KAAQ,WAAW,GAAA,EAAK,OAAO,KAAK,IAAI,CAAA;AAC5D;AAGO,SAAS,SAAA,CAAU,MAAgB,OAAA,EAA0B;AAClE,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,IAAI,GAAA,CAAI,IAAA,CAAK,IAAI,CAAC,GAAA,EAAK,MAAM,UAAA,CAAW,GAAA,EAAK,OAAO,CAAA,IAAK,CAAA,EAAA,EAAS,CAAC,CAAA,CAAE,CAAC,EAAE,IAAI,CAAA;AACjG;AAOO,SAAS,SAAS,IAAA,EAAgB,KAAA,EAAe,OAAA,EAAkB,MAAA,EAAgB,aAAa,KAAA,EAAO;AAC5G,EAAA,MAAM,KAAA,GAA0C,UAAA,GAAa,CAAC,CAAA,EAAG,MAAA,EAAQ,MAAA,EAAQ,CAAC,CAAA,GAAI,CAAC,MAAA,EAAQ,MAAA,EAAQ,CAAA,EAAG,CAAC,CAAA;AAC3G,EAAA,MAAM,MAAA,GAA2C,CAAC,CAAA,EAAG,CAAA,EAAG,GAAG,CAAC,CAAA;AAC5D,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,KAAK,GAAG,OAAO,CAAA;AAC7C,EAAA,MAAM,QAAQ,KAAA,IAAS,IAAA,GAAO,EAAC,GAAI,KAAK,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,IAAI,KAAA,IAAS,UAAA,CAAW,CAAA,EAAG,OAAO,MAAM,KAAK,CAAA;AAGtG,EAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,KAAmB;AAChC,IAAA,MAAM,CAAA,GAAI,KAAA;AACV,IAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,IAAW,EAAC;AAC1B,IAAA,MAAM,IAAA,GAAO,OAAO,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA,CAAE,OAAO,CAAC,CAAA,GAAI,CAAA;AAChD,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,KAAM;AAC/B,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,OAAO,CAAC,CAAA;AACnC,MAAA,OAAO,EAAE,IAAA,GAAO,KAAA,GAAQ,CAAA,GAAI,KAAA,GAAQ,CAAA,CAAA;AAAA,IACtC,CAAC,CAAA;AACD,IAAA,uBAAOF,IAAC,SAAA,EAAA,EAAW,GAAI,OAAkB,MAAA,EAAQ,KAAA,GAAQ,QAAQ,MAAA,EAAQ,CAAA;AAAA,EAC3E,CAAA;AACA,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,WAAA,CAAY,IAAA,EAAiC,IAAA,EAAgB,OAAA,EAA4B;AAChG,EAAA,OAAO,WAAW,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,CAAC,SAAS,EAAE,OAAA,EAAS,GAAA,CAAI,OAAA,EAAS,OAAO,UAAA,CAAW,GAAA,EAAK,OAAO,CAAA,IAAK,IAAA,GAAO,CAAC,CAAA;AAChH;AAGA,IAAM,YAAY,CAAC,EAAA,KAAe,KAAK,IAAA,CAAK,EAAA,GAAK,GAAG,CAAA,GAAI,CAAA;AAExD,IAAM,cAAA,GAAiB,0CAAA;AA+ChB,IAAM,QAAA,GAAW,SAAA,CAAUG,UAAAA,CAA0C,SAASC,SAAAA,CAAS;AAAA,EAC5F,IAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,OAAA,GAAU,KAAA;AAAA,EACV,UAAA;AAAA,EACA,YAAA,EAAAT,aAAAA;AAAA,EACA,QAAA,GAAW,IAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,UAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,UAAA,GAAaU,OAA8B,IAAI,CAAA;AACrD,EAAA,MAAM,SAASJ,OAAAA,CAAQ,MAAA,CAAO,QAAQ,EAAC,EAAG,IAAI,CAAC,CAAA,KAAM,OAAO,CAAA,CAAE,QAAQ,KAAK,EAAE,CAAC,GAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAEjG,EAAA,MAAM,SAAS,eAAA,EAAgB;AAG/B,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,IAAA,GAAON,aAAAA,IAAgB,YAAA,CAAA,CAAmB,IAAA,IAAQ,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAC,CAAA,EAAG,QAAA,GAAW,SAAY,MAAM,CAAA;AAClH,EAAA,MAAM,QAAQ,IAAA,KAAS,OAAA;AACvB,EAAA,MAAM,WAAW,cAAA,CAAe,UAAA,EAAA,CAAa,IAAA,EAAM,MAAA,IAAU,KAAK,CAAC,CAAA;AACnE,EAAA,MAAM,MAAA,GAASM,OAAAA,CAAQ,MAAM,WAAA,CAAY,QAAQ,EAAC,EAAG,IAAA,EAAM,OAAO,CAAA,EAAG,CAAC,IAAA,EAAM,IAAA,EAAM,OAAO,CAAC,CAAA;AAC1F,EAAA,MAAM,UAAA,GAAaA,OAAAA,CAAQ,MAAM,iBAAA,CAAkB,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAC,CAAA;AAC9G,EAAA,MAAM,UAAA,GAAaA,OAAAA,CAAQ,MAAM,kBAAA,CAAmB,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,WAAA,EAAa,MAAM,CAAC,CAAA;AAC/F,EAAA,MAAM,SAAA,GAAYA,OAAAA;AAAA,IAChB,MAAO,SAAS,OAAA,GAAU,cAAA,CAAe,QAAQ,QAAA,CAAS,OAAA,EAAS,UAAU,CAAA,GAAI,CAAA;AAAA,IACjF,CAAC,QAAA,CAAS,OAAA,EAAS,MAAA,EAAQ,UAAU;AAAA,GACvC;AACA,EAAA,MAAM,MAAA,GAAS,kBAAkB,UAAA,KAAe,MAAA,IAAa,OAAO,MAAA,EAAQ,QAAA,EAAU,WAAW,CAAC,CAAA;AAClG,EAAA,MAAM,WAAW,UAAA,IAAc,MAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,iBAAiB,IAAA,EAAM,QAAA,EAAU,YAAY,aAAA,EAAe,QAAA,IAAY,KAAA,GAAQ,OAAA,GAAU,OAAO,CAAA;AAChH,EAAA,MAAM,MAAA,GAAS,QAAA,GAAW,UAAA,CAAW,MAAA,EAAQ,QAAQ,CAAA,GAAI,MAAA;AACzD,EAAA,MAAM,OAAA,GAAUA,OAAAA,CAAQ,MAAM,SAAA,CAAU,QAAA,CAAS,OAAA,EAAS,GAAG,CAAA,EAAG,CAAC,QAAA,CAAS,OAAO,CAAC,CAAA;AAClF,EAAA,MAAM,IAAA,GAAOA,OAAAA,CAAQ,MAAM,SAAA,CAAU,QAAA,CAAS,OAAA,EAAS,GAAA,EAAK,MAAM,CAAA,EAAG,CAAC,QAAA,CAAS,OAAA,EAAS,MAAM,CAAC,CAAA;AAC/F,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,KAAK,CAAA;AACrD,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAA;AACnD,EAAA,MAAM,aAAa,aAAA,EAAc;AACjC,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAC7C,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,aAAA,GAAgB,UAAA,IAAc,IAAA,CAAK,MAAA,IAAU,CAAA;AAInD,EAAA,MAAM,UAAA,GAAa,UAAA,KAAe,IAAA,GAAO,UAAA,GAAa,UAAA;AACtD,EAAA,MAAM,aAAA,GAAgB,UAAA,KAAe,IAAA,GAAO,UAAA,GAAa,UAAA;AACzD,EAAA,MAAM,QAAA,GAAW,WAAW,aAAA,GAAgB,UAAA;AAC5C,EAAA,MAAM,WAAA,GAAc,WAAW,UAAA,GAAa,aAAA;AAC5C,EAAA,MAAM,cAAA,GAAiB,EAAE,QAAA,EAAU,wBAAA,EAA0B,YAAY,qBAAA,EAAuB,IAAA,EAAM,SAAA,CAAU,IAAA,CAAK,IAAA,EAAK;AAC1H,EAAA,MAAM,WAAA,GAAc,WAAA,GAAc,EAAE,KAAA,EAAO,WAAA,EAAa,QAAA,EAAU,cAAA,EAAyB,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,cAAA,EAAe,GAAI,MAAA;AAEjI,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,OAAO,CAAA;AACtC,EAAA,MAAM,WAAA,GAAc,CAAA,GAAI,GAAA,IAAO,MAAA,GAAS,CAAA,CAAA;AACxC,EAAA,MAAM,SAAS,CAAC,QAAA,EAAU,WAAW,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,MAAA;AACvD,EAAA,MAAM,OAAO,QAAA,GACT;AAAA,IACE,KAAA,EAAO,MAAA;AAAA,IACP,KAAA,EAAO,OAAO,MAAA,GAAS,WAAA;AAAA,IACvB,KAAA,EAAO,YAAA,CAAa,MAAA,EAAQ,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC5C,IAAA,EAAM,SAAS,CAAA,KAAA,EAAQ,SAAS,MAAM,MAAM,CAAA,GAAA,EAAM,cAAc,CAAA,CAAA,CAAA,GAAM;AAAA,GACxE,GACA,EAAE,KAAA,EAAO,OAAA,EAAiB;AAE9B,EAAA,MAAM,UAAA,GAAa,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAO,QAAA,CAAS,KAAA,GAAQ,WAAA,GAAc,GAAA,GAAO,MAAM,CAAC,CAAA,GAAI,MAAA;AAEvG,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACED,GAAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,SAAA,CAAU,GAAA,EAAyB,UAA8B,CAAA;AAAA,MACtE,MAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA,EAAM,KAAA;AAAA,MACN,YAAA,EAAc,IAAA;AAAA,MACd,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,YAAA,EAAc,WAAW,GAAA,GAAM,GAAA;AAAA,MAC/B,QAAA;AAAA,MACA,SAAA,EAAW,QAAA;AAAA,MACX,WAAA,EAAa,UAAA;AAAA,MACb,SAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MAEZ,0BAAAA,GAAAA,CAAC,mBAAA,EAAA,EAAoB,OAAM,MAAA,EAAO,MAAA,EAAO,QACvC,QAAA,kBAAAD,IAAAA;AAAA,QAACO,UAAA;AAAA,QAAA;AAAA,UACC,IAAA;AAAA,UACA,MAAA,EAAQ,WAAW,UAAA,GAAa,YAAA;AAAA,UAChC,WAAA,EAAa,QAAA,CAAS,IAAA,EAAM,OAAO,IAAI,MAAA,GAAS,MAAA;AAAA,UAEhD,QAAQ,EAAE,GAAA,EAAK,KAAK,QAAA,GAAW,SAAA,CAAU,SAAS,EAAE,CAAA,GAAI,IAAI,KAAA,EAAO,QAAA,IAAY,QAAQ,CAAA,GAAI,MAAA,CAAO,WAAW,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,EAAE;AAAA,UAChI,kBAAA,EAAkB,IAAA;AAAA,UAEjB,QAAA,EAAA;AAAA,YAAA,QAAA,oBACCN,GAAAA,CAAC,aAAA,EAAA,EAAc,eAAA,EAAgB,KAAA,EAAM,MAAA,EAAQ,UAAA,EAAY,QAAA,EAAU,CAAC,QAAA,EAAU,UAAA,EAAU,IAAA,EAAC,CAAA;AAAA,YAE1F,QAAA,mBACCD,IAAAA,CAAAQ,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,8BAAAP,IAAC,KAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAU,GAAG,UAAU,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,OAAO,MAAA,EAAO,MAAA,EAAO,KAAA,EAAO,WAAA,EAAa,eAAe,UAAA,EAAY,CAAA;AAAA,8BACxIA,GAAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,QAAA;AAAA,kBACT,IAAA,EAAK,UAAA;AAAA,kBACL,OAAO,MAAA,IAAU,MAAA;AAAA,kBAChB,GAAG,SAAA,CAAU,IAAA;AAAA,kBACd,QAAA,EAAU,KAAA;AAAA,kBACV,QAAA,EAAU,KAAA;AAAA,kBACV,QAAA,EAAU,CAAA;AAAA,kBACV,IAAA,EAAM;AAAA;AAAA;AACR,aAAA,EACF,CAAA,mBAEAD,IAAAA,CAAAQ,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,8BAAAP,GAAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,QAAA;AAAA,kBACR,GAAG,SAAA,CAAU,IAAA;AAAA,kBACd,QAAA,EAAU,KAAA;AAAA,kBACV,QAAA,EAAU,KAAA;AAAA,kBACV,IAAA,EAAM,QAAQ,OAAA,GAAU,SAAA;AAAA,kBACxB,UAAU,MAAA,CAAO,QAAA;AAAA,kBACjB,OAAO,MAAA,CAAO,KAAA;AAAA,kBACd,MAAA,EAAO,MAAA;AAAA,kBACP,KAAA,EAAO;AAAA;AAAA,eACT;AAAA,8BACAA,GAAAA,CAAC,KAAA,EAAA,EAAM,KAAA,EAAM,MAAA,EAAQ,GAAG,SAAA,CAAU,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,eAAe,UAAA,EAAY;AAAA,aAAA,EACvG,CAAA;AAAA,YAED,WAAA,oBAAeA,GAAAA,CAAC,OAAA,EAAA,EAAQ,yBAASA,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,QAAQ,EAAE,IAAA,EAAM,oBAAA,EAAsB,OAAA,EAAS,KAAI,EAAG,CAAA;AAAA,YAChH,aAAA,oBAAiBA,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAA,EAAG,CAAA;AAAA,YACjE,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAK,sBACdA,GAAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBAEC,SAAS,GAAA,CAAI,OAAA;AAAA,gBACb,IAAA,EAAM,GAAA,CAAI,KAAA,IAAS,GAAA,CAAI,OAAA;AAAA,gBACvB,MAAM,GAAA,CAAI,IAAA,GAAO,WAAW,CAAC,CAAA,GAAI,YAAY,CAAC,CAAA;AAAA,gBAE9C,MAAA,EAAQ,GAAA,CAAI,IAAA,GAAO,WAAA,CAAY,CAAC,CAAA,GAAI,MAAA;AAAA,gBACpC,WAAA,EAAa,GAAA,CAAI,IAAA,GAAO,CAAA,GAAI,MAAA;AAAA,gBAC5B,OAAO,QAAA,CAAS,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,QAAQ,QAAQ,CAAA;AAAA,gBAClD,OAAA,EAAS,UAAA,CAAW,GAAA,EAAK,OAAO,CAAA;AAAA,gBAChC,UAAA;AAAA,gBACA,iBAAA,EAAmB;AAAA,eAAA;AAAA,cAVd,GAAA,CAAI;AAAA,aAYZ;AAAA;AAAA;AAAA,OACH,EACF;AAAA;AAAA,GACF;AAEJ,CAAC,CAAC;ACrOK,IAAM,SAAA,GAAY,SAAA,CAAUG,UAAAA,CAA2C,SAASK,UAAAA,CAAU;AAAA,EAC/F,IAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,MAAA,GAAS,IAAA;AAAA,EACT,QAAA,GAAW,KAAA;AAAA,EACX,QAAA,GAAW,IAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,UAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,UAAA,GAAaH,OAA8B,IAAI,CAAA;AACrD,EAAA,MAAM,SAASJ,OAAAA,CAAQ,MAAM,aAAa,IAAA,IAAQ,IAAI,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAA,EAAG,KAAK,GAAG,CAAC,IAAA,EAAM,KAAK,CAAC,CAAA;AAExG,EAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,EAAA,MAAM,UAAA,GAAaA,OAAAA,CAAQ,MAAM,iBAAA,CAAkB,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAC,CAAA;AAC9G,EAAA,MAAM,UAAA,GAAaA,OAAAA,CAAQ,MAAM,kBAAA,CAAmB,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,WAAA,EAAa,MAAM,CAAC,CAAA;AAE/F,EAAA,MAAM,SAAS,gBAAA,CAAiB,IAAA,EAAM,QAAA,EAAU,UAAA,EAAY,eAAe,OAAO,CAAA;AAClF,EAAA,MAAM,QAAA,GAAW,eAAe,UAAA,EAAY,CAAC,CAAC,UAAA,IAAA,CAAe,IAAA,EAAM,MAAA,IAAU,CAAA,IAAK,CAAC,CAAA;AACnF,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,KAAA,CAAM,MAAA,EAAQ,KAAK,CAAA;AACjD,EAAA,MAAM,aAAa,aAAA,EAAc;AACjC,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAC7C,EAAA,MAAM,aAAA,GAAgB,UAAA,IAAc,KAAA,CAAM,MAAA,IAAU,CAAA;AACpD,EAAA,MAAM,cAAA,GAAiB,EAAE,QAAA,EAAU,wBAAA,EAA0B,YAAY,qBAAA,EAAuB,IAAA,EAAM,SAAA,CAAU,IAAA,CAAK,IAAA,EAAK;AAC1H,EAAA,MAAM,GAAA,GAAM,KAAK,UAAA,GAAa,IAAA,CAAK,KAAK,QAAA,CAAS,EAAA,GAAK,GAAG,CAAA,GAAI,CAAA,GAAI,CAAA,CAAA;AAEjE,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACED,GAAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,SAAA,CAAU,GAAA,EAAyB,UAA8B,CAAA;AAAA,MACtE,MAAA;AAAA,MACA,IAAA,EAAM,EAAE,KAAA,EAAO,OAAA,EAAQ;AAAA,MACvB,KAAA,EAAM,MAAA;AAAA,MACN,YAAA,EAAa,OAAA;AAAA,MACb,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,YAAA,EAAa,GAAA;AAAA,MACb,SAAA,EAAW,UAAA;AAAA,MACX,WAAA,EAAa,UAAA;AAAA,MACb,SAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MAEZ,QAAA,kBAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,QAAO,MAAA,EAAO,MAAA,EACvC,QAAA,kBAAAV,IAAAA,CAACW,WAAA,EAAA,EAAkB,IAAA,EAAY,QAAQ,EAAE,GAAA,EAAK,KAAA,EAAO,MAAA,CAAO,SAAA,EAAW,MAAA,EAAQ,GAAG,IAAA,EAAM,CAAA,EAAE,EAAG,kBAAA,EAAkB,IAAA,EAC5G,QAAA,EAAA;AAAA,QAAA,QAAA,oBAAYV,GAAAA,CAACW,aAAAA,EAAA,EAAc,eAAA,EAAgB,KAAA,EAAM,QAAQ,UAAA,EAAY,CAAA;AAAA,wBACtEX,GAAAA;AAAA,UAACY,KAAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,QAAA;AAAA,YACR,GAAG,SAAA,CAAU,IAAA;AAAA,YACd,QAAA,EAAU,KAAA;AAAA,YACV,QAAA,EAAU,KAAA;AAAA,YACV,IAAA,EAAM,SAAA;AAAA,YACN,UAAU,MAAA,CAAO,QAAA;AAAA,YACjB,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,MAAA,EAAO,MAAA;AAAA,YACP,KAAA,EAAO,UAAA,GAAa,EAAE,KAAA,EAAO,UAAA,EAAY,QAAA,EAAU,cAAA,EAAgB,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,cAAA,EAAe,GAAI;AAAA;AAAA,SAC3G;AAAA,wBACAZ,GAAAA,CAACa,KAAAA,EAAA,EAAM,OAAM,MAAA,EAAQ,GAAG,SAAA,CAAU,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,eAAe,UAAA,EAAY,CAAA;AAAA,QACpG,WAAA,oBAAeb,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,CAAA;AAAA,QAC1D,aAAA,oBAAiBA,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAA,EAAG,CAAA;AAAA,QAClE,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,sBAChBA,GAAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAM,SAAS,UAAA,GAAa,QAAA;AAAA,YAC5B,SAAS,IAAA,CAAK,OAAA;AAAA,YACd,IAAA,EAAM,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,OAAA;AAAA,YACzB,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,YAChB,WAAA,EAAa,CAAA;AAAA,YACb,eAAA,EAAiB,IAAA,CAAK,MAAA,GAAS,KAAA,GAAQ,MAAA;AAAA,YACvC,GAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAW,EAAE,CAAA,EAAG,CAAA,EAAG,aAAa,CAAA,EAAE;AAAA,YAClC,iBAAA,EAAmB;AAAA,WAAA;AAAA,UATd,IAAA,CAAK;AAAA,SAWb;AAAA,OAAA,EACH,CAAA,EACF;AAAA;AAAA,GACF;AAEJ,CAAC,CAAC;ACtFK,IAAM,SAAA,GAAY,SAAA,CAAUG,UAAAA,CAA2C,SAASY,UAAAA,CAAU;AAAA,EAC/F,IAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,OAAA,GAAU,KAAA;AAAA,EACV,MAAA,GAAS,IAAA;AAAA,EACT,QAAA,GAAW,IAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,UAAA;AAAA,EACA,QAAA,GAAW,IAAA;AAAA,EACX,UAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,UAAA,GAAaV,OAA8B,IAAI,CAAA;AACrD,EAAA,MAAM,MAAA,GAASJ,QAAQ,MAAM,YAAA,CAAa,QAAQ,EAAC,EAAG,MAAM,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,OAAO,GAAG,OAAO,CAAA,EAAG,CAAC,IAAA,EAAM,KAAA,EAAO,OAAO,CAAC,CAAA;AAEnH,EAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,EAAA,MAAM,UAAA,GAAaA,OAAAA,CAAQ,MAAM,iBAAA,CAAkB,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAC,CAAA;AAC9G,EAAA,MAAM,UAAA,GAAaA,OAAAA,CAAQ,MAAM,kBAAA,CAAmB,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,WAAA,EAAa,MAAM,CAAC,CAAA;AAE/F,EAAA,MAAM,SAAS,gBAAA,CAAiB,IAAA,EAAM,QAAA,EAAU,UAAA,EAAY,eAAe,OAAO,CAAA;AAClF,EAAA,MAAM,QAAA,GAAW,eAAe,UAAA,EAAY,CAAC,CAAC,UAAA,IAAA,CAAe,IAAA,EAAM,MAAA,IAAU,CAAA,IAAK,CAAC,CAAA;AACnF,EAAA,MAAM,aAAa,KAAA,EAAM;AACzB,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,KAAA,CAAM,MAAA,EAAQ,KAAK,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,KAAA,CAAM,MAAA,EAAQ,IAAI,CAAA;AACpD,EAAA,MAAM,aAAa,aAAA,EAAc;AACjC,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAC7C,EAAA,MAAM,aAAA,GAAgB,UAAA,IAAc,KAAA,CAAM,MAAA,IAAU,CAAA;AACpD,EAAA,MAAM,cAAA,GAAiB,EAAE,QAAA,EAAU,wBAAA,EAA0B,YAAY,qBAAA,EAAuB,IAAA,EAAM,SAAA,CAAU,IAAA,CAAK,IAAA,EAAK;AAC1H,EAAA,MAAM,GAAA,GAAM,KAAK,UAAA,GAAa,IAAA,CAAK,KAAK,QAAA,CAAS,EAAA,GAAK,GAAG,CAAA,GAAI,CAAA,GAAI,CAAA,CAAA;AAEjE,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACED,GAAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,SAAA,CAAU,GAAA,EAAyB,UAA8B,CAAA;AAAA,MACtE,MAAA;AAAA,MACA,IAAA,EAAM,EAAE,KAAA,EAAO,OAAA,EAAQ;AAAA,MACvB,KAAA,EAAM,MAAA;AAAA,MACN,YAAA,EAAa,OAAA;AAAA,MACb,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,YAAA,EAAa,GAAA;AAAA,MACb,SAAA,EAAW,UAAA;AAAA,MACX,WAAA,EAAa,UAAA;AAAA,MACb,SAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MAEZ,QAAA,kBAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,QAAO,MAAA,EAAO,MAAA,EACvC,QAAA,kBAAAV,IAAAA,CAACiB,WAAA,EAAA,EAAkB,IAAA,EAAY,QAAQ,EAAE,GAAA,EAAK,KAAA,EAAO,MAAA,CAAO,SAAA,EAAW,MAAA,EAAQ,GAAG,IAAA,EAAM,CAAA,EAAE,EAAG,kBAAA,EAAkB,IAAA,EAC7G,QAAA,EAAA;AAAA,wBAAAhB,GAAAA,CAAC,MAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,CAAA,qBAChBD,IAAAA,CAAC,gBAAA,EAAA,EAAkC,EAAA,EAAI,CAAA,SAAA,EAAY,UAAU,CAAA,CAAA,EAAI,IAAA,CAAK,OAAO,CAAA,CAAA,EAAI,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EACvG,QAAA,EAAA;AAAA,0BAAAC,GAAAA,CAAC,UAAK,MAAA,EAAO,IAAA,EAAK,WAAW,UAAA,CAAW,CAAC,CAAA,EAAG,WAAA,EAAa,CAAA,EAAG,CAAA;AAAA,0BAC5DA,GAAAA,CAAC,MAAA,EAAA,EAAK,MAAA,EAAO,KAAA,EAAM,WAAW,UAAA,CAAW,CAAC,CAAA,EAAG,WAAA,EAAa,GAAA,EAAK;AAAA,SAAA,EAAA,EAF5C,IAAA,CAAK,OAG1B,CACD,CAAA,EACH,CAAA;AAAA,QACC,QAAA,oBAAYA,GAAAA,CAACW,aAAAA,EAAA,EAAc,eAAA,EAAgB,KAAA,EAAM,QAAQ,UAAA,EAAY,CAAA;AAAA,wBACtEX,GAAAA;AAAA,UAACY,KAAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,QAAA;AAAA,YACR,GAAG,SAAA,CAAU,IAAA;AAAA,YACd,QAAA,EAAU,KAAA;AAAA,YACV,QAAA,EAAU,KAAA;AAAA,YACV,IAAA,EAAM,SAAA;AAAA,YACN,UAAU,MAAA,CAAO,QAAA;AAAA,YACjB,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,MAAA,EAAO,MAAA;AAAA,YACP,KAAA,EAAO,UAAA,GAAa,EAAE,KAAA,EAAO,UAAA,EAAY,QAAA,EAAU,cAAA,EAAgB,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,cAAA,EAAe,GAAI;AAAA;AAAA,SAC3G;AAAA,wBACAZ,GAAAA,CAACa,KAAAA,EAAA,EAAM,OAAM,MAAA,EAAQ,GAAG,SAAA,CAAU,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,eAAe,UAAA,EAAY,CAAA;AAAA,QACpG,WAAA,oBAAeb,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,CAAA;AAAA,QAC1D,aAAA,oBAAiBA,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAA,EAAG,CAAA;AAAA,QAClE,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,sBAChBA,GAAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAM,SAAS,UAAA,GAAa,QAAA;AAAA,YAC5B,SAAS,IAAA,CAAK,OAAA;AAAA,YACd,IAAA,EAAM,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,OAAA;AAAA,YACzB,MAAA,EAAQ,YAAY,CAAC,CAAA;AAAA,YACrB,WAAA,EAAa,CAAA;AAAA,YACb,IAAA,EAAM,WAAW,CAAA,cAAA,EAAiB,UAAU,IAAI,IAAA,CAAK,OAAO,CAAA,CAAA,CAAA,GAAM,UAAA,CAAW,CAAC,CAAA;AAAA,YAC9E,OAAA,EAAS,UAAU,OAAA,GAAU,MAAA;AAAA,YAC7B,iBAAA,EAAmB;AAAA,WAAA;AAAA,UARd,IAAA,CAAK;AAAA,SAUb;AAAA,OAAA,EACH,CAAA,EACF;AAAA;AAAA,GACF;AAEJ,CAAC,CAAC;AC7HK,IAAM,QAAA,GAAW,SAAA,CAAUG,UAAAA,CAA0C,SAASc,SAAAA,CAAS;AAAA,EAC5F,IAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,KAAA,GAAQ,KAAA;AAAA,EACR,WAAA,GAAc,IAAA;AAAA,EACd,UAAA,GAAa,IAAA;AAAA,EACb,UAAA,GAAa,KAAA;AAAA,EACb,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,KAAK,CAAA;AAChD,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAE7C,EAAA,MAAM,WAAA,GAAc,UAAA,GAChB,CAAC,EAAE,OAAA,EAAQ,KAA4B,CAAA,EAAA,CAAA,CAAK,OAAA,IAAW,CAAA,IAAK,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA,GAC3E,KAAA;AAEJ,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACEjB,GAAAA,CAAC,YAAA,EAAA,EAAa,GAAA,EAAU,MAAA,EAAgB,IAAA,EAAM,EAAE,KAAA,EAAO,QAAA,EAAS,EAAG,KAAA,EAAM,KAAA,EAAM,SAAA,EAAsB,YAAA,EAAY,SAAA,EAC/G,QAAA,kBAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,MAAA,EAAO,MAAA,EAAO,MAAA,EACvC,QAAA,kBAAAV,IAAAA,CAACmB,UAAA,EAAA,EAAiB,kBAAA,EAAkB,IAAA,EAClC,QAAA,EAAA;AAAA,oBAAAlB,GAAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,OAAA,EAAQ,OAAA;AAAA,QACR,OAAA,EAAQ,MAAA;AAAA,QACR,EAAA,EAAG,KAAA;AAAA,QACH,EAAA,EAAG,KAAA;AAAA,QACH,WAAA,EAAY,KAAA;AAAA,QACZ,WAAA,EAAa,QAAQ,KAAA,GAAQ,CAAA;AAAA,QAC7B,KAAA,EAAO,WAAA;AAAA,QACP,SAAA,EAAW,UAAA;AAAA,QACX,iBAAA,EAAmB,UAAA;AAAA,QACnB,QAAA,EAAS,wBAAA;AAAA,QACT,UAAA,EAAW,qBAAA;AAAA,QAEV,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,sBACZA,GAAAA,CAAC,IAAA,EAAA,EAAa,IAAA,EAAM,OAAO,CAAA,GAAI,MAAA,CAAO,MAAM,CAAA,EAAA,EAAjC,CAAoC,CAChD;AAAA;AAAA,KACH;AAAA,IACC,WAAA,oBAAeA,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,CAAA;AAAA,IAC1D,UAAA,oBAAcA,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,EAAG,IAAG,OAAA,EAAQ;AAAA,GAAA,EACzE,GACF,CAAA,EACF,CAAA;AAEJ,CAAC,CAAC;ACOK,IAAM,cAAA,GAAiB,SAAA,CAAUG,UAAAA,CAAgD,SAASgB,eAAAA,CAAe;AAAA,EAC9G,IAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,OAAA,GAAU,KAAA;AAAA,EACV,QAAA,GAAW,CAAC,QAAA,CAAS,IAAA,EAAM,OAAO,CAAA;AAAA,EAClC,YAAA,EAAAxB,aAAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA,GAAW,IAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,UAAA,GAAa,IAAA;AAAA,EACb,UAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA,GAAkB,WAAA;AAAA,EAClB,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,UAAA,GAAaU,OAA8B,IAAI,CAAA;AACrD,EAAA,MAAM,SAASJ,OAAAA,CAAQ,MAAA,CAAO,QAAQ,EAAC,EAAG,IAAI,CAAC,CAAA,KAAM,OAAO,CAAA,CAAE,QAAQ,KAAK,EAAE,CAAC,GAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAEjG,EAAA,MAAM,SAAS,eAAA,EAAgB;AAE/B,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,IAAA,GAAON,aAAAA,IAAgB,YAAA,CAAA,CAAmB,IAAA,IAAQ,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAC,CAAA,EAAG,QAAA,GAAW,SAAY,MAAM,CAAA;AAClH,EAAA,MAAM,QAAQ,IAAA,KAAS,OAAA;AACvB,EAAA,MAAM,WAAW,cAAA,CAAe,UAAA,EAAA,CAAa,IAAA,EAAM,MAAA,IAAU,KAAK,CAAC,CAAA;AAEnE,EAAA,MAAM,CAAC,MAAA,EAAQ,UAAU,CAAA,GAAIM,QAAQ,MAAM;AAGzC,IAAA,MAAMmB,OAAAA,GAAS,UAAA,CAAW,IAAA,IAAQ,EAAC,EAAG;AAAA,MACpC,GAAG,IAAA,CAAK,GAAA,CAAI,CAAC,SAAS,EAAE,OAAA,EAAS,GAAA,CAAI,OAAA,EAAS,OAAO,UAAA,CAAW,GAAA,EAAK,OAAO,CAAA,IAAK,MAAK,CAAE,CAAA;AAAA,MACxF,GAAI,QAAA,GAAW,EAAC,GAAI,MAAM,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,OAAA,EAAS,KAAA,EAAO,MAAK,CAAE;AAAA,KAC3E,CAAA;AACD,IAAA,MAAMC,eAAc,IAAA,IAAQ,EAAC,EAAG,OAAA,CAAQ,CAAC,GAAA,KAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,MAAA,CAAO,GAAA,CAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;AACzF,IAAA,OAAO,CAACD,SAAQC,WAAU,CAAA;AAAA,EAC5B,GAAG,CAAC,IAAA,EAAM,MAAM,KAAA,EAAO,OAAA,EAAS,QAAQ,CAAC,CAAA;AACzC,EAAA,MAAM,UAAA,GAAapB,OAAAA,CAAQ,MAAM,iBAAA,CAAkB,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAC,CAAA;AAC9G,EAAA,MAAM,cAAA,GAAiBA,OAAAA,CAAQ,MAAM,iBAAA,CAAkB,UAAA,EAAY,eAAA,EAAiB,MAAM,CAAA,EAAG,CAAC,UAAA,EAAY,eAAA,EAAiB,MAAM,CAAC,CAAA;AAClI,EAAA,MAAM,UAAA,GAAaA,QAAQ,MAAM;AAC/B,IAAA,MAAM,GAAA,GAAM,kBAAA,CAAmB,WAAA,EAAa,MAAM,CAAA;AAClD,IAAA,MAAM,IAAA,GAAO,kBAAA,CAAmB,QAAA,GAAW,eAAA,GAAkB,aAAa,MAAM,CAAA;AAChF,IAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAC,CAAA;AACpD,IAAA,OAAO,CAAC,KAAA,EAAe,OAAA,KAAsB,OAAA,IAAW,QAAA,CAAS,GAAA,CAAI,OAAO,CAAA,GAAI,IAAA,CAAK,KAAK,CAAA,GAAI,GAAA,CAAI,KAAK,CAAA;AAAA,EACzG,GAAG,CAAC,WAAA,EAAa,iBAAiB,QAAA,EAAU,KAAA,EAAO,MAAM,CAAC,CAAA;AAE1D,EAAA,MAAM,SAAA,GAAYA,QAAQ,MAAM;AAC9B,IAAA,IAAI,CAAC,QAAA,CAAS,OAAA,EAAS,OAAO,CAAA;AAC9B,IAAA,OAAO,cAAA,CAAe,MAAA,EAAQ,QAAA,CAAS,OAAA,EAAS,UAAU,CAAA,IAAK,QAAA,GAAW,cAAA,CAAe,UAAA,EAAY,QAAA,CAAS,OAAA,EAAS,cAAc,CAAA,GAAI,CAAA,CAAA;AAAA,EAC3I,CAAA,EAAG,CAAC,QAAA,CAAS,OAAA,EAAS,QAAQ,UAAA,EAAY,UAAA,EAAY,cAAA,EAAgB,QAAQ,CAAC,CAAA;AAC/E,EAAA,MAAM,MAAA,GAAS,kBAAkB,UAAA,KAAe,MAAA,IAAa,OAAO,MAAA,EAAQ,QAAA,EAAU,WAAW,CAAC,CAAA;AAClG,EAAA,MAAM,WAAW,UAAA,IAAc,MAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,iBAAiB,IAAA,EAAM,QAAA,EAAU,YAAY,aAAA,EAAe,QAAA,GAAW,UAAU,IAAI,CAAA;AACpG,EAAA,MAAM,MAAA,GAAS,QAAA,GAAW,UAAA,CAAW,MAAA,EAAQ,QAAQ,CAAA,GAAI,MAAA;AACzD,EAAA,MAAM,IAAA,GAAOA,OAAAA,CAAQ,MAAO,KAAA,GAAQ,UAAU,QAAA,CAAS,OAAA,EAAS,GAAG,CAAA,GAAI,SAAA,EAAY,CAAC,KAAA,EAAO,QAAA,CAAS,OAAO,CAAC,CAAA;AAC5G,EAAA,MAAM,IAAA,GAAOA,OAAAA,CAAQ,MAAM,SAAA,CAAU,QAAA,CAAS,OAAA,EAAS,GAAA,EAAK,MAAM,CAAA,EAAG,CAAC,QAAA,CAAS,OAAA,EAAS,MAAM,CAAC,CAAA;AAC/F,EAAA,MAAM,aAAA,GAAgB,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAA;AACtD,EAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,KAAK,CAAA;AACxD,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,KAAA,CAAM,MAAA,EAAQ,KAAK,CAAA;AACrD,EAAA,MAAM,aAAa,aAAA,EAAc;AACjC,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAC7C,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,cAAA,GAAiB,EAAE,QAAA,EAAU,wBAAA,EAA0B,YAAY,qBAAA,EAAuB,IAAA,EAAM,SAAA,CAAU,IAAA,CAAK,IAAA,EAAK;AAE1H,EAAA,MAAM,QAAA,GAAW,WAAW,UAAA,GAAa,UAAA;AACzC,EAAA,MAAM,WAAA,GAAc,WAAW,UAAA,GAAa,UAAA;AAC5C,EAAA,MAAM,WAAA,GAAc,WAAA,GAAc,EAAE,KAAA,EAAO,WAAA,EAAa,QAAA,EAAU,cAAA,EAAyB,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,cAAA,EAAe,GAAI,MAAA;AACjI,EAAA,MAAM,GAAA,GAAM,KAAK,QAAA,GAAW,IAAA,CAAK,KAAK,QAAA,CAAS,EAAA,GAAK,GAAG,CAAA,GAAI,CAAA,GAAI,CAAA,CAAA;AAC/D,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,OAAO,CAAA;AACtC,EAAA,MAAM,WAAA,GAAc,CAAA,GAAI,GAAA,IAAO,MAAA,GAAS,CAAA,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,CAAC,QAAA,EAAU,WAAW,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,MAAA,IAAU,QAAA,IAAY,QAAA,GAAW,CAAA,GAAI,CAAA,CAAA;AAC5F,EAAA,MAAM,OAAO,QAAA,GACT;AAAA,IACE,KAAA,EAAO,MAAA;AAAA,IACP,KAAA,EAAO,OAAO,MAAA,GAAS,WAAA;AAAA,IACvB,KAAA,EAAO,YAAA,CAAa,MAAA,EAAQ,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC5C,MAAM,MAAA,GAAS,CAAA,KAAA,EAAQ,SAAS,CAAA,GAAA,EAAM,MAAM,CAAA,4CAAA,CAAA,GAAiD;AAAA,GAC/F,GACA,EAAE,KAAA,EAAO,OAAA,EAAiB;AAC9B,EAAA,MAAM,UAAA,GAAa,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAO,QAAA,CAAS,KAAA,GAAQ,WAAA,GAAc,GAAA,GAAO,MAAM,CAAC,CAAA,GAAI,MAAA;AAEvG,EAAA,MAAM,OAAA,GAAU,WAAW,EAAE,OAAA,EAAS,QAAO,GAAI,EAAE,SAAS,MAAA,EAAO;AACnE,EAAA,MAAM,QAAA,GAAW,QAAA,GAAW,EAAE,OAAA,EAAS,QAAA,GAAW,OAAA,GAAU,MAAA,EAAO,GAAI,EAAE,OAAA,EAAS,QAAA,GAAW,OAAA,GAAU,MAAA,EAAO;AAE9G,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACED,GAAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,SAAA,CAAU,GAAA,EAAyB,UAA8B,CAAA;AAAA,MACtE,MAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA,EAAM,WAAA;AAAA,MACN,YAAA,EAAc,IAAA;AAAA,MACd,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,YAAA,EAAc,WAAW,GAAA,GAAM,GAAA;AAAA,MAC/B,QAAA;AAAA,MACA,SAAA,EAAW,QAAA;AAAA,MACX,WAAA,EAAa,UAAA;AAAA,MACb,SAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MAEZ,QAAA,kBAAAA,IAACS,mBAAAA,EAAA,EAAoB,OAAM,MAAA,EAAO,MAAA,EAAO,QACvC,QAAA,kBAAAV,IAAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,IAAA;AAAA,UACA,MAAA,EAAQ,WAAW,UAAA,GAAa,YAAA;AAAA,UAChC,WAAA,EAAa,QAAA,CAAS,IAAA,EAAM,OAAO,IAAI,MAAA,GAAS,MAAA;AAAA,UAEhD,MAAA,EAAQ,EAAE,GAAA,EAAK,KAAA,EAAO,QAAA,IAAY,KAAA,GAAQ,CAAA,GAAI,MAAA,CAAO,SAAA,EAAW,MAAA,EAAQ,CAAA,EAAG,IAAA,EAAM,CAAA,EAAE;AAAA,UACnF,kBAAA,EAAkB,IAAA;AAAA,UAEjB,QAAA,EAAA;AAAA,YAAA,QAAA,oBAAYC,GAAAA,CAACW,aAAAA,EAAA,EAAc,eAAA,EAAgB,KAAA,EAAM,MAAA,EAAQ,UAAA,EAAY,QAAA,EAAU,CAAC,QAAA,EAAU,UAAA,EAAU,IAAA,EAAC,CAAA;AAAA,YACrG,QAAA,mBACCZ,IAAAA,CAAAQ,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,8BAAAP,IAACY,KAAAA,EAAA,EAAM,SAAQ,MAAA,EAAO,IAAA,EAAK,UAAU,GAAG,SAAA,CAAU,MAAM,QAAA,EAAU,KAAA,EAAO,UAAU,KAAA,EAAO,MAAA,EAAO,QAAO,KAAA,EAAO,WAAA,EAAa,eAAe,UAAA,EAAY,CAAA;AAAA,cACtJ,QAAA,oBAAYZ,GAAAA,CAACY,KAAAA,EAAA,EAAM,OAAA,EAAQ,OAAA,EAAQ,MAAK,QAAA,EAAS,WAAA,EAAY,OAAO,GAAG,SAAA,CAAU,MAAM,QAAA,EAAU,KAAA,EAAO,UAAU,KAAA,EAAO,MAAA,EAAO,MAAA,EAAO,aAAA,EAAe,cAAA,EAAgB,CAAA;AAAA,8BACvKZ,GAAAA;AAAA,gBAACa,KAAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,QAAA;AAAA,kBACT,IAAA,EAAK,UAAA;AAAA,kBACL,OAAO,MAAA,IAAU,MAAA;AAAA,kBAChB,GAAG,SAAA,CAAU,IAAA;AAAA,kBACd,QAAA,EAAU,KAAA;AAAA,kBACV,QAAA,EAAU,KAAA;AAAA,kBACV,QAAA,EAAU,CAAA;AAAA,kBACV,IAAA,EAAM;AAAA;AAAA;AACR,aAAA,EACF,CAAA,mBAEAd,IAAAA,CAAAQ,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,8BAAAP,GAAAA;AAAA,gBAACY,KAAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,QAAA;AAAA,kBACR,GAAG,SAAA,CAAU,IAAA;AAAA,kBACd,QAAA,EAAU,KAAA;AAAA,kBACV,QAAA,EAAU,KAAA;AAAA,kBACV,IAAA;AAAA,kBACA,UAAU,MAAA,CAAO,QAAA;AAAA,kBACjB,OAAO,MAAA,CAAO,KAAA;AAAA,kBACd,MAAA,EAAO,MAAA;AAAA,kBACP,KAAA,EAAO;AAAA;AAAA,eACT;AAAA,8BACAZ,GAAAA,CAACa,KAAAA,EAAA,EAAM,OAAA,EAAQ,QAAO,KAAA,EAAM,MAAA,EAAQ,GAAG,SAAA,CAAU,MAAM,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,eAAe,UAAA,EAAY,CAAA;AAAA,cACnH,4BACCb,GAAAA,CAACa,OAAA,EAAM,OAAA,EAAQ,SAAQ,WAAA,EAAY,OAAA,EAAQ,OAAM,MAAA,EAAQ,GAAG,UAAU,IAAA,EAAM,QAAA,EAAU,OAAO,QAAA,EAAU,KAAA,EAAO,eAAe,cAAA,EAAgB;AAAA,aAAA,EAEjJ,CAAA;AAAA,YAED,WAAA,oBAAeb,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,CAAA;AAAA,YAC1D,UAAA,oBAAcA,GAAAA,CAAC,WAAA,EAAA,EAAY,OAAO,CAAC,GAAG,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA,EAAG,GAAG,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,CAAC,CAAA,EAAG,CAAA;AAAA,YACnG,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAK,sBACdA,GAAAA;AAAA,cAACsB,GAAAA;AAAA,cAAA;AAAA,gBAEC,SAAS,GAAA,CAAI,OAAA;AAAA,gBACb,IAAA,EAAM,GAAA,CAAI,KAAA,IAAS,GAAA,CAAI,OAAA;AAAA,gBACvB,IAAA,EAAM,cAAc,CAAC,CAAA;AAAA,gBAGrB,MAAA,EAAQ,eAAe,CAAC,CAAA;AAAA,gBACxB,WAAA,EAAa,CAAA;AAAA,gBACb,OAAO,QAAA,CAAS,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,QAAQ,QAAQ,CAAA;AAAA,gBAClD,OAAA,EAAS,UAAA,CAAW,GAAA,EAAK,OAAO,CAAA;AAAA,gBAChC,UAAA;AAAA,gBACC,GAAG,OAAA;AAAA,gBACJ,iBAAA,EAAmB;AAAA,eAAA;AAAA,cAZd,GAAA,CAAI;AAAA,aAcZ,CAAA;AAAA,YACA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,sBAChBtB,GAAAA;AAAA,cAACuB,IAAAA;AAAA,cAAA;AAAA,gBAEC,IAAA,EAAK,UAAA;AAAA,gBACL,SAAS,IAAA,CAAK,OAAA;AAAA,gBACd,IAAA,EAAM,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,OAAA;AAAA,gBACzB,MAAA,EAAQ,WAAW,CAAC,CAAA;AAAA,gBACpB,WAAA,EAAa,CAAA;AAAA,gBACb,eAAA,EAAiB,IAAA,CAAK,MAAA,GAAS,KAAA,GAAQ,MAAA;AAAA,gBACvC,GAAA,EAAK,KAAA;AAAA,gBACJ,GAAG,QAAA;AAAA,gBACJ,iBAAA,EAAmB;AAAA,eAAA;AAAA,cATd,IAAA,CAAK;AAAA,aAWb;AAAA;AAAA;AAAA,OACH,EACF;AAAA;AAAA,GACF;AAEJ,CAAC,CAAC;AC/NK,IAAM,YAAA,GAAe,SAAA,CAAUpB,UAAAA,CAA8C,SAASqB,aAAAA,CAAa;AAAA,EACxG,IAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,QAAA,GAAW,IAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,UAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,UAAA,GAAanB,OAA8B,IAAI,CAAA;AAErD,EAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,EAAA,MAAM,CAAC,WAAA,EAAa,WAAA,EAAa,UAAU,CAAA,GAAIJ,QAAQ,MAAM;AAC3D,IAAA,MAAM,MAAA,GAAA,CAAU,QAAQ,EAAC,EAAG,QAAQ,CAAC,CAAA,KAAM,EAAE,MAAM,CAAA;AACnD,IAAA,MAAM,CAAA,GAAI,kBAAA,CAAmB,YAAA,EAAc,MAAM,CAAA;AACjD,IAAA,MAAM,CAAA,GAAI,kBAAA,CAAmB,WAAA,EAAa,MAAM,CAAA;AAChD,IAAA,OAAO;AAAA,MACL,iBAAA,CAAkB,OAAO,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,CAAC,CAAA,EAAG,YAAA,EAAc,MAAM,CAAA;AAAA,MAC9D,iBAAA,CAAkB,OAAO,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,CAAC,CAAA,EAAG,WAAA,EAAa,MAAM,CAAA;AAAA,MAC7D,CAAC,KAAA,EAAe,OAAA,KAAsB,OAAA,KAAY,MAAM,CAAA,CAAE,KAAK,CAAA,GAAI,OAAA,KAAY,MAAM,CAAA,CAAE,KAAK,CAAA,GAAI,KAAA,CAAM,eAAe,MAAM;AAAA,KAC7H;AAAA,EACF,GAAG,CAAC,IAAA,EAAM,WAAA,EAAa,YAAA,EAAc,MAAM,CAAC,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,eAAe,UAAA,EAAY,CAAC,CAAC,MAAA,IAAA,CAAW,IAAA,EAAM,MAAA,IAAU,CAAA,IAAK,CAAC,CAAA;AAC/E,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,KAAK,CAAA;AAChD,EAAA,MAAM,aAAa,aAAA,EAAc;AACjC,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAC7C,EAAA,MAAM,aAAA,GAAgB,UAAA,IAAc,IAAA,CAAK,MAAA,IAAU,CAAA;AACnD,EAAA,MAAM,cAAA,GAAiB,EAAE,QAAA,EAAU,wBAAA,EAA0B,YAAY,qBAAA,EAAuB,IAAA,EAAM,SAAA,CAAU,IAAA,CAAK,IAAA,EAAK;AAE1H,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACED,GAAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,SAAA,CAAU,GAAA,EAAyB,UAA8B,CAAA;AAAA,MACtE,MAAA;AAAA,MACA,IAAA,EAAM,EAAE,KAAA,EAAO,OAAA,EAAQ;AAAA,MACvB,KAAA,EAAM,SAAA;AAAA,MACN,SAAA,EAAW,MAAA;AAAA,MACX,WAAA,EAAa,UAAA;AAAA,MACb,SAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MAEZ,QAAA,kBAAAA,IAACS,mBAAAA,EAAA,EAAoB,OAAM,MAAA,EAAO,MAAA,EAAO,QACvC,QAAA,kBAAAV,IAAAA;AAAA,QAAC0B,cAAA;AAAA,QAAA;AAAA,UACC,MAAA,EAAQ,EAAE,GAAA,EAAK,CAAA,IAAK,SAAS,IAAA,CAAK,IAAA,CAAK,SAAS,EAAA,GAAK,GAAG,IAAI,CAAA,GAAI,CAAA,CAAA,EAAI,OAAO,CAAA,EAAG,MAAA,EAAQ,SAAS,EAAA,GAAK,CAAA,EAAG,MAAM,CAAA,EAAE;AAAA,UAC/G,kBAAA,EAAkB,IAAA;AAAA,UAEjB,QAAA,EAAA;AAAA,YAAA,QAAA,oBAAYzB,GAAAA,CAACW,aAAAA,EAAA,EAAc,eAAA,EAAgB,KAAA,EAAM,QAAQ,UAAA,EAAY,CAAA;AAAA,4BACtEX,GAAAA;AAAA,cAACY,KAAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,OAAA,EAAQ,GAAA;AAAA,gBACR,MAAM,MAAA,IAAU,GAAA;AAAA,gBACf,GAAG,SAAA,CAAU,IAAA;AAAA,gBACd,QAAA,EAAU,KAAA;AAAA,gBACV,QAAA,EAAU,KAAA;AAAA,gBACV,aAAA,EAAe,WAAA;AAAA,gBACf,OAAO,MAAA,GAAS,EAAE,KAAA,EAAO,MAAA,EAAQ,UAAU,QAAA,EAAU,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAO,EAAE,GAAG,cAAA,EAAgB,UAAA,EAAY,QAAA,IAAW,GAAI;AAAA;AAAA,aACzH;AAAA,4BACAZ,GAAAA;AAAA,cAACa,KAAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,OAAA,EAAQ,GAAA;AAAA,gBACR,MAAM,MAAA,IAAU,GAAA;AAAA,gBAChB,KAAA,EAAM,MAAA;AAAA,gBACL,GAAG,SAAA,CAAU,IAAA;AAAA,gBACd,QAAA,EAAU,KAAA;AAAA,gBACV,QAAA,EAAU,KAAA;AAAA,gBACV,aAAA,EAAe;AAAA;AAAA,aACjB;AAAA,4BACAb,GAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,OAAA,EAAQ,GAAA,EAAI,KAAA,EAAO,CAAC,EAAA,EAAI,GAAG,CAAA,EAAG,CAAA;AAAA,YAClD,WAAA,oBAAeA,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,CAAA;AAAA,YAC1D,aAAA,oBAAiBA,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,EAAG,IAAG,OAAA,EAAQ,CAAA;AAAA,YACzE,IAAA,CAAK,GAAA,CAAI,CAAC,MAAA,EAAQ,sBACjBA,GAAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBAEC,MAAM,MAAA,CAAO,IAAA;AAAA,gBACb,MAAM,MAAA,CAAO,MAAA;AAAA,gBACb,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,gBACd,iBAAA,EAAmB;AAAA,eAAA;AAAA,cAJd,MAAA,CAAO;AAAA,aAMf;AAAA;AAAA;AAAA,OACH,EACF;AAAA;AAAA,GACF;AAEJ,CAAC,CAAC;ACjGK,IAAM,UAAA,GAAa,SAAA,CAAUG,UAAAA,CAA4C,SAASuB,WAAAA,CAAW;AAAA,EAClG,IAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,MAAA,GAAS,IAAA;AAAA,EACT,QAAA,GAAW,IAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,UAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,QAAA;AAAA,EACd,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,WAAA,GAAc,cAAA,CAAe,QAAA,CAAS,MAAA,EAAQ,KAAK,CAAA;AACzD,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,QAAA,CAAS,MAAA,EAAQ,IAAI,CAAA;AACvD,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAC7C,EAAA,MAAM,aAAA,GAAgB,UAAA,IAAc,QAAA,CAAS,MAAA,IAAU,CAAA;AAEvD,EAAA,MAAM,SAASzB,OAAAA,CAAQ,MAAM,aAAa,IAAA,IAAQ,IAAI,QAAA,CAAS,GAAA,CAAI,CAAC,EAAA,KAAO,GAAG,GAAG,CAAC,GAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAErG,EAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,EAAA,MAAM,UAAA,GAAaA,OAAAA,CAAQ,MAAM,iBAAA,CAAkB,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAC,CAAA;AAC9G,EAAA,MAAM,UAAA,GAAaA,OAAAA,CAAQ,MAAM,kBAAA,CAAmB,WAAA,EAAa,MAAM,CAAA,EAAG,CAAC,WAAA,EAAa,MAAM,CAAC,CAAA;AAE/F,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACED,GAAAA,CAAC,YAAA,EAAA,EAAa,GAAA,EAAU,MAAA,EAAgB,MAAM,EAAE,KAAA,EAAO,QAAA,EAAS,EAAG,OAAM,OAAA,EAAQ,SAAA,EAAsB,YAAA,EAAY,SAAA,EAAW,aAAa,UAAA,EACzI,QAAA,kBAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,MAAA,EAAO,MAAA,EAAO,MAAA,EACvC,0BAAAV,IAAAA,CAAC4B,YAAA,EAAA,EAAmB,IAAA,EAAY,EAAA,EAAG,OAAM,EAAA,EAAG,KAAA,EAAM,WAAA,EAAY,KAAA,EAAM,oBAAkB,IAAA,EACpF,QAAA,EAAA;AAAA,oBAAA3B,GAAAA,CAAC,SAAA,EAAA,EAAU,MAAA,EAAO,yBAAA,EAA0B,CAAA;AAAA,oBAC5CA,GAAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,OAAA;AAAA,QACT,MAAM,EAAE,QAAA,EAAU,0BAA0B,UAAA,EAAY,qBAAA,EAAuB,MAAM,sBAAA;AAAuB;AAAA,KAC9G;AAAA,oBACAA,GAAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,MAAM,EAAE,QAAA,EAAU,0BAA0B,UAAA,EAAY,qBAAA,EAAuB,MAAM,sBAAA,EAAuB;AAAA,QAC5G,aAAA,EAAe,UAAA;AAAA,QACf,QAAA,EAAU;AAAA;AAAA,KACZ;AAAA,IACC,WAAA,oBAAeA,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,CAAA;AAAA,IAC1D,aAAA,oBAAiBA,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,QAAA,CAAS,GAAA,CAAI,CAAC,EAAA,KAAO,EAAA,CAAG,GAAG,CAAA,EAAG,CAAA;AAAA,IACnE,QAAA,CAAS,GAAA,CAAI,CAAC,EAAA,EAAI,sBACjBA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAM,EAAA,CAAG,KAAA,IAAS,EAAA,CAAG,GAAA;AAAA,QACrB,SAAS,EAAA,CAAG,GAAA;AAAA,QACZ,MAAA,EAAQ,YAAY,CAAC,CAAA;AAAA,QACrB,IAAA,EAAM,MAAA,GAAS,UAAA,CAAW,CAAC,CAAA,GAAI,aAAA;AAAA,QAC/B,WAAA,EAAa,CAAA;AAAA,QACb,GAAA,EAAK,WAAW,EAAE,CAAA,EAAG,GAAG,IAAA,EAAM,WAAA,CAAY,CAAC,CAAA,EAAE,GAAI,KAAA;AAAA,QACjD,iBAAA,EAAmB;AAAA,OAAA;AAAA,MAPd,EAAA,CAAG;AAAA,KASX;AAAA,GAAA,EACH,GACF,CAAA,EACF,CAAA;AAEJ,CAAC,CAAC;ACxEK,IAAM,cAAA,GAAiB,SAAA,CAAUG,UAAAA,CAAgD,SAASyB,eAAAA,CAAe;AAAA,EAC9G,IAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,WAAA,GAAc,IAAA;AAAA,EACd,UAAA,GAAa,IAAA;AAAA,EACb,UAAA,GAAa,KAAA;AAAA,EACb,UAAA,GAAa,EAAA;AAAA,EACb,QAAA,GAAW,IAAA;AAAA,EACX,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,KAAK,CAAA;AAChD,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAE7C,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAC,GAAG,CAAA,MAAO;AAAA,IACpC,GAAG,CAAA;AAAA,IACH,IAAA,EAAM,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAM;AAAA,GAChC,CAAE,CAAA;AAEF,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACE5B,IAAC,YAAA,EAAA,EAAa,GAAA,EAAU,QAAgB,IAAA,EAAM,EAAE,KAAA,EAAO,QAAA,EAAS,EAAG,KAAA,EAAM,cAAa,SAAA,EAAsB,YAAA,EAAY,SAAA,EACtH,QAAA,kBAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,MAAA,EAAO,MAAA,EAAO,MAAA,EACvC,QAAA,kBAAAV,IAAAA;AAAA,IAAC8B,gBAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,SAAA;AAAA,MACN,EAAA,EAAG,KAAA;AAAA,MACH,EAAA,EAAG,KAAA;AAAA,MACH,WAAA,EAAY,KAAA;AAAA,MACZ,WAAA,EAAY,KAAA;AAAA,MACZ,UAAA;AAAA,MACA,QAAA;AAAA,MACA,kBAAA,EAAkB,IAAA;AAAA,MAElB,QAAA,EAAA;AAAA,wBAAA7B,GAAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,OAAA;AAAA,YACR,UAAA,EAAY,EAAE,IAAA,EAAM,oBAAA,EAAqB;AAAA,YACzC,KAAA,EAAO,aAAa,EAAE,QAAA,EAAU,eAAe,IAAA,EAAM,wBAAA,EAA0B,QAAA,EAAU,wBAAA,EAAyB,GAAI,KAAA;AAAA,YACtH,iBAAA,EAAmB;AAAA;AAAA,SACrB;AAAA,QACC,WAAA,oBAAeA,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,CAAA;AAAA,QAC1D,UAAA,oBAAcA,GAAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,EAAG,IAAG,OAAA,EAAQ;AAAA;AAAA;AAAA,KAE3E,CAAA,EACF,CAAA;AAEJ,CAAC,CAAC;AC3DF,IAAM,UAAA,GAAa,GAAA;AAeZ,IAAM,WAAA,GAAc,SAAA,CAAUG,UAAAA,CAA6C,SAAS2B,YAAAA,CAAY;AAAA,EACrG,IAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,WAAA,GAAc,IAAA;AAAA,EACd,UAAA,GAAa,IAAA;AAAA,EACb,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,CAAK,MAAA,EAAQ,KAAK,CAAA;AAChD,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAE7C,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAC,GAAG,CAAA,MAAO;AAAA,IACpC,GAAG,CAAA;AAAA,IACH,IAAA,EAAM,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAM;AAAA,GAChC,CAAE,CAAA;AAEF,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACE9B,GAAAA,CAAC,YAAA,EAAA,EAAa,GAAA,EAAU,QAAgB,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,IAAA,CAAK,MAAA,GAAS,UAAA,EAAY,MAAM,MAAA,EAAO,EAAG,KAAA,EAAM,QAAA,EAAS,SAAA,EAAsB,YAAA,EAAY,SAAA,EAC/J,QAAA,kBAAAA,IAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,MAAA,EAAO,QAAO,MAAA,EACvC,QAAA,kBAAAV,IAAAA,CAACgC,aAAA,EAAA,EAAoB,oBAAkB,IAAA,EACrC,QAAA,EAAA;AAAA,oBAAA/B,GAAAA,CAAC,UAAO,OAAA,EAAQ,OAAA,EAAQ,MAAM,SAAA,EAAW,iBAAA,EAAmB,UAAA,EACzD,QAAA,EAAA,UAAA,oBACCA,GAAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,MAAA;AAAA,QACR,QAAA,EAAS,OAAA;AAAA,QACT,IAAA,EAAK,wBAAA;AAAA,QACL,QAAA,EAAS,wBAAA;AAAA,QACT,UAAA,EAAW;AAAA;AAAA,KACb,EAEJ,CAAA;AAAA,IACC,WAAA,oBAAeA,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI;AAAA,GAAA,EAC7D,GACF,CAAA,EACF,CAAA;AAEJ,CAAC,CAAC;;;ACqCK,SAAS,SAAS,MAAA,EAAuB;AAC9C,EAAA,OAAO,CAAA,MAAA,EAAS,MAAA,CAAO,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,OAAO,CAAC,CAAA,CAAA,CAAA;AACxE;AAGO,SAAS,WAAW,KAAA,EAA6B;AACtD,EAAA,MAAM,CAAA,GAAI,KAAA,CAAM,IAAA,EAAK,CAAE,MAAM,kFAAkF,CAAA;AAC/G,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,UAAA,CAAW,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,GAAA,GAAM,UAAA,CAAW,CAAA,CAAE,CAAC,CAAC,CAAA;AACzD,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,UAAA,CAAW,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,CAAA,EAAG,UAAA,CAAW,CAAA,CAAE,CAAC,CAAC,CAAA,EAAE;AACvD;AAEA,SAAS,iBAAA,CAAkB,EAAE,CAAA,EAAG,CAAA,EAAG,GAAE,EAAoC;AACvE,EAAA,MAAM,CAAA,GAAK,CAAA,GAAI,IAAA,CAAK,EAAA,GAAM,GAAA;AAC1B,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AACxB,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AACxB,EAAA,MAAM,EAAA,GAAK,CAAA,GAAI,YAAA,GAAe,CAAA,GAAI,YAAA,GAAe,CAAA;AACjD,EAAA,MAAM,EAAA,GAAK,CAAA,GAAI,YAAA,GAAe,CAAA,GAAI,YAAA,GAAe,CAAA;AACjD,EAAA,MAAM,EAAA,GAAK,CAAA,GAAI,YAAA,GAAe,CAAA,GAAI,WAAA,GAAe,CAAA;AACjD,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AACpB,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AACpB,EAAA,MAAM,CAAA,GAAI,KAAK,EAAA,GAAK,EAAA;AACpB,EAAA,OAAO;AAAA,IACL,YAAA,GAAgB,CAAA,GAAI,YAAA,GAAe,CAAA,GAAI,YAAA,GAAe,CAAA;AAAA,IACtD,aAAA,GAAgB,CAAA,GAAI,YAAA,GAAe,CAAA,GAAI,YAAA,GAAe,CAAA;AAAA,IACtD,aAAA,GAAgB,CAAA,GAAI,YAAA,GAAe,CAAA,GAAI,WAAA,GAAe;AAAA,GACxD;AACF;AAwBA,SAAS,yBAAyB,MAAA,EAAyC;AACzE,EAAA,OAAO,iBAAA,CAAkB,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAC,CAAA;AACzE;AAEA,IAAM,WAAA,GAAc,CAAC,CAAA,KAAe,CAAA,IAAK,QAAA,GAAY,KAAA,GAAQ,CAAA,GAAI,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAA,GAAI,GAAG,CAAA,GAAI,KAAA;AAChG,IAAM,WAAA,GAAc,CAAC,CAAA,KAAe,CAAA,IAAK,OAAA,GAAU,CAAA,GAAI,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAA,CAAK,CAAA,GAAI,KAAA,IAAS,KAAA,EAAO,GAAG,CAAA;AAGhG,SAAS,YAAY,MAAA,EAAyC;AAC5D,EAAA,OAAO,wBAAA,CAAyB,MAAM,CAAA,CAAE,GAAA,CAAI,WAAW,CAAA;AACzD;AAeO,IAAM,eAAA,GAAkB,IAAA;AAM/B,SAAS,mBAAmB,OAAA,EAA4C;AACtE,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACxB,IAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAA,GAAI,GAAA;AACxC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AAC1B,IAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,KAAA,GAAQ,GAAG,CAAA,IAAK,eAAA,GAAkB,CAAC,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,KAAA,GAAQ,CAAC,CAAC,CAAA,GAAI,CAAC,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AAC/H,IAAA,MAAM,SAAS,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM,EAAE,CAAC,CAAA;AACzC,IAAA,EAAA,IAAM,MAAA,GAAS,WAAA,CAAY,CAAA,GAAI,GAAG,CAAA;AAClC,IAAA,EAAA,IAAM,MAAA,GAAS,WAAA,CAAY,CAAA,GAAI,GAAG,CAAA;AAAA,EACpC,CAAC,CAAA;AACD,EAAA,OAAO,CAAC,IAAI,EAAE,CAAA;AAChB;AAGO,SAAS,eAAe,MAAA,EAA+B;AAC5D,EAAA,OAAO,kBAAA,CAAmB,WAAA,CAAY,MAAM,CAAC,CAAA;AAC/C;AAGO,SAAS,eAAA,CAAgB,CAAC,EAAA,EAAI,EAAE,GAAmB,CAAC,EAAA,EAAI,EAAE,CAAA,EAA2B;AAC1F,EAAA,IAAI,EAAA,IAAM,EAAA,IAAM,EAAA,IAAM,EAAA,EAAI,OAAO,CAAA;AACjC,EAAA,OAAO,EAAA,GAAK,KAAK,aAAA,CAAc,EAAA,EAAI,EAAE,CAAA,GAAI,aAAA,CAAc,IAAI,EAAE,CAAA;AAC/D;AAGO,SAAS,aAAA,CAAc,MAAc,IAAA,EAAsB;AAChE,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,IAAI,CAAA;AACnC,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,IAAI,CAAA;AAClC,EAAA,OAAA,CAAQ,OAAA,GAAU,SAAS,MAAA,GAAS,IAAA,CAAA;AACtC;AAmCO,IAAM,YAAA,GAAe,GAAA;AAGrB,IAAM,aAAA,GAAgB,cAAA;AAEtB,IAAM,YAAA,GAAe,uBAAA;AAMrB,IAAM,sBAA6B,EAAE,CAAA,EAAG,MAAM,CAAA,EAAG,IAAA,EAAO,GAAG,CAAA,EAAE;AAG7D,IAAM,mBAAA,GAAsB,GAAA;AAE5B,IAAM,mBAAA,GAAsB,CAAA;AACnC,IAAM,UAAA,GAAa,IAAA;AACnB,IAAM,UAAA,GAAa,GAAA;AACnB,IAAM,WAAA,GAAc,IAAA;AAEpB,IAAM,WAAA,GAA8B,CAAC,CAAA,EAAG,CAAC,CAAA;AACzC,IAAM,UAAA,GAAa,eAAe,mBAAmB,CAAA;AAGrD,SAAS,WAAA,CAAY,MAAsB,KAAA,EAAwB;AACjE,EAAA,IAAI,GAAA,GAAM,QAAA;AACV,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,EAAO,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,eAAA,CAAgB,IAAA,EAAM,cAAA,CAAe,CAAC,CAAC,CAAC,CAAA;AACnF,EAAA,OAAO,GAAA;AACT;AAwBO,SAAS,cAAA,CAAe,SAAgB,SAAA,EAAkC;AAC/E,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,EAAM,GAAG,SAAS,CAAA;AACjC,EAAA,MAAM,IAAI,IAAA,CAAK,CAAA;AACf,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,mBAAA,EAAqB,KAAK,CAAC,CAAA;AACnD,EAAA,KAAA,MAAW,MAAA,IAAU,CAAC,mBAAA,EAAqB,YAAY,CAAA,EAAG;AACxD,IAAA,KAAA,MAAW,KAAK,CAAC,MAAA,EAAQ,SAAS,CAAA,EAAG,MAAA,GAAS,CAAC,CAAA,EAAG;AAChD,MAAA,KAAA,IAAS,IAAI,UAAA,EAAY,CAAA,IAAK,UAAA,GAAa,IAAA,EAAM,KAAK,WAAA,EAAa;AACjE,QAAA,MAAM,SAAA,GAAY,EAAE,CAAA,EAAG,CAAC,EAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAG,CAAA,EAAE;AAC1D,QAAA,IAAI,YAAY,cAAA,CAAe,SAAS,GAAG,KAAK,CAAA,IAAK,QAAQ,OAAO,SAAA;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAYO,SAAS,eAAA,CAAgB,SAAgB,SAAA,EAA4B;AAC1E,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,EAAM,GAAG,SAAS,CAAA;AACjC,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,WAAA,EAAa,KAAK,CAAA;AAC/C,EAAA,IAAI,QAAA,IAAY,cAAc,OAAO,aAAA;AACrC,EAAA,MAAM,IAAA,GAAO,cAAA,CAAe,IAAA,EAAM,GAAG,SAAS,CAAA;AAC9C,EAAA,IAAI,IAAA,EAAM,OAAO,QAAA,CAAS,IAAI,CAAA;AAC9B,EAAA,OAAO,WAAA,CAAY,UAAA,EAAY,KAAK,CAAA,IAAK,WAAW,YAAA,GAAe,aAAA;AACrE;ACnSA,IAAM,WAAA,GAAc,CAAA;AAMb,SAAS,iBAAA,CAAkB,KAAA,EAAe,MAAA,EAAgB,OAAA,EAA+B;AAC9F,EAAA,IAAI,QAAQ,CAAA,GAAI,WAAA,GAAc,OAAA,CAAQ,QAAA,GAAW,GAAG,OAAO,CAAA;AAC3D,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAA,CAAO,SAAS,CAAA,GAAI,WAAA,IAAe,OAAA,CAAQ,UAAU,CAAC,CAAA;AAChF;AAGA,IAAM,cAAA,uBAAqB,GAAA,EAAoB;AAC/C,SAAS,cAAc,GAAA,EAAqB;AAC1C,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,GAAA;AAC5C,EAAA,IAAI,KAAA,GAAQ,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA;AAClC,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA;AAC3C,IAAA,KAAA,CAAM,MAAM,KAAA,GAAQ,GAAA;AACpB,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AAC/B,IAAA,KAAA,GAAQ,gBAAA,CAAiB,KAAK,CAAA,CAAE,KAAA;AAChC,IAAA,KAAA,CAAM,MAAA,EAAO;AACb,IAAA,cAAA,CAAe,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,KAAA;AACT;AAQA,SAAS,aAAa,IAAA,EAAsB;AAC1C,EAAA,MAAM,SAAS,UAAA,CAAW,IAAI,KAAK,UAAA,CAAW,aAAA,CAAc,IAAI,CAAC,CAAA;AACjE,EAAA,OAAO,SAAS,eAAA,CAAgB,MAAM,IAAI,aAAA,CAAc,aAAA,CAAc,IAAI,CAAC,CAAA;AAC7E;AAGA,SAAS,cAAc,KAAA,EAAuB;AAC5C,EAAA,MAAM,GAAA,GAAM,wCAAA,CAAyC,IAAA,CAAK,KAAK,CAAA;AAC/D,EAAA,MAAM,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAC/B,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,MAAM,CAAC,MAAA,CAAO,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,OAAO,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,MAAA,CAAO,GAAA,CAAI,CAAC,CAAC,CAAC,CAAA,GAAI,CAAA,CAAE,MAAA,IAAU,CAAA,GAAI,CAAC,SAAS,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA,EAAG,EAAE,CAAA,EAAG,QAAA,CAAS,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA,EAAG,EAAE,GAAG,QAAA,CAAS,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,GAAI,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AACzM,EAAA,MAAM,aAAa,KAAA,GAAQ,CAAA,GAAI,KAAA,GAAQ,CAAA,GAAI,QAAQ,CAAA,IAAK,GAAA;AACxD,EAAA,OAAO,SAAA,GAAY,OAAO,SAAA,GAAY,SAAA;AACxC;AAEA,SAAS,eAAe,EAAE,CAAA,GAAI,GAAG,CAAA,GAAI,CAAA,EAAG,QAAQ,CAAA,EAAG,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAG,MAAM,KAAA,EAAO,MAAA,EAAQ,QAAQ,KAAA,GAAQ,CAAA,EAAG,SAAQ,EAAwB;AACxI,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,KAAA,GAAQ,MAAA,CAAO,MAAM,CAAA;AAKzC,EAAA,MAAM,QAAQ,OAAA,IAAW,IAAA,GAAO,kBAAkB,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,GAAI,CAAA;AACvE,EAAA,MAAM,UAAA,GAAa,aAAa,IAAI,CAAA;AAEpC,EAAA,uBACED,KAAC,GAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAC,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,CAAA;AAAA,QACA,CAAA;AAAA,QACA,KAAA;AAAA,QACA,MAAA,EAAQ,CAAA;AAAA,QACR,IAAA;AAAA,QACA,MAAA,EAAO,sBAAA;AAAA,QACP,WAAA,EAAa,CAAA;AAAA,QACb,EAAA,EAAI,KAAA,KAAU,CAAA,GAAI,MAAA,GAAS,CAAA;AAAA,QAC3B,OAAO,EAAE,OAAA,EAAS,KAAA,KAAU,CAAA,GAAI,IAAI,IAAA;AAAK;AAAA,KAC3C;AAAA,IACC,KAAA,GAAQ,CAAA,oBACPA,GAAAA,CAAC,eAAA,EAAA,EAAc,GAAM,CAAA,EAAM,KAAA,EAAc,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAO,EAAE,eAAe,MAAA,EAAO,EACjF,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4EAAA,EAA6E,KAAA,EAAO,EAAE,OAAA,EAAS,WAAA,EAAY,EACxH,QAAA,kBAAAA,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,oBAAA,EAAmB,EAAA;AAAA,QACnB,SAAA,EAAW,UAAA;AAAA,QACX,KAAA,EAAO,EAAE,KAAA,EAAO,UAAA,EAAY,SAAS,aAAA,EAAe,eAAA,EAAiB,UAAA,EAAY,eAAA,EAAiB,OAAO,QAAA,EAAU,QAAA,EAAU,YAAA,EAAc,UAAA,EAAY,SAAS,MAAA,EAAO;AAAA,QAEtK,QAAA,EAAA;AAAA;AAAA,OAEL,CAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAEA,SAAS,eAAe,KAAA,EAAsB,MAAA,EAAkB,UAAU,EAAE,CAAA,EAAG,GAAE,EAAkB;AACjG,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACzB,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,QAAA,EAAU,eAAe,IAAA,CAAK,QAAA,EAAU,MAAA,EAAQ,OAAO,CAAA,EAAE;AAAA,IAC7E;AACA,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,CAAA,GAAI,OAAO,MAAM,CAAA;AAC7C,IAAA,OAAA,CAAQ,CAAA,EAAA;AACR,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAK;AAAA,EACzB,CAAC,CAAA;AACH;AAGA,IAAM,UAAA,GAAa,8DAAA;AAGnB,SAAS,eAAA,GAAkF;AACzF,EAAA,MAAM,KAAA,GAAQK,OAA+B,IAAI,CAAA;AACjD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIT,SAA8B,IAAI,CAAA;AAIhE,EAAAC,gBAAgB,MAAM;AACpB,IAAA,MAAM,KAAK,KAAA,CAAM,OAAA;AACjB,IAAA,IAAI,CAAC,EAAA,EAAI;AACT,IAAA,MAAM,EAAA,GAAK,iBAAiB,EAAE,CAAA;AAC9B,IAAA,MAAM,QAAA,GAAW,UAAA,CAAW,EAAA,CAAG,QAAQ,CAAA;AACvC,IAAA,MAAM,aAAa,UAAA,CAAW,EAAA,CAAG,UAAU,CAAA,IAAK,EAAA,CAAG,uBAAsB,CAAE,MAAA;AAC3E,IAAA,IAAI,EAAE,QAAA,GAAW,CAAA,CAAA,IAAM,EAAE,aAAa,CAAA,CAAA,EAAI;AAC1C,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAAY,OAAA,CAAQ,UAAA,KAAe,UAAA,EAAY,UAAA,CAAW,EAAE,QAAA,EAAU,UAAA,EAAY,CAAA;AAAA,EACzH,CAAC,CAAA;AACD,EAAA,OAAO,CAAC,OAAO,OAAO,CAAA;AACxB;AAEO,IAAM,YAAA,GAAe,SAAA,CAAUM,UAAAA,CAA8C,SAAS6B,aAAAA,CAAa;AAAA,EACxG,IAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,WAAA,GAAc,IAAA;AAAA,EACd,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,CAAA,EAAG,KAAK,CAAA;AACtC,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAC7C,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,CAAC,KAAA,EAAO,OAAO,CAAA,GAAI,eAAA,EAAgB;AAEzC,EAAA,MAAM,SAAA,GAAY,cAAA,CAAe,IAAA,EAAM,MAAM,CAAA;AAE7C,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,uBACEjC,IAAAA,CAAC,YAAA,EAAA,EAAa,GAAA,EAAU,QAAgB,IAAA,EAAM,EAAE,KAAA,EAAO,OAAA,EAAQ,EAAG,KAAA,EAAM,SAAA,EAAU,SAAA,EAAsB,cAAY,SAAA,EAClH,QAAA,EAAA;AAAA,oBAAAC,IAACS,mBAAAA,EAAA,EAAoB,OAAM,MAAA,EAAO,MAAA,EAAO,QACvC,QAAA,kBAAAT,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,SAAA;AAAA,QACN,OAAA,EAAQ,OAAA;AAAA,QACR,OAAA,EAAQ,MAAA;AAAA,QACR,aAAa,CAAA,GAAI,CAAA;AAAA,QACjB,MAAA,EAAO,sBAAA;AAAA,QACP,iBAAA,EAAmB,UAAA;AAAA,QACnB,yBAASA,GAAAA,CAAC,cAAA,EAAA,EAAe,MAAA,EAAgB,QAAgB,OAAA,EAAkB,CAAA;AAAA,QAE1E,QAAA,EAAA,WAAA,oBAAeA,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI;AAAA;AAAA,KAC7D,EACF,CAAA;AAAA,oBACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,KAAK,KAAA,EAAO,aAAA,EAAW,MAAC,SAAA,EAAW,UAAA,EAAY,KAAA,EAAO,EAAE,UAAU,UAAA,EAAY,UAAA,EAAY,UAAU,aAAA,EAAe,MAAA,IAAU,QAAA,EAAA,GAAA,EAAC;AAAA,GAAA,EACtI,CAAA;AAEJ,CAAC,CAAC;AChLK,IAAM,WAAA,GAAc,SAAA,CAAUG,UAAAA,CAA6C,SAAS8B,YAAAA,CAAY;AAAA,EACrG,IAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,WAAA,GAAc,IAAA;AAAA,EACd,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,CAAK,KAAA,CAAM,QAAQ,KAAK,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,iBAAiB,oBAAoB,CAAA;AAExD,EAAA,MAAM,iBAAiB,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,CAAA,MAAO;AAAA,IAClD,GAAG,IAAA;AAAA,IACH,IAAA,EAAM,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAM;AAAA,GAChC,CAAE,CAAA;AAEF,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,KAAA,EAAO,cAAA;AAAA,IACP,OAAO,IAAA,CAAK;AAAA,GACd;AAEA,EAAA,IAAI,CAAC,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,OAAO,IAAA;AAEjC,EAAA,uBACEjC,IAAC,YAAA,EAAA,EAAa,GAAA,EAAU,QAAgB,IAAA,EAAM,EAAE,KAAA,EAAO,OAAA,EAAQ,EAAG,KAAA,EAAM,UAAS,SAAA,EAAsB,YAAA,EAAY,SAAA,EACjH,QAAA,kBAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,MAAA,EAAO,MAAA,EAAO,MAAA,EACvC,QAAA,kBAAAT,GAAAA;AAAA,IAACkC,MAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,UAAA;AAAA,MACN,SAAA,EAAW,EAAA;AAAA,MACX,WAAA,EAAa,EAAA;AAAA,MACb,MAAA,EAAQ,EAAE,GAAA,EAAK,CAAA,EAAG,OAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,IAAA,EAAM,CAAA,EAAE;AAAA,MAC/C,IAAA,EAAM,EAAE,MAAA,EAAQ,UAAA,EAAY,eAAe,GAAA,EAAI;AAAA,MAE9C,QAAA,EAAA,WAAA,oBAAelC,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI;AAAA;AAAA,KAE/D,CAAA,EACF,CAAA;AAEJ,CAAC,CAAC;AC9BK,IAAM,SAAA,GAAYG,UAAAA,CAA2C,SAASgC,UAAAA,CAAU;AAAA,EACrF,IAAA;AAAA,EACA,OAAA,GAAU,MAAA;AAAA,EACV,KAAA,GAAQ,CAAA;AAAA,EACR,MAAA,GAAS,EAAA;AAAA,EACT,KAAA,GAAQ,MAAA;AAAA,EACR,WAAA,GAAc,KAAA;AAAA,EACd,MAAA,GAAS,IAAA;AAAA,EACT,QAAA;AAAA,EACA,YAAA,EAAc,SAAA;AAAA,EACd;AACF,CAAA,EAAG,GAAA,EAAK;AACN,EAAA,MAAM,aAAaC,KAAAA,EAAM;AACzB,EAAA,MAAM,UAAA,GAAa,kBAAkB,QAAQ,CAAA;AAC7C,EAAA,MAAM,kBAAkB,uBAAA,EAAwB;AAEhD,EAAA,MAAM,SAAA,GAAY,cAAc,KAAK,CAAA,CAAA;AACrC,EAAA,MAAM,aAAA,GAAgB,cAAc,KAAK,CAAA,KAAA,CAAA;AACzC,EAAA,MAAM,UAAA,GAAa,iBAAiB,SAAS,CAAA;AAC7C,EAAA,MAAM,SAAA,GAAY,iBAAiB,aAAa,CAAA;AAChD,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAC,KAAA,EAAO,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,CAAA,EAAE,CAAE,CAAA;AAE9D,EAAA,MAAM,cAAA,GAAiB,kBACnB,EAAE,KAAA,EAAO,QAAQ,MAAA,EAAQ,MAAA,KACzB,EAAE,KAAA,EAAO,OAAO,KAAA,KAAU,QAAA,GAAW,GAAG,KAAK,CAAA,EAAA,CAAA,GAAO,OAAO,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,EAAA,CAAA,EAAK;AAErF,EAAA,IAAI,CAAC,IAAA,EAAM,MAAA,EAAQ,OAAO,IAAA;AAE1B,EAAA,IAAI,YAAY,KAAA,EAAO;AACrB,IAAA,uBACEpC,GAAAA,CAAC,KAAA,EAAA,EAAI,KAAU,KAAA,EAAO,cAAA,EAAgB,WAAuB,GAAI,SAAA,GAAY,EAAE,IAAA,EAAM,OAAO,YAAA,EAAc,SAAA,KAAc,EAAC,EACvH,0BAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,QAAO,MAAA,EAAO,MAAA,EACvC,0BAAAV,IAAAA,CAACK,UAAAA,EAAA,EAAS,IAAA,EAAM,SAAA,EAAW,QAAQ,EAAE,GAAA,EAAK,GAAG,KAAA,EAAO,CAAA,EAAG,QAAQ,CAAA,EAAG,IAAA,EAAM,GAAE,EACxE,QAAA,EAAA;AAAA,sBAAAJ,IAACY,KAAAA,EAAA,EAAM,OAAA,EAAQ,OAAA,EAAQ,MAAI,IAAA,EAAC,CAAA;AAAA,sBAC5BZ,GAAAA,CAACa,KAAAA,EAAA,EAAM,MAAI,IAAA,EAAC,CAAA;AAAA,MACX,WAAA,oBAAeb,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,MAAA,EAAQ,KAAA,EAAO,CAAA;AAAA,sBAC1EA,GAAAA;AAAA,QAACsB,GAAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAQ,OAAA;AAAA,UACR,IAAA,EAAM,UAAA;AAAA,UACN,MAAA,EAAQ,CAAC,CAAA,EAAG,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,UACnB,iBAAA,EAAmB;AAAA;AAAA;AACrB,KAAA,EACF,GACF,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,MAAM,UAAA,GAAa,CAAA,mBAAA,EAAsB,UAAU,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA;AAC5D,IAAA,uBACEtB,GAAAA,CAAC,KAAA,EAAA,EAAI,KAAU,KAAA,EAAO,cAAA,EAAgB,WAAuB,GAAI,SAAA,GAAY,EAAE,IAAA,EAAM,OAAO,YAAA,EAAc,SAAA,KAAc,EAAC,EACvH,0BAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,QAAO,MAAA,EAAO,MAAA,EACvC,0BAAAV,IAAAA,CAACgB,WAAAA,EAAA,EAAU,IAAA,EAAM,SAAA,EAAW,QAAQ,EAAE,GAAA,EAAK,GAAG,KAAA,EAAO,CAAA,EAAG,QAAQ,CAAA,EAAG,IAAA,EAAM,GAAE,EACzE,QAAA,EAAA;AAAA,sBAAAf,GAAAA,CAAC,MAAA,EAAA,EACC,QAAA,kBAAAD,IAAAA,CAAC,oBAAe,EAAA,EAAI,UAAA,EAAY,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EACtD,QAAA,EAAA;AAAA,wBAAAC,IAAC,MAAA,EAAA,EAAK,MAAA,EAAO,MAAK,SAAA,EAAW,SAAA,EAAW,aAAa,CAAA,EAAG,CAAA;AAAA,wBACxDA,IAAC,MAAA,EAAA,EAAK,MAAA,EAAO,OAAM,SAAA,EAAW,SAAA,EAAW,aAAa,GAAA,EAAK;AAAA,OAAA,EAC7D,CAAA,EACF,CAAA;AAAA,sBACAA,GAAAA,CAACY,KAAAA,EAAA,EAAM,OAAA,EAAQ,OAAA,EAAQ,MAAI,IAAA,EAAC,CAAA;AAAA,sBAC5BZ,GAAAA,CAACa,KAAAA,EAAA,EAAM,IAAA,EAAI,MAAC,MAAA,EAAQ,CAAC,aAAA,EAAe,aAAa,CAAA,EAAG,CAAA;AAAA,MACnD,WAAA,oBAAeb,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,MAAA,EAAQ,KAAA,EAAO,CAAA;AAAA,sBAC1EA,GAAAA;AAAA,QAACqC,IAAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAM,SAAS,UAAA,GAAa,QAAA;AAAA,UAC5B,OAAA,EAAQ,OAAA;AAAA,UACR,MAAA,EAAQ,UAAA;AAAA,UACR,WAAA,EAAa,GAAA;AAAA,UACb,IAAA,EAAM,QAAQ,UAAU,CAAA,CAAA,CAAA;AAAA,UACxB,GAAA,EAAK,KAAA;AAAA,UACL,WAAW,WAAA,GAAc,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,YAAW,GAAI,KAAA;AAAA,UACtD,iBAAA,EAAmB;AAAA;AAAA;AACrB,KAAA,EACF,GACF,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACErC,GAAAA,CAAC,KAAA,EAAA,EAAI,KAAU,KAAA,EAAO,cAAA,EAAgB,WAAuB,GAAI,SAAA,GAAY,EAAE,IAAA,EAAM,OAAO,YAAA,EAAc,SAAA,KAAc,EAAC,EACvH,0BAAAA,GAAAA,CAACS,mBAAAA,EAAA,EAAoB,KAAA,EAAM,QAAO,MAAA,EAAO,MAAA,EACvC,0BAAAV,IAAAA,CAACS,WAAAA,EAAA,EAAU,IAAA,EAAM,SAAA,EAAW,QAAQ,EAAE,GAAA,EAAK,GAAG,KAAA,EAAO,CAAA,EAAG,QAAQ,CAAA,EAAG,IAAA,EAAM,GAAE,EACzE,QAAA,EAAA;AAAA,oBAAAR,IAACY,KAAAA,EAAA,EAAM,OAAA,EAAQ,OAAA,EAAQ,MAAI,IAAA,EAAC,CAAA;AAAA,oBAC5BZ,GAAAA,CAACa,KAAAA,EAAA,EAAM,IAAA,EAAI,MAAC,MAAA,EAAQ,CAAC,aAAA,EAAe,aAAa,CAAA,EAAG,CAAA;AAAA,IACnD,WAAA,oBAAeb,GAAAA,CAACc,OAAAA,EAAA,EAAQ,OAAA,kBAASd,GAAAA,CAAC,mBAAA,EAAA,EAAoB,CAAA,EAAI,MAAA,EAAQ,KAAA,EAAO,CAAA;AAAA,oBAC1EA,GAAAA;AAAA,MAACuB,IAAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,SAAS,UAAA,GAAa,QAAA;AAAA,QAC5B,OAAA,EAAQ,OAAA;AAAA,QACR,MAAA,EAAQ,UAAA;AAAA,QACR,WAAA,EAAa,GAAA;AAAA,QACb,GAAA,EAAK,KAAA;AAAA,QACL,WAAW,WAAA,GAAc,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,YAAW,GAAI,KAAA;AAAA,QACtD,iBAAA,EAAmB;AAAA;AAAA;AACrB,GAAA,EACF,GACF,CAAA,EACF,CAAA;AAEJ,CAAC;ACvHM,IAAM,mBAAA,GAAsB,UAAA;AAoB5B,SAAS,cAAA,CAAe;AAAA,EAC7B,MAAA,GAAS,MAAA;AAAA,EACT,KAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,UAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,QAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,UAAUa,KAAAA,EAAM;AACtB,EAAA,MAAM,KAAA,GAAQ,iBAAiB,MAAM,CAAA;AAGrC,EAAA,MAAM,cAAc,CAAC,OAAA,IAAW,CAAC,CAAC,QAAA,IAAY,eAAe,QAAQ,CAAA;AACrE,EAAA,MAAM,IAAA,GAAO,SAAS,aAAA,CAAc,EAAA;AACpC,EAAA,MAAM,OAAA,GAAUnC,OAAAA;AAAA,IACd,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,QAAQ,OAAA,GAAU,MAAA,EAAW,QAAA,EAAU,CAAC,WAAA,EAAY,CAAA;AAAA,IACrF,CAAC,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,WAAW;AAAA,GACrC;AAEA,EAAA,IAAI,IAAA,GAAkB,IAAA;AACtB,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,IAAA,mBACEF,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6DAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACZ,QAAA,EAAA,CAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAE,EAAE,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACpCA,GAAAA,CAAC,QAAA,EAAA,EAAiB,OAAA,EAAQ,QAAA,EAAS,SAAA,EAAU,QAAA,EAAS,MAAA,EAAQ,CAAA,EAAG,CAAC,CAAA,CAAA,CAAA,EAAA,EAAnD,CAAwD,CACxE,CAAA,EACH,CAAA;AAAA,sBACAA,IAAC,QAAA,EAAA,EAAS,OAAA,EAAQ,QAAO,KAAA,EAAO,CAAA,EAAG,WAAU,QAAA,EAAS;AAAA,KAAA,EACxD,CAAA;AAAA,EAEJ,WAAW,QAAA,EAAU;AACnB,IAAA,IAAA,mBACEA,GAAAA,CAAC,qBAAA,CAAsB,UAAtB,EAA+B,KAAA,EAAO,SACpC,QAAA,EAAA,WAAA,GAAc,QAAA;AAAA;AAAA,sBAEbA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EAAiB,QAAA,EAAS,CAAA,EAC3C;AAAA,KAAA,EAEJ,CAAA;AAAA,EAEJ,WAAW,UAAA,EAAY;AACrB,IAAA,IAAA,mBAAOA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2CAA2C,QAAA,EAAA,UAAA,EAAW,CAAA;AAAA,EAC9E;AAEA,EAAA,uBACED,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,EAAA;AAAA,MACV,SAAA,EAAQ,OAAA;AAAA,MACR,SAAA,EAAW,EAAA;AAAA,QACT,eAAA;AAAA,QACA,OAAA,KAAY,UACR,gBAAA,GACA,EAAA;AAAA;AAAA,UAEE,+CAAA;AAAA,UACA,mGAAA;AAAA,UACA;AAAA,SACF;AAAA,QACJ;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,KAAA,oBACCC,GAAAA,CAAC,IAAA,EAAA,EAAG,EAAA,EAAI,OAAA,EAAS,WAAW,EAAA,CAAG,mBAAA,EAAqB,SAAS,CAAA,EAC1D,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,wBAEFA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,iBAAA,EAAgB,EAAA;AAAA,YAChB,SAAA,EAAU,gCAAA;AAAA,YACV,OAAO,EAAE,IAAA,EAAM,UAAU,SAAA,EAAW,WAAA,GAAc,SAAY,IAAA,EAAK;AAAA,YAElE,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,GACF;AAEJ","file":"charts.js","sourcesContent":["import { useState, useLayoutEffect, useSyncExternalStore } from \"react\";\n\nconst CHART_TOKENS = [\n \"--ds-chart-1\",\n \"--ds-chart-2\",\n \"--ds-chart-3\",\n \"--ds-chart-4\",\n \"--ds-chart-5\",\n \"--ds-chart-6\",\n] as const;\n\nconst CHART_TOKENS_SOFT = [\n \"--ds-chart-1-soft\",\n \"--ds-chart-2-soft\",\n \"--ds-chart-3-soft\",\n \"--ds-chart-4-soft\",\n \"--ds-chart-5-soft\",\n \"--ds-chart-6-soft\",\n] as const;\n\nconst FALLBACK_COLORS: Record<string, string> = {\n \"--ds-chart-1\": \"#6366f1\",\n \"--ds-chart-2\": \"#d97706\",\n \"--ds-chart-3\": \"#059669\",\n \"--ds-chart-4\": \"#dc2626\",\n \"--ds-chart-5\": \"#0891b2\",\n \"--ds-chart-6\": \"#7c3aed\",\n \"--ds-chart-1-soft\": \"rgba(99, 102, 241, 0.3)\",\n \"--ds-chart-2-soft\": \"rgba(217, 119, 6, 0.3)\",\n \"--ds-chart-3-soft\": \"rgba(5, 150, 105, 0.3)\",\n \"--ds-chart-4-soft\": \"rgba(220, 38, 38, 0.3)\",\n \"--ds-chart-5-soft\": \"rgba(8, 145, 178, 0.3)\",\n \"--ds-chart-6-soft\": \"rgba(124, 58, 237, 0.3)\",\n \"--ds-bg-surface\": \"#ffffff\",\n \"--ds-border-subtle\": \"#e5e7eb\",\n \"--ds-text-primary\": \"#111827\",\n \"--ds-text-secondary\": \"#6b7280\",\n \"--ds-text-muted\": \"#9ca3af\",\n};\n\ntype Subscriber = () => void;\n\nlet modeVersion = 0;\nconst subscribers = new Set<Subscriber>();\nlet observerAttached = false;\n\nfunction attachObserver() {\n if (observerAttached || typeof document === \"undefined\") return;\n observerAttached = true;\n\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n if (m.attributeName === \"data-mode\") {\n modeVersion++;\n for (const sub of subscribers) sub();\n break;\n }\n }\n });\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-mode\"],\n });\n}\n\nfunction subscribe(cb: Subscriber) {\n attachObserver();\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n}\n\nfunction getSnapshot() {\n return modeVersion;\n}\n\nfunction getServerSnapshot() {\n return 0;\n}\n\nexport function resolveToken(token: string): string {\n if (typeof document === \"undefined\") return FALLBACK_COLORS[token] ?? \"#6366f1\";\n const val = getComputedStyle(document.documentElement).getPropertyValue(token).trim();\n return val || FALLBACK_COLORS[token] || \"#6366f1\";\n}\n\nexport function useChartColors(count: number, soft = false): string[] {\n const version = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [colors, setColors] = useState<string[]>(() => fallbackColors(count, soft));\n\n // Reads computed CSS custom properties, which only exist after the theme's\n // style tag is committed — this has to be a post-layout effect.\n /* eslint-disable react-hooks/set-state-in-effect -- token resolution is a DOM read after commit */\n useLayoutEffect(() => {\n setColors(resolveColors(count, soft));\n }, [count, soft, version]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n return colors;\n}\n\nfunction fallbackColors(count: number, soft: boolean): string[] {\n const tokens = soft ? CHART_TOKENS_SOFT : CHART_TOKENS;\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const token = tokens[i % tokens.length];\n result.push(FALLBACK_COLORS[token] ?? \"#6366f1\");\n }\n return result;\n}\n\nfunction resolveColors(count: number, soft: boolean): string[] {\n const tokens = soft ? CHART_TOKENS_SOFT : CHART_TOKENS;\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const token = tokens[i % tokens.length];\n result.push(resolveToken(token));\n }\n return result;\n}\n\nexport function useResolvedToken(token: string): string {\n const version = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [value, setValue] = useState(() => FALLBACK_COLORS[token] ?? \"#6366f1\");\n\n /* eslint-disable react-hooks/set-state-in-effect -- token resolution is a DOM read after commit */\n useLayoutEffect(() => {\n setValue(resolveToken(token));\n }, [token, version]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n return value;\n}\n\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n useLayoutEffect(() => {\n const mql = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const handler = (e: MediaQueryListEvent) => setReduced(e.matches);\n mql.addEventListener(\"change\", handler);\n return () => mql.removeEventListener(\"change\", handler);\n }, []);\n\n return reduced;\n}\n\nexport const useChartAnimation = (animated?: boolean): boolean => {\n const reduced = useReducedMotion();\n return animated !== false && !reduced;\n};\n","/**\n * Sprint 25.9, A3 — what a chart's category axis holds, and how its labels fit. No Recharts here: the charts entry and\n * the tests import it, and it never measures on its own (the measurer is handed in).\n *\n * - `categoryKind(labels)`: \"scale\" when every non-empty label is a date, a time, a period or a number, else \"names\".\n * Anchored patterns only — never `Date.parse`, which V8 lets read \"Tier 1\", \"Sprint 1\" and \"Northern Region 2\" as dates.\n * - `createAxisMeasurer(el)`: canvas text widths in the axis's resolved font, read from a probe that carries\n * `font-size: var(--ds-font-size-xs)`, so a `calc()` token (`calc(16px * .75)`, a 14 px base) measures right.\n * - `fitLabel(name, width, measure)`: one line; else two lines split at a space; else \"…\" on the second. Never drops it.\n */\n\nexport type CategoryKind = \"names\" | \"scale\";\n\n/** A text's width in px in the axis font. */\nexport type Measure = (text: string) => number;\n\nconst ENGLISH_MONTHS = [\n \"january\", \"february\", \"march\", \"april\", \"may\", \"june\", \"july\", \"august\", \"september\", \"october\", \"november\", \"december\",\n \"jan\", \"feb\", \"mar\", \"apr\", \"jun\", \"jul\", \"aug\", \"sep\", \"sept\", \"oct\", \"nov\", \"dec\",\n];\nconst ENGLISH_WEEKDAYS = [\n \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\",\n \"mon\", \"tue\", \"tues\", \"wed\", \"thu\", \"thur\", \"thurs\", \"fri\", \"sat\", \"sun\",\n];\n\nconst escape = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nconst clean = (s: string) => s.trim().toLowerCase().replace(/\\.$/, \"\");\n\nfunction intlNames(locale: string, kind: \"month\" | \"weekday\"): string[] {\n const out: string[] = [];\n try {\n for (const width of [\"short\", \"long\"] as const) {\n const fmt = new Intl.DateTimeFormat(locale, kind === \"month\" ? { month: width, timeZone: \"UTC\" } : { weekday: width, timeZone: \"UTC\" });\n // 2026-01-05 is a Monday: seven days give the weekdays, the 15th of each month the months\n const count = kind === \"month\" ? 12 : 7;\n for (let i = 0; i < count; i++) {\n const date = kind === \"month\" ? new Date(Date.UTC(2026, i, 15)) : new Date(Date.UTC(2026, 0, 5 + i));\n out.push(clean(fmt.format(date)));\n }\n }\n } catch {\n // an unknown locale tag: English covers it\n }\n return out;\n}\n\n/**\n * The languages whose month and weekday names count: English, and the locale given (a chart's locale while a\n * server-rendered page hydrates, the same on both sides: Sprint 25.20); with none given, the runtime's, the browser's and\n * the page's, as an app's own call and a chart in the browser read them (labels in the visitor's own language count).\n */\nfunction locales(given?: string): string[] {\n const out = new Set<string>([\"en\"]);\n if (given !== undefined) {\n out.add(given);\n return [...out];\n }\n try { out.add(new Intl.DateTimeFormat().resolvedOptions().locale); } catch { /* no Intl locale */ }\n if (typeof navigator !== \"undefined\" && navigator.language) out.add(navigator.language);\n if (typeof document !== \"undefined\" && document.documentElement?.lang) out.add(document.documentElement.lang);\n return [...out];\n}\n\ninterface Patterns { key: string; list: RegExp[] }\nlet cached: Patterns | null = null;\n\nfunction patterns(given?: string): Patterns {\n const tags = locales(given);\n const key = tags.join(\"|\");\n if (cached?.key === key) return cached;\n const months = new Set(ENGLISH_MONTHS);\n const weekdays = new Set(ENGLISH_WEEKDAYS);\n for (const tag of tags) {\n for (const m of intlNames(tag, \"month\")) if (m) months.add(m);\n for (const d of intlNames(tag, \"weekday\")) if (d) weekdays.add(d);\n }\n // the longest first, so \"sept\" wins over \"sep\" and \"june\" over \"jun\"\n const alt = (set: Set<string>) => [...set].sort((a, b) => b.length - a.length).map(escape).join(\"|\");\n const M = `(?:${alt(months)})\\\\.?`;\n const D = `(?:${alt(weekdays)})\\\\.?`;\n const day = String.raw`\\d{1,2}(?:st|nd|rd|th|\\.)?`;\n const year = String.raw`'?\\d{2,4}`;\n const list = [\n // dates in digits: 2026-09-21, 21/09, 09/21/2026, 21.09.2026, an ISO date-time\n /^\\d{4}[-/.]\\d{1,2}(?:[-/.]\\d{1,2})?$/,\n /^\\d{1,2}[-/.]\\d{1,2}(?:[-/.]\\d{2,4})?$/,\n /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{1,2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:?\\d{2})?$/,\n // a day and a month in either order, and a month alone or with its year: 16 Sep, 21. Sept., Sept 21, March 2026\n new RegExp(`^${day}\\\\s*${M}(?:,?\\\\s+${year})?$`, \"iu\"),\n new RegExp(`^${M}\\\\s*${day}(?:,?\\\\s+${year})?$`, \"iu\"),\n new RegExp(`^${M}(?:\\\\s*${year})?$`, \"iu\"),\n // CJK dates: 9月21日, 2026年9月, 9월 21일\n /^(?:\\d{4}年)?\\d{1,2}月(?:\\d{1,2}日)?$/u,\n /^\\d{4}年(?:\\d{1,2}月)?$/u,\n /^(?:\\d{4}년\\s?)?\\d{1,2}월(?:\\s?\\d{1,2}일)?$/u,\n // a quarter or a half: Q3, Q3 2026, Q3 FY26, 2026 Q3, 3Q26, H1 2026\n /^Q[1-4](?:\\s*[-/']?\\s*(?:FY\\s?)?'?\\d{2,4})?$/i,\n /^[1-4]Q\\s*'?\\d{0,4}$/i,\n /^(?:FY\\s?)?'?\\d{2,4}\\s*[-/]?\\s*Q[1-4]$/i,\n /^H[12](?:\\s*'?\\d{2,4})?$/i,\n // a year or a fiscal year: 2026, FY26, FY 2025/26, 2025/26, 2025-2026\n /^(?:19|20)\\d{2}$/,\n /^FY\\s?'?\\d{2,4}(?:\\s?[-/]\\s?'?\\d{2,4})?$/i,\n /^(?:19|20)\\d{2}\\s?[-/–]\\s?(?:(?:19|20)?\\d{2})$/,\n // a week: W12, Wk 3, Week 12, Week 12 2026, 2026-W12\n /^(?:W|Wk|Week)\\.?\\s?\\d{1,2}(?:\\s*[,/-]?\\s*\\d{4})?$/i,\n /^\\d{4}-?W\\d{1,2}(?:-?\\d)?$/i,\n // a weekday: Mon, Tuesday, and the runtime and page locales' own\n new RegExp(`^${D}$`, \"iu\"),\n // a time: 09:00, 9:30 pm, 9am, 14h\n /^\\d{1,2}:\\d{2}(?::\\d{2})?\\s?(?:[ap]\\.?m\\.?)?$/i,\n /^\\d{1,2}\\s?[ap]\\.?m\\.?$/i,\n /^\\d{1,2}h(?:\\d{2})?$/i,\n // a number, a percentage or an amount: 12, -3.5, 1,200, 12%, $5k, €1.2m, 5 €, a bin (10–20, <10, 50+)\n /^[<>≤≥~]?\\s?[+\\-−]?\\s?[$€£¥₹]?\\s?\\d[\\d,. \\u00a0\\u202f]*(?:\\s?(?:k|m|mn|bn|b|t))?\\s?(?:%|[$€£¥₹])?\\+?$/iu,\n /^[$€£¥₹]?\\d[\\d,.]*\\s?[-–]\\s?[$€£¥₹]?\\d[\\d,.]*\\s?(?:k|m|bn|%)?$/iu,\n ];\n cached = { key, list };\n return cached;\n}\n\n/**\n * Whether a category axis holds names or a scale (dates, times, periods, numbers). Every non-empty label must match an\n * anchored pattern to be \"scale\"; an all-empty set is \"scale\". LineChart and AreaChart are always \"scale\"; BarChart and\n * CompositeChart guess with this, and their `categoryKind` prop overrides the guess.\n */\nexport function categoryKind(labels: ReadonlyArray<unknown>, locale?: string): CategoryKind {\n const { list } = patterns(locale);\n for (const raw of labels) {\n if (raw == null) continue;\n if (typeof raw === \"number\") { if (Number.isFinite(raw)) continue; return \"names\"; }\n if (raw instanceof Date) continue;\n const text = String(raw).trim();\n if (!text) continue;\n if (!list.some((re) => re.test(text))) return \"names\";\n }\n return \"scale\";\n}\n\n/* ── Measuring ──────────────────────────────────────────────────────────── */\n\n/** The axis font as the page resolves it: size and family from a probe carrying the chart's tick tokens. */\nexport function resolvedAxisFont(el: Element): { font: string; px: number } {\n const doc = el.ownerDocument;\n const view = doc.defaultView;\n let probe = el.querySelector<HTMLElement>(\"[data-chart-probe]\");\n let temporary = false;\n if (!probe) {\n probe = doc.createElement(\"span\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n probe.style.cssText = \"position:absolute;visibility:hidden;pointer-events:none;white-space:nowrap;font-size:var(--ds-font-size-xs);font-family:var(--ds-font-sans)\";\n el.appendChild(probe);\n temporary = true;\n }\n const cs = view?.getComputedStyle(probe);\n const px = parseFloat(cs?.fontSize ?? \"\") || 12;\n const family = (cs?.fontFamily ?? \"\").trim() || \"sans-serif\";\n const style = cs?.fontStyle && cs.fontStyle !== \"normal\" ? `${cs.fontStyle} ` : \"\";\n const weight = cs?.fontWeight && cs.fontWeight !== \"400\" && cs.fontWeight !== \"normal\" ? `${cs.fontWeight} ` : \"\";\n if (temporary) probe.remove();\n return { font: `${style}${weight}${px}px ${family}`, px };\n}\n\n/** One 2D context for every chart, kept per getContext implementation (a test may swap it for a stub). */\nlet shared: { getContext: unknown; ctx: CanvasRenderingContext2D | null } | null = null;\n\nfunction canvasContext(): CanvasRenderingContext2D | null {\n if (typeof document === \"undefined\") return null;\n const getContext = (globalThis as { HTMLCanvasElement?: { prototype: { getContext?: unknown } } }).HTMLCanvasElement?.prototype.getContext;\n if (shared && shared.getContext === getContext) return shared.ctx;\n let ctx: CanvasRenderingContext2D | null = null;\n try { ctx = document.createElement(\"canvas\").getContext?.(\"2d\") ?? null; } catch { ctx = null; }\n shared = { getContext, ctx };\n return ctx;\n}\n\n/**\n * A text measurer in the chart's own axis font, or null where there is no canvas (jsdom): the charts then show every\n * label in full on one line and leave the thinning to nobody.\n */\nexport function createAxisMeasurer(el: Element): { measure: Measure; px: number; font: string } | null {\n const ctx = canvasContext();\n if (!ctx) return null;\n const { font, px } = resolvedAxisFont(el);\n ctx.font = font;\n const widths = new Map<string, number>();\n const measure: Measure = (text) => {\n let w = widths.get(text);\n if (w === undefined) {\n // the context is shared: another chart may have set its own font since\n ctx.font = font;\n w = ctx.measureText(text).width;\n widths.set(text, w);\n }\n return w;\n };\n return { measure, px, font };\n}\n\n/* ── Fitting a name ─────────────────────────────────────────────────────── */\n\nexport const ELLIPSIS = \"…\";\n\nexport interface FittedLabel {\n /** One or two lines; the second ends with \"…\" when the name was cut. */\n lines: string[];\n cut: boolean;\n /** Characters of the name that show, spaces and the ellipsis left out. */\n shown: number;\n}\n\nconst letters = (s: string) => s.replace(/\\s+/g, \"\").replace(/…/g, \"\").length;\n\n/** The longest prefix of `text` that fits `width` (at least one character). */\nfunction prefixThatFits(text: string, width: number, measure: Measure, suffix = \"\"): number {\n let lo = 1;\n let hi = text.length;\n let best = 0;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (measure(text.slice(0, mid).trimEnd() + suffix) <= width) { best = mid; lo = mid + 1; } else hi = mid - 1;\n }\n return best;\n}\n\n/**\n * A name fitted to `width`: one line when it fits; else two lines split at a space; else the second line ends with \"…\".\n * A first word wider than the line breaks where the line ends, with a hyphen, so it reads as one word going on. The\n * name is never dropped, and without a measurer it shows in full on one line.\n */\nexport function fitLabel(name: string, width: number, measure: Measure | null): FittedLabel {\n const text = name.replace(/\\s+/g, \" \").trim();\n if (!measure || !text || width <= 0 || measure(text) <= width) return { lines: [text], cut: false, shown: letters(text) };\n const words = text.split(\" \");\n let first = \"\";\n let firstShown = \"\";\n let rest = \"\";\n for (let i = words.length - 1; i >= 1; i--) {\n const candidate = words.slice(0, i).join(\" \");\n if (measure(candidate) <= width) { first = firstShown = candidate; rest = words.slice(i).join(\" \"); break; }\n }\n if (!first) {\n // the first word alone is too wide: the first line holds what fits of it and a hyphen\n const k = Math.max(1, prefixThatFits(text, width, measure, \"-\"));\n firstShown = text.slice(0, k).trimEnd();\n rest = text.slice(k).trimStart();\n first = rest && !text.slice(k - 1, k + 1).includes(\" \") ? `${firstShown}-` : firstShown;\n }\n if (!rest) return { lines: [first], cut: false, shown: letters(firstShown) };\n if (measure(rest) <= width) return { lines: [first, rest], cut: false, shown: letters(firstShown) + letters(rest) };\n const k = prefixThatFits(rest, width, measure, ELLIPSIS);\n const kept = k > 0 ? rest.slice(0, k).trimEnd() : \"\";\n return { lines: [first, kept + ELLIPSIS], cut: true, shown: letters(firstShown) + letters(kept) };\n}\n\n/** D8: fewer visible characters than this on a cut name turns an upright chart of names sideways. */\nexport const MIN_NAME_CHARS = 6;\n\n/** Whether any name, fitted to `width`, would be cut to fewer than MIN_NAME_CHARS characters. */\nexport function namesCutShort(names: ReadonlyArray<string>, width: number, measure: Measure): boolean {\n return names.some((n) => {\n const fit = fitLabel(n, width, measure);\n return fit.cut && fit.shown < MIN_NAME_CHARS;\n });\n}\n","import {\n Children, createContext, forwardRef, isValidElement, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState,\n type CSSProperties, type KeyboardEvent, type ReactNode, type Ref,\n} from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { elementType } from \"../../lib/element-type\";\nimport { mergeRefs } from \"../../lib/slot\";\n\n/* ── Heights ────────────────────────────────────────────────────────────── */\n\n/** A chart's height: \"auto\" (the default) sizes it from its type and its data; a preset or a number overrides. */\nexport type ChartHeight = \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n\nexport const CHART_HEIGHTS = {\n sm: \"var(--ds-chart-height-sm)\",\n md: \"var(--ds-chart-height-md)\",\n lg: \"var(--ds-chart-height-lg)\",\n} as const;\n\n/** One row of a row chart (a sideways bar, a funnel stage). */\nexport const CHART_ROW = \"var(--ds-chart-row, 2rem)\";\n\n/** A preset or a number as a CSS height; \"auto\" and \"fill\" have none (the chart sizes itself). */\nexport function fixedChartHeight(height: ChartHeight | \"fill\" | undefined): string | undefined {\n if (typeof height === \"number\") return `${height}px`;\n if (height === \"sm\" || height === \"md\" || height === \"lg\") return CHART_HEIGHTS[height];\n return undefined;\n}\n\n/**\n * How a chart sizes itself (Sprint 25.9, A2, P2):\n * - \"rows\" (a sideways BarChart, a FunnelChart): a row per item, never under sm; `units` rows, `lines` extra label lines\n * (a two-line name makes its row one line taller), `axis` the value axis and titles below or above the rows;\n * - \"ratio\" (charts over dates or numbers, Treemap, Sankey): two wide to one high, between sm and lg;\n * - \"square\" (Pie, Radar, RadialBar): as tall as wide, between sm and lg.\n */\nexport type ChartSize =\n | { model: \"ratio\" }\n | { model: \"square\" }\n | { model: \"rows\"; units: number; lines?: number; axis?: string };\n\nconst SM = CHART_HEIGHTS.sm;\nconst LG = CHART_HEIGHTS.lg;\n\n/**\n * The plot box's height and its bound in a row. `cqi` resolves against the chart's wrapper, the size container, because\n * the plot box is its child (on the wrapper itself it would read the page's container). The box is `flex: 1 0 auto`,\n * never `flex-1`: its drawing is absolute, so a zero basis would collapse it (R5). In a row it grows to the row's\n * height up to a bound: a ratio chart to square, a row chart to twice its height, a round chart not at all.\n */\nexport function plotBoxStyle(size: ChartSize, fixed: string | undefined): CSSProperties {\n if (size.model === \"square\") {\n return { height: fixed ?? `clamp(${SM}, 100cqi, ${LG})`, flex: \"0 0 auto\" };\n }\n if (size.model === \"rows\") {\n const lines = size.lines ? ` + ${size.lines} * 1.25 * var(--ds-font-size-xs)` : \"\";\n const height = fixed ?? `max(${SM}, calc(${size.units} * ${CHART_ROW}${lines} + ${size.axis ?? CHART_ROW}))`;\n return { height, maxHeight: `calc(2 * ${height})`, flex: \"1 0 auto\" };\n }\n return { height: fixed ?? `clamp(${SM}, 50cqi, ${LG})`, maxHeight: `max(${fixed ?? LG}, 100cqi)`, flex: \"1 0 auto\" };\n}\n\n/* ── The chart mark ─────────────────────────────────────────────────────── */\n\n/**\n * Marks the library's charts, so ChartContainer knows its child sizes itself and needs no minimum area of its own.\n * `Symbol.for`, as PAGE_HEADER_MARK, so a second copy of the module still matches. A hand-built chart, an EmptyState\n * or a Sparkline carries no mark and keeps the container's area.\n */\nexport const CHART_MARK: unique symbol = Symbol.for(\"gridsmith.Chart\") as never;\n\nexport function markChart<T extends object>(component: T): T {\n Object.assign(component, { [CHART_MARK]: true });\n return component;\n}\n\n/** A single library chart (not a Fragment, a wrapper of the builder's or a list of children). */\nexport function isLibraryChart(children: ReactNode): boolean {\n const kids = Children.toArray(children);\n if (kids.length !== 1) return false;\n const only = kids[0];\n if (!isValidElement(only)) return false;\n const type = elementType(only.type) as Record<symbol, unknown> | string | null;\n return !!type && typeof type !== \"string\" && type[CHART_MARK] === true;\n}\n\n/* ── Context ────────────────────────────────────────────────────────────── */\n\nexport interface ChartContainerValue {\n /** The container's own height (a preset or a number, as CSS): it beats the chart's. */\n height?: string;\n /** The container title's id: the chart's graphic is named by it. */\n titleId?: string;\n /** The chart is not the container's only child (or is wrapped): it fills the container's area instead of sizing itself. */\n fillArea?: boolean;\n}\n\nexport const ChartContainerContext = createContext<ChartContainerValue | null>(null);\n\nexport function useInsideChartContainer(): boolean {\n return useContext(ChartContainerContext) !== null;\n}\n\n/** The chart's slots outside its drawing: the legend (Recharts' Legend portals into it) and the tooltip's live region. */\nexport interface ChartFrame {\n legend: HTMLElement | null;\n live: HTMLElement | null;\n /** A value in full, with its unit, for the tooltip and what the chart says (Sprint 25.17 A27); toLocaleString without one. */\n formatValue?: (value: number, dataKey?: string) => string;\n}\n\nexport const ChartFrameContext = createContext<ChartFrame>({ legend: null, live: null });\n\n/* ── Keyboard ───────────────────────────────────────────────────────────── */\n\nconst REMAPPED = new WeakSet<Event>();\n\n/**\n * A sideways chart lists its rows top to bottom. Recharts maps only ArrowLeft and ArrowRight, and in that layout reads\n * ArrowRight as the row above. Down and Right move to the next row, Up and Left to the one before, in reading order.\n */\nfunction remapRowKeys(e: KeyboardEvent<HTMLDivElement>) {\n if (REMAPPED.has(e.nativeEvent)) return;\n const next = e.key === \"ArrowDown\" || e.key === \"ArrowRight\";\n const previous = e.key === \"ArrowUp\" || e.key === \"ArrowLeft\";\n if (!next && !previous) return;\n const target = e.target as Element;\n if (!target.closest?.(\".recharts-wrapper\")) return;\n e.preventDefault();\n e.stopPropagation();\n const View = target.ownerDocument.defaultView ?? window;\n const event = new View.KeyboardEvent(\"keydown\", { key: next ? \"ArrowLeft\" : \"ArrowRight\", bubbles: true, cancelable: true });\n REMAPPED.add(event);\n target.dispatchEvent(event);\n}\n\n/* ── The wrapper ────────────────────────────────────────────────────────── */\n\nexport interface ChartWrapperProps {\n /** The chart's own height prop. A ChartContainer's preset or number beats it. */\n height?: ChartHeight;\n /** How the chart sizes itself when no height is set. */\n size: ChartSize;\n /** The chart type, for `data-gs-chart` (the bench reads it). */\n chart: string;\n /** A cartesian category axis: its kind and its categories (`data-category-kind`, `data-categories`). */\n categoryKind?: \"names\" | \"scale\";\n categories?: number;\n /** Which axis carries the categories, for the label counts (`data-labels-shown`, `data-labels-cut`). */\n categoryAxis?: \"x\" | \"y\";\n /** The rows run top to bottom (a sideways BarChart): the arrow keys follow them. */\n sideways?: boolean;\n /** The value axis's title, drawn horizontally above the axis (the chart leaves room at the top). */\n axisTitle?: string;\n className?: string;\n children: ReactNode;\n /** The chart's values in full, for its tooltip, by series (Sprint 25.17 A27). */\n formatValue?: (value: number, dataKey?: string) => string;\n \"aria-label\"?: string;\n}\n\n/**\n * Sprint 25.9, A2: the chart's frame and its size container. It holds the plot box (the Recharts drawing sits absolutely\n * inside it), the legend's slot below and the tooltip's live region, and owns the height, with or without a\n * ChartContainer. `min-inline-size` keeps a shrink-to-fit parent from collapsing it.\n */\nexport const ChartWrapper = forwardRef<HTMLDivElement, ChartWrapperProps>(function ChartWrapper({\n height = \"auto\",\n size,\n chart,\n categoryKind,\n categories,\n categoryAxis,\n sideways = false,\n axisTitle,\n className,\n children,\n formatValue,\n \"aria-label\": ariaLabel,\n}, ref) {\n const container = useContext(ChartContainerContext);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const plotRef = useRef<HTMLDivElement | null>(null);\n const [legend, setLegend] = useState<HTMLDivElement | null>(null);\n const [live, setLive] = useState<HTMLDivElement | null>(null);\n const frame = useMemo<ChartFrame>(() => ({ legend, live, formatValue }), [legend, live, formatValue]);\n // The drawing never shrinks below the plot box's last real size. A box sized with `cqi` reports a width of 0 for a\n // moment while headless Chrome takes a full-page screenshot; handed to Recharts, that cleared the drawing, so the\n // screenshot showed an empty chart or bars growing again from zero (measured). A reading of 0 is no layout: the\n // drawing keeps its size, grows at once and shrinks a frame later.\n const [drawn, setDrawn] = useState<{ width: number; height: number } | null>(null);\n useLayoutEffect(() => {\n const plot = plotRef.current;\n if (!plot || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver((entries) => {\n const box = entries[entries.length - 1]?.contentRect;\n if (!box || box.width <= 0 || box.height <= 0) return;\n setDrawn((prev) => (prev && Math.abs(prev.width - box.width) < 0.5 && Math.abs(prev.height - box.height) < 0.5 ? prev : { width: box.width, height: box.height }));\n });\n observer.observe(plot);\n return () => observer.disconnect();\n }, []);\n\n const fill = container?.fillArea === true;\n const fixed = container?.height ?? fixedChartHeight(height);\n const plotStyle: CSSProperties = fill ? { flex: \"1 1 0%\", minHeight: 0 } : plotBoxStyle(size, fixed);\n\n // The graphic is named by the chart's own label, else by its container's title (A1).\n const named = ariaLabel\n ? { role: \"img\", \"aria-label\": ariaLabel }\n : container?.titleId\n ? { role: \"img\", \"aria-labelledby\": container.titleId }\n : {};\n\n // A8: how many category labels show, and how many were shortened, counted on the rendered ticks.\n useEffect(() => {\n const root = rootRef.current;\n const plot = plotRef.current;\n if (!root || !plot || !categoryAxis || typeof MutationObserver === \"undefined\") return;\n const selector = `.recharts-${categoryAxis}Axis-tick-labels .recharts-cartesian-axis-tick-value`;\n const count = () => {\n const labels = Array.from(plot.querySelectorAll(selector)).filter((el) => (el.textContent ?? \"\").trim() !== \"\");\n const shown = String(labels.length);\n const cut = String(labels.filter((el) => el.hasAttribute(\"data-cut\")).length);\n if (root.getAttribute(\"data-labels-shown\") !== shown) root.setAttribute(\"data-labels-shown\", shown);\n if (root.getAttribute(\"data-labels-cut\") !== cut) root.setAttribute(\"data-labels-cut\", cut);\n };\n count();\n const observer = new MutationObserver(count);\n observer.observe(plot, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: [\"data-cut\"] });\n return () => observer.disconnect();\n }, [categoryAxis]);\n\n return (\n <div\n ref={mergeRefs(ref as Ref<HTMLElement>, rootRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n data-gs-chart={chart}\n data-category-kind={categoryKind}\n data-categories={categories}\n className={cn(\"relative flex w-full flex-col\", fill && \"h-full\", className)}\n style={{ containerType: \"inline-size\", minInlineSize: \"min(100%, 16rem)\", ...(fill ? {} : { flex: \"1 0 auto\" }) }}\n >\n <div\n ref={plotRef}\n data-chart-plot=\"\"\n className=\"relative w-full\"\n style={plotStyle}\n onKeyDownCapture={sideways ? remapRowKeys : undefined}\n {...named}\n >\n {axisTitle && (\n <span data-chart-axis-title=\"\" className=\"absolute left-0 top-0 whitespace-nowrap text-xs text-[var(--ds-text-muted)] font-[family-name:var(--ds-font-sans)] leading-normal\">\n {axisTitle}\n </span>\n )}\n <div className=\"absolute inset-0\" style={drawn ? { minWidth: drawn.width, minHeight: drawn.height } : undefined}>\n <ChartFrameContext.Provider value={frame}>{children}</ChartFrameContext.Provider>\n </div>\n </div>\n <div ref={setLegend} data-chart-legend=\"\" />\n <div ref={setLive} role=\"status\" aria-live=\"polite\" className=\"sr-only\" />\n {/* the axis font and one row, as the page resolves them (useAxisMeasure reads it) */}\n <span\n data-chart-probe=\"\"\n aria-hidden=\"true\"\n className=\"pointer-events-none invisible absolute left-0 top-0\"\n style={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", height: CHART_ROW, width: 0 }}\n />\n </div>\n );\n});\n","import { getNiceTickValues } from \"recharts\";\n\n/**\n * How a chart's values read (Sprint 25.17 A27, R28-50, P21). \"number\" (the default): plain numbers, compact on the axis\n * from five digits up (1M, 750K; 1,234 as it is). \"percent\": values are percentages out of 100 (45 reads 45%; multiply a fraction by\n * 100 first). \"milliseconds\": durations in ms (120 ms, 1.5 s, 2 min). \"bytes\": sizes in bytes, in the units of 1,000 the\n * browser's own formats name (1.5 MB). A function formats both the axis and the tooltip itself. Everything is in the\n * page's language (its `lang`, in the visitor's formats where they speak it: formatLocale).\n */\nexport type ValueFormat = \"number\" | \"percent\" | \"milliseconds\" | \"bytes\" | ((value: number) => string);\n\n/** Recharts draws a value axis with five ticks on a nice scale that includes 0 (its default domain, [0, \"auto\"]). */\nconst TICK_COUNT = 5;\n\nconst TIME_UNITS: Array<[unit: string, ms: number]> = [[\"hour\", 3_600_000], [\"minute\", 60_000], [\"second\", 1_000], [\"millisecond\", 1]];\nconst BYTE_UNITS: Array<[unit: string, bytes: number]> = [[\"petabyte\", 1e15], [\"terabyte\", 1e12], [\"gigabyte\", 1e9], [\"megabyte\", 1e6], [\"kilobyte\", 1e3], [\"byte\", 1]];\n\n/** Fraction digits tried before giving up on an exact label (a value with more is shown to this many). */\nconst MAX_FRACTION = 10;\n\n/**\n * A value as `format` writes it with the fewest fraction digits that show it exactly, in the locale's own notation:\n * 2,500 is \"2.5K\" in English and 15,000 \"1.5万\" in Japanese, 0.0004 is \"0.0004\" — never a rounded \"3K\", \"2万\" or \"0\"\n * (Sprint 25.17's review: digits counted in thousands misread the locales that group by 万 or by lakh, and a cap of\n * three turned small rates into a row of zeros). Exact means more digits change nothing.\n */\nfunction exact(format: (digits: number) => string, maxDigits = MAX_FRACTION): string {\n for (let digits = 0; digits < maxDigits; digits++) {\n const label = format(digits);\n if (label === format(digits + 6)) return label;\n }\n return format(maxDigits);\n}\n\nconst unitFormat = (unit: string, value: number, locale: string | undefined) => (digits: number) =>\n new Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay: \"short\", maximumFractionDigits: digits }).format(value);\n\nconst unitsOf = (format: \"milliseconds\" | \"bytes\") => (format === \"bytes\" ? BYTE_UNITS : TIME_UNITS);\n\n/** The largest unit a value reaches (1.5 MB, 120 ms), for a value read on its own. */\nfunction unitReached(units: Array<[string, number]>, value: number): [string, number] {\n return units.find(([, size]) => Math.abs(value) >= size) ?? units[units.length - 1];\n}\n\n/**\n * One unit for a whole axis (the review: \"0 ms, 25 sec, 1.25 min\" chose it tick by tick): the largest its biggest tick\n * reaches in which every tick reads exactly in two fraction digits or fewer, so 25 s and 75 s stay seconds where minutes\n * would read 0.417.\n */\nfunction axisUnit(units: Array<[string, number]>, ticks: number[]): [string, number] {\n const largest = Math.max(0, ...ticks.map(Math.abs));\n const exactIn = (size: number) => ticks.every((t) => Math.abs((t / size) * 100 - Math.round((t / size) * 100)) < 1e-6);\n return units.find(([, size]) => largest / size >= 1 && exactIn(size)) ?? units[units.length - 1];\n}\n\n/** The ticks Recharts draws for these values on a value axis. */\nexport function valueAxisTicks(values: number[]): number[] {\n const finite = values.filter(Number.isFinite);\n if (!finite.length) return [];\n const lo = Math.min(0, ...finite);\n const hi = Math.max(0, ...finite);\n if (lo === hi) return [lo];\n return getNiceTickValues([lo, hi], TICK_COUNT, true).map(Number);\n}\n\n/**\n * A value axis's tick labels: compact from five digits up, in the chart's locale (its useFormatLocale(), Sprint 25.20),\n * each exact (formatted as Recharts draws it, whatever ticks it picks); a duration or a size in one unit for the axis.\n */\nexport function axisTickFormatter(values: number[], format: ValueFormat | undefined, locale: string | undefined): (value: number) => string {\n if (typeof format === \"function\") return format;\n if (format === \"percent\") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: \"percent\", maximumFractionDigits: d }).format(value / 100));\n if (format === \"milliseconds\" || format === \"bytes\") {\n const [unit, size] = axisUnit(unitsOf(format), valueAxisTicks(values));\n return (value) => exact(unitFormat(unit, value / size, locale));\n }\n const compact = (value: number) => exact((d) => new Intl.NumberFormat(locale, { notation: \"compact\", maximumFractionDigits: d }).format(value));\n const plain = (value: number) => exact((d) => new Intl.NumberFormat(locale, { maximumFractionDigits: d }).format(value));\n // compact where it pays, from five digits up (250k for 250,000); below, the number as people write it: 1,234, never\n // 1.234K, which is longer and reads worse (the 25.17 second review). Read from the values, so a domain of the page's own\n // (2018 to 2024) is read as Recharts draws it.\n const largest = Math.max(0, ...values.filter(Number.isFinite).map(Math.abs));\n return largest >= COMPACT_FROM ? compact : plain;\n}\n\n/** The size from which a value axis's numbers read compact (Sprint 25.17's second review). */\nconst COMPACT_FROM = 10_000;\n\n/** A value in full, as the tooltip shows it, in the chart's locale: every digit of a number (grouped); a duration's or a size's, exactly, in the largest unit it reaches. */\nexport function fullValueFormatter(format: ValueFormat | undefined, locale: string | undefined): (value: number) => string {\n if (typeof format === \"function\") return format;\n if (format === undefined || format === \"number\") return (value) => value.toLocaleString(locale);\n if (format === \"percent\") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: \"percent\", maximumFractionDigits: d }).format(value / 100), 4);\n return (value) => {\n const [unit, size] = unitReached(unitsOf(format), value);\n return exact(unitFormat(unit, value / size, locale), 4);\n };\n}\n\n/** A series a value axis draws: its key, and the stack it sits in (null: on its own). */\nexport interface AxisSeries {\n dataKey: string;\n stack: string | null;\n}\n\n/**\n * The values a value axis spans: each value of a series drawn on its own, and each stack's positive values summed up from\n * 0 and its negative values down — the charts stack both ways from zero (Sprint 25.17's review: a stack of 6,500 up and\n * 2,500 down was read as one sum of 4,000). One reading for every chart.\n */\nexport function axisExtent(data: Record<string, unknown>[], series: AxisSeries[]): number[] {\n return data.flatMap((row) => {\n const own: number[] = [];\n const up = new Map<string, number>();\n const down = new Map<string, number>();\n for (const s of series) {\n const raw = row[s.dataKey];\n const v = typeof raw === \"number\" ? raw : typeof raw === \"string\" && raw.trim() !== \"\" ? Number(raw) : NaN;\n if (!Number.isFinite(v)) continue;\n if (s.stack == null) own.push(v);\n else if (v >= 0) up.set(s.stack, (up.get(s.stack) ?? 0) + v);\n else down.set(s.stack, (down.get(s.stack) ?? 0) + v);\n }\n return [...own, ...up.values(), ...down.values()];\n });\n}\n\n/** The values a value axis spans for these series: each on its own, or one stack of them all. */\nexport function seriesValues(data: Record<string, unknown>[], keys: string[], stacked = false): number[] {\n return axisExtent(data, keys.map((dataKey) => ({ dataKey, stack: stacked ? \"stack\" : null })));\n}\n","import { useContext, useEffect, useLayoutEffect, useMemo, useState, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Legend, Text } from \"recharts\";\nimport { useResolvedToken } from \"../../lib/chart-utils\";\nimport { createAxisMeasurer, fitLabel, namesCutShort, type CategoryKind, type Measure } from \"../../lib/chart-categories\";\nimport { ChartFrameContext } from \"./ChartWrapper\";\nimport { valueAxisTicks } from \"./value-format\";\nimport { formatLocale } from \"../../lib/format-locale\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\ninterface TooltipEntry {\n name: string;\n value: number | string;\n color: string;\n dataKey?: string;\n payload?: Record<string, unknown>;\n}\n\ninterface ChartTooltipContentProps {\n active?: boolean;\n payload?: TooltipEntry[];\n label?: string;\n}\n\nconst hasLabel = (label: unknown) => label != null && label !== \"\" && typeof label !== \"number\";\n/**\n * A series' name. A chart without a category label (a pie's slice, a funnel's stage, a treemap's tile) names the item by\n * its row's `name`; on an axis chart the row's `name` is the category, already shown as the label, so the series keeps\n * its own (a row keyed by `name` read \"Alice: Alice 20\" instead of \"Alice: Hours 20\").\n */\nconst entryName = (entry: TooltipEntry, label: unknown) =>\n (!hasLabel(label) && typeof entry.payload?.name === \"string\" && entry.payload.name) || entry.name;\n/** A value as the tooltip shows it: in full, with the chart's unit (Sprint 25.17 A27), else grouped in the locale given. */\nconst entryValue = (entry: TooltipEntry, format: ((value: number, dataKey?: string) => string) | undefined, locale: string | undefined) =>\n (typeof entry.value === \"number\" ? (format ? format(entry.value, entry.dataKey) : entry.value.toLocaleString(locale)) : entry.value);\n\n/** What the live region says for the active point: its category, then each series' name and value. */\nexport function tooltipAnnouncement(label: unknown, payload: TooltipEntry[] | undefined, format?: (value: number, dataKey?: string) => string, locale: string | undefined = formatLocale()): string {\n if (!payload?.length) return \"\";\n const values = payload.map((entry) => `${entryName(entry, label)} ${entryValue(entry, format, locale)}`).join(\", \");\n return hasLabel(label) ? `${String(label)}: ${values}` : values;\n}\n\n/**\n * The chart's tooltip box. What it shows is also said in the chart's `role=\"status\"` `aria-live=\"polite\"` region, which\n * sits outside the drawing (a graphic's children are presentational) and starts empty, so the category and the values\n * are heard as the pointer or the arrow keys move (WCAG 4.1.3). Outside a library chart the region wraps the box.\n */\nexport function ChartTooltipContent({ active, payload, label }: ChartTooltipContentProps) {\n const bgSurface = useResolvedToken(\"--ds-bg-surface\");\n const borderSubtle = useResolvedToken(\"--ds-border-subtle\");\n const textPrimary = useResolvedToken(\"--ds-text-primary\");\n const textSecondary = useResolvedToken(\"--ds-text-secondary\");\n const { live, formatValue } = useContext(ChartFrameContext);\n // the values in the chart's locale (Sprint 25.20)\n const locale = useFormatLocale();\n\n const on = !!active && !!payload?.length;\n const showLabel = hasLabel(label);\n\n const box = on ? (\n <div\n className=\"rounded-[var(--ds-radius-md)] shadow-[var(--ds-shadow-popover)] font-[family-name:var(--ds-font-sans)] text-sm\"\n style={{\n backgroundColor: bgSurface,\n border: `var(--ds-border-width) solid ${borderSubtle}`,\n padding: \"var(--ds-space-2) var(--ds-space-3)\",\n }}\n >\n {showLabel && (\n <p className=\"font-medium mb-ds-1\" style={{ color: textPrimary }}>\n {label}\n </p>\n )}\n {payload!.map((entry, i) => {\n const dotColor = (entry.payload?.fill as string) || entry.color || textSecondary;\n return (\n <div key={i} className=\"flex items-center gap-ds-2\" style={{ marginTop: i > 0 ? 2 : 0 }}>\n <span\n className=\"shrink-0 rounded-[var(--ds-radius-full)]\"\n style={{ width: 8, height: 8, backgroundColor: dotColor }}\n />\n <span style={{ color: textSecondary }}>{entryName(entry, label)}:</span>\n <span className=\"tabular-nums\" style={{ color: textPrimary }}>\n {entryValue(entry, formatValue, locale)}\n </span>\n </div>\n );\n })}\n </div>\n ) : null;\n\n if (live) {\n return (\n <>\n {box}\n {createPortal(on ? tooltipAnnouncement(label, payload, formatValue, locale) : \"\", live)}\n </>\n );\n }\n return (\n <div role=\"status\" aria-live=\"polite\">\n {box}\n </div>\n );\n}\n\ninterface ChartLegendContentProps {\n payload?: Array<{\n value: string;\n color: string;\n dataKey?: string;\n }>;\n}\n\n/** A legend entry's outline: the series' stroke when it has one (a soft bar's solid edge, a line), else its colour. */\nfunction swatchEdge(entry: { color?: string; payload?: unknown }): string | undefined {\n const stroke = (entry.payload as { stroke?: unknown } | undefined)?.stroke;\n return typeof stroke === \"string\" ? stroke : entry.color;\n}\n\nexport function ChartLegendContent({ payload }: ChartLegendContentProps) {\n const textSecondary = useResolvedToken(\"--ds-text-secondary\");\n\n if (!payload?.length) return null;\n\n return (\n <div className=\"flex flex-wrap justify-center gap-y-ds-1 gap-x-ds-4 font-[family-name:var(--ds-font-sans)] text-sm\">\n {payload.map((entry, i) => (\n <div key={i} className=\"flex items-center gap-ds-1.5\">\n <span\n className=\"shrink-0 rounded-[var(--ds-radius-full)]\"\n // the series' own fill inside its outline (a soft bar's solid stroke), so a 30% tint stays visible (C4)\n style={{ width: 10, height: 10, backgroundColor: entry.color, border: `1.5px solid ${swatchEdge(entry)}` }}\n />\n <span style={{ color: textSecondary }}>{entry.value}</span>\n </div>\n ))}\n </div>\n );\n}\n\n/** Legend items in the order the chart draws its series: by dataKey (bars, lines, areas, radars) or by name (a pie's slices). */\nexport function seriesSorter(order: ReadonlyArray<string>, by: \"dataKey\" | \"value\" = \"dataKey\") {\n return (item: { dataKey?: unknown; value?: unknown }) => {\n const key = by === \"dataKey\" ? item.dataKey : item.value;\n const i = order.indexOf(String(key));\n return i < 0 ? order.length : i;\n };\n}\n\n/**\n * Sprint 25.9, A2: the chart's legend is Recharts' own Legend portalled into the slot below the drawing, so it no longer\n * takes its height from the plot. It keeps ChartLegendContent and its swatch, and follows the series' order, not the\n * alphabet (Recharts' default `itemSorter: \"value\"`). Rendered once the slot exists, so it never lands in the drawing.\n */\nexport function ChartLegend({ order, by = \"dataKey\" }: { order: ReadonlyArray<string>; by?: \"dataKey\" | \"value\" }) {\n const { legend } = useContext(ChartFrameContext);\n const orderKey = order.join(\"\\u0001\");\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the order is compared by value\n const sorter = useMemo(() => seriesSorter(order, by), [orderKey, by]);\n if (!legend) return null;\n return <Legend portal={legend} content={<ChartLegendContent />} itemSorter={sorter} wrapperStyle={{ paddingTop: \"var(--ds-space-3)\" }} />;\n}\n\nexport function useGridStroke(): string {\n return useResolvedToken(\"--ds-border-subtle\");\n}\n\nexport function useAxisStyle() {\n const textMuted = useResolvedToken(\"--ds-text-muted\");\n\n return {\n tick: {\n fontSize: \"var(--ds-font-size-xs)\",\n fontFamily: \"var(--ds-font-sans)\",\n fill: textMuted,\n // Sprint 25.9: Recharts paints a default tick's text with the axis stroke (#666 unless set), not with fill, so the\n // value axes drew their numbers at about 2.6:1 on dark cards (WCAG 1.4.3 asks 4.5:1). Every axis that spreads this\n // hides its axis and tick lines, so the stroke only colours the text.\n stroke: textMuted,\n },\n };\n}\n\nexport function useRadius(): number {\n const val = useResolvedToken(\"--ds-radius-md\");\n const parsed = parseInt(val, 10);\n return isNaN(parsed) ? 6 : parsed;\n}\n/**\n * Recharts' `tick` prop as an object only passes SVG-valid properties.\n * Props like `maxLines`, `verticalAnchor` are stripped. We must use a\n * function to pass them to the internal Text component.\n */\nexport function xAxisTick(props: Record<string, unknown>) {\n // No width box (Sprint 25.3 C12): with one, Recharts measured \"20 Aug\" in a hidden span that did not carry the\n // chart's font, judged it too wide for its share of the axis and wrapped or truncated it. Without a width Text never\n // wraps or truncates; `interval` (preserveStartEnd) thins colliding ticks and keeps the first and last. Recharts' own\n // Text keeps the axis's auto height right, which a bare <text> does not (the label was clipped 8px in the pass).\n // Scale axes (dates, numbers) keep this tick; a names axis takes namesTick.\n const { x, y, payload, width: _width, visibleTicksCount: _count, ...rest } = props as {\n x: number; y: number; payload: { value: string };\n width?: number; visibleTicksCount?: number; [k: string]: unknown;\n };\n return (\n <Text {...rest} x={x} y={y} textAnchor=\"middle\" verticalAnchor=\"start\">\n {payload.value}\n </Text>\n );\n}\n\nexport function yAxisTick(props: Record<string, unknown>) {\n const { x, y, payload, ...rest } = props as { x: number; y: number; payload: { value: string };[k: string]: unknown };\n return (\n <Text {...rest} x={x} y={y} textAnchor=\"end\" verticalAnchor=\"middle\" width={200} maxLines={2}>\n {payload.value}\n </Text>\n );\n}\n\n/* ── Names on a category axis (Sprint 25.9, A3) ─────────────────────────── */\n\n/** The line height of a two-line name, in em. */\nconst LINE_EM = 1.2;\n/** The least space between two names under an upright chart. */\nexport const NAME_GAP = 8;\n/**\n * A sideways name's inset from its column: Recharts draws it tickSize + tickMargin (8 px) left of the axis edge, and\n * the chart's own margin leaves 4 px on the left.\n */\nexport const NAME_COLUMN_INSET = 12;\n\n/**\n * The tick for a names axis: each name fitted to its band — one line; else two lines split at a space; else \"…\" on\n * the second — inside one `<g className={props.className}>`, so Recharts sizes the axis for both lines (two Texts each\n * carrying the tick's class leave the axis sized for one, and the second line clipped). The full name is the label's\n * `<title>`. Upright, the band is the axis width over the ticks it draws; sideways it is the name column the chart sets.\n * Without a measurer (no canvas) every name shows in full on one line.\n */\nexport function namesTick(measure: Measure | null, orientation: \"x\" | \"y\", column?: number) {\n return function NamesTick(props: Record<string, unknown>) {\n const { x, y, payload, width, visibleTicksCount, className, fill, fontSize, fontFamily } = props as {\n x: number; y: number; payload?: { value?: unknown }; width?: number; visibleTicksCount?: number;\n className?: string; fill?: string; fontSize?: string | number; fontFamily?: string;\n };\n const name = String(payload?.value ?? \"\");\n const room = orientation === \"x\"\n ? (Number(width) || 0) / Math.max(1, Number(visibleTicksCount) || 1) - NAME_GAP\n : (column ?? (Number(width) || 0)) - NAME_COLUMN_INSET;\n const fit = fitLabel(name, room, measure);\n const text = { fill, fontSize, fontFamily, stroke: \"none\" };\n // upright: the first line's top at y (Recharts' verticalAnchor \"start\"); sideways: the lines centred on the row\n const firstDy = orientation === \"x\" ? 0.71 : 0.355 - ((fit.lines.length - 1) * LINE_EM) / 2;\n return (\n <g className={className} data-cut={fit.cut ? \"\" : undefined} data-lines={fit.lines.length}>\n <title>{name}</title>\n {fit.lines.map((line, i) => (\n <text key={i} x={x} y={y} dy={`${firstDy + i * LINE_EM}em`} textAnchor={orientation === \"x\" ? \"middle\" : \"end\"} {...text}>\n {line}\n </text>\n ))}\n </g>\n );\n };\n}\n\nexport type XAxisInterval = number | \"preserveStart\" | \"preserveEnd\" | \"preserveStartEnd\" | \"equidistantPreserveStart\";\n\nexport interface AxisMeasure {\n /** Text widths in the axis's resolved font, or null (no canvas: jsdom). */\n measure: Measure | null;\n /** The resolved axis font size, px. */\n px: number;\n /** One row of a row chart, px (--ds-chart-row as the page resolves it). */\n rowPx: number;\n /** The chart wrapper's width, px. */\n width: number;\n}\n\ntype FontSet = { ready: Promise<unknown>; addEventListener?: (t: string, f: () => void) => void; removeEventListener?: (t: string, f: () => void) => void };\n\n/**\n * The chart's measurer: the axis font read from the wrapper's probe (so `calc()` font tokens measure right), and the\n * wrapper's width. Re-read when the wrapper resizes and when web fonts land (the same font string then measures\n * differently, so the cache starts again).\n */\nexport function useAxisMeasure(ref: RefObject<HTMLDivElement | null>, enabled = true): AxisMeasure {\n const [state, setState] = useState<AxisMeasure>({ measure: null, px: 12, rowPx: 32, width: 0 });\n useLayoutEffect(() => {\n const el = ref.current;\n if (!enabled || !el) return;\n let live = true;\n let font = \"\";\n const update = (fresh = false) => {\n if (!live) return;\n const measured = el.clientWidth;\n const probe = el.querySelector<HTMLElement>(\"[data-chart-probe]\");\n const row = probe?.getBoundingClientRect().height ?? 0;\n const next = createAxisMeasurer(el);\n setState((prev) => {\n // no width is no layout (a hidden tab, or the moment headless Chrome takes a full-page screenshot): keep the last\n const width = measured > 0 ? measured : prev.width;\n const rowPx = row > 0 ? row : prev.rowPx;\n if (!next) return prev.width === width ? prev : { ...prev, width };\n if (!fresh && next.font === font && prev.measure && prev.width === width && prev.rowPx === rowPx) return prev;\n const keep = !fresh && next.font === font && prev.measure;\n font = next.font;\n return { measure: keep ? prev.measure : next.measure, px: next.px, rowPx, width };\n });\n };\n update(true);\n const ro = typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(() => update()) : null;\n ro?.observe(el);\n const fonts = (typeof document !== \"undefined\" ? (document as Document & { fonts?: FontSet }).fonts : undefined);\n const landed = () => update(true);\n fonts?.ready.then(landed, () => {});\n fonts?.addEventListener?.(\"loadingdone\", landed);\n return () => {\n live = false;\n ro?.disconnect();\n fonts?.removeEventListener?.(\"loadingdone\", landed);\n };\n }, [ref, enabled]);\n return state;\n}\n\n/** The value axis's width on an upright chart: its widest tick label, as the axis formats it (Sprint 25.17 A27). */\nexport function valueAxisWidth(values: number[], measure: Measure, format: (value: number) => string = String): number {\n const ticks = valueAxisTicks(values);\n if (!ticks.length) return Math.ceil(measure(format(0))) + 8;\n return Math.ceil(Math.max(...ticks.map((t) => measure(format(t))))) + 8;\n}\n\n/** How far the switch looks back before turning an automatic sideways chart upright again (no flip at the boundary). */\nconst SWITCH_HYSTERESIS = 32;\n\n/**\n * D8: an upright chart of names turns sideways when a name would be cut to fewer than six characters at the chart's\n * width, and back when there's room: it turns upright again only once names would also fit a little narrower, so a\n * scrollbar appearing does not flip it back. The last decision is kept as state (information from the previous render).\n */\nexport function useSidewaysSwitch(enabled: boolean, names: string[], m: AxisMeasure, axisWidth: number, sideMargins: number): boolean {\n const [turned, setTurned] = useState(false);\n const key = names.join(\"\\u0001\");\n const cut = useMemo(() => {\n if (!enabled || !m.measure || m.width <= 0 || names.length === 0) return { here: false, narrower: false };\n const cutAt = (width: number) => namesCutShort(names, (width - sideMargins - axisWidth) / names.length - NAME_GAP, m.measure!);\n return { here: cutAt(m.width), narrower: cutAt(m.width - SWITCH_HYSTERESIS) };\n // names are compared by value\n }, [enabled, key, m.measure, m.width, axisWidth, sideMargins]); // eslint-disable-line react-hooks/exhaustive-deps\n // sideways as soon as names are cut short here; upright only when they fit here and a little narrower (no flip-flop)\n const decision = turned ? cut.here || cut.narrower : cut.here;\n if (decision !== turned) setTurned(decision);\n return decision;\n}\n\n/** A sideways chart's name column: its widest name, at most a third of the chart's width. */\nexport function nameColumn(names: string[], m: AxisMeasure): number | undefined {\n if (!m.measure || m.width <= 0) return undefined;\n const widest = names.reduce((w, n) => Math.max(w, m.measure!(n.replace(/\\s+/g, \" \").trim())), 0);\n return Math.max(24, Math.min(Math.ceil(widest) + NAME_COLUMN_INSET, Math.floor(m.width / 3)));\n}\n\n/** How many names take two lines in a name column (each makes its row one line taller). */\nexport function twoLineNames(names: string[], column: number | undefined, m: AxisMeasure): number {\n if (!m.measure || column === undefined) return 0;\n return names.filter((n) => fitLabel(n, column - NAME_COLUMN_INSET, m.measure).lines.length > 1).length;\n}\n\n/** The widest label in the chart's own axis font (canvas measureText), or null where there is no canvas (jsdom). */\nfunction widestLabel(el: HTMLElement, labels: string[]): number | null {\n const measurer = createAxisMeasurer(el);\n if (!measurer) return null;\n return labels.reduce((w, l) => Math.max(w, measurer.measure(l)), 0);\n}\n\nconst TICK_GAP = 12; // the least space between two labels\nconst AXIS_RESERVE = 48; // the y-axis column and the chart's side margins\n\n/**\n * Sprint 25.4 C-11 (decision 7): the category ticks a chart shows. Recharts' preserveStartEnd thins colliding ticks\n * by its own measurement (without the chart's font) and keeps the last tick, so the labels fall unevenly (round 5:\n * 14 and 15 September missing). The chart measures its widest label with the resolved axis font, picks the step\n * that fits the axis width, and labels every step from the first category — the last only when it falls on the step.\n * Re-measured when the wrapper resizes and when the web fonts land. A numeric `override` (the chart's xAxisInterval\n * prop) is every Nth category and skips the measurement; the Recharts strings are treated as \"measured\" (round 13).\n *\n * Sprint 25.9, A3: this thinning is for dates and numbers only. A names axis (`kind` \"names\") is never thinned: every\n * name from the first render (interval 0, no explicit ticks, so duplicate names keep their own bands), each fitted to\n * its band by namesTick. The font is the axis font as the page resolves it (a probe), so `calc()` tokens measure right.\n */\nexport function useCategoryTicks(\n data: ReadonlyArray<Record<string, unknown>> | undefined,\n xAxisKey: string,\n ref: RefObject<HTMLDivElement | null>,\n override?: XAxisInterval,\n kind: CategoryKind = \"scale\",\n): { ticks?: string[]; interval: XAxisInterval; endMargin: number } {\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n const labelsKey = labels.join(\"\\u0001\");\n const [ticks, setTicks] = useState<string[] | undefined>(undefined);\n // Half the widest label: the chart's right margin, so the last label (centred on the last point) is not clipped.\n const [endMargin, setEndMargin] = useState(4);\n // Only a number is an override (every Nth category). The Recharts strings — \"preserveStartEnd\" and friends — are the\n // thinning this hook replaced (round 13: a builder passed the old default by name and got uneven labels again), so\n // they mean \"measured\" too.\n const numeric = typeof override === \"number\" ? override : undefined;\n const names = kind === \"names\";\n useEffect(() => {\n const el = ref.current;\n if (names || numeric !== undefined || !el || labels.length === 0) return;\n let live = true;\n const compute = () => {\n if (!live) return;\n // no width is no layout (a hidden tab, or the moment headless Chrome takes a full-page screenshot): keep the last\n if (el.clientWidth <= 0) return;\n const widest = widestLabel(el, labels);\n const plot = el.clientWidth - AXIS_RESERVE;\n if (widest == null || plot <= 0) { setTicks(undefined); return; }\n setEndMargin(Math.max(4, Math.ceil(widest / 2)));\n const fits = Math.max(1, Math.floor(plot / (widest + TICK_GAP)));\n const step = Math.ceil(labels.length / fits);\n // every k-th label from the first, explicitly — an explicit list keeps Recharts from thinning on its own\n // measurement even when every label fits (round 5: \"16 Sep\" dropped at full width)\n setTicks(labels.filter((_, i) => i % step === 0));\n };\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(compute);\n ro.observe(el);\n const fonts = (document as Document & { fonts?: { ready: Promise<unknown> } }).fonts;\n fonts?.ready.then(compute, () => {});\n return () => { live = false; ro.disconnect(); };\n // labels are compared by value\n }, [labelsKey, numeric, names, ref]); // eslint-disable-line react-hooks/exhaustive-deps\n if (names) return { interval: 0, endMargin: 4 };\n if (numeric !== undefined) return { interval: numeric, endMargin: 4 };\n return ticks ? { ticks, interval: 0, endMargin } : { interval: \"preserveStartEnd\", endMargin: 4 };\n}\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n BarChart as RechartsBarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Rectangle,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { categoryKind as guessCategoryKind } from \"../../lib/chart-categories\";\nimport {\n ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useRadius, xAxisTick, namesTick, useCategoryTicks,\n useAxisMeasure, useSidewaysSwitch, valueAxisWidth, nameColumn, twoLineNames, type XAxisInterval,\n} from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisExtent, axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, CHART_ROW, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { useHydrated } from \"../../lib/hydrated\";\n\nexport interface BarDef {\n dataKey: string;\n label?: string;\n soft?: boolean;\n /**\n * Bars with the same stackId stack into one column (Sprint 25.7, C4); a bar without one stands alone. BarChart's\n * `stacked` puts every bar without a stackId into one stack. The same field works in CompositeChart, where lines\n * draw over the stacks.\n */\n stackId?: string;\n}\n\n/** The stack a bar joins: its own stackId, else the one `stacked` makes for every bar. */\nexport function barStackOf(bar: BarDef, stacked: boolean): string | undefined {\n return bar.stackId ?? (stacked ? \"stack\" : undefined);\n}\n\n/** Some bar stacks. Its chart then stacks both ways from zero (stackOffset \"sign\"), so a negative series sits below it. */\nexport function anyStack(bars: BarDef[], stacked: boolean): boolean {\n return bars.some((bar) => barStackOf(bar, stacked) != null);\n}\n\n/** How many bars stand side by side in one category: one per stack, one per bar on its own. */\nexport function barGroups(bars: BarDef[], stacked: boolean): number {\n return Math.max(1, new Set(bars.map((bar, i) => barStackOf(bar, stacked) ?? `\\u0000${i}`)).size);\n}\n\n/**\n * The bar's shape: only the end segment of each stack is rounded, per column and per side of zero — the top of the\n * positive side, the bottom of the negative one — so a stack whose last series is zero in a column rounds the segment\n * that ends it there. A bar on its own rounds its end.\n */\nexport function barShape(bars: BarDef[], index: number, stacked: boolean, radius: number, horizontal = false) {\n const round: [number, number, number, number] = horizontal ? [0, radius, radius, 0] : [radius, radius, 0, 0];\n const square: [number, number, number, number] = [0, 0, 0, 0];\n const stack = barStackOf(bars[index], stacked);\n const above = stack == null ? [] : bars.filter((b, j) => j > index && barStackOf(b, stacked) === stack);\n // Recharts hands the shape the bar's geometry and its row of data; it draws a negative bar's rounded corners at its\n // far end itself\n const Shape = (props: unknown) => {\n const p = props as { payload?: Record<string, unknown> };\n const row = p.payload ?? {};\n const down = Number(row[bars[index].dataKey]) < 0;\n const onTop = above.every((b) => {\n const value = Number(row[b.dataKey]);\n return !(down ? value < 0 : value > 0);\n });\n return <Rectangle {...(props as object)} radius={onTop ? round : square} />;\n };\n return Shape;\n}\n\n/** The values the value axis must reach: each bar on its own, and each stack up and down from zero (axisExtent). */\nfunction valueExtent(data: Record<string, unknown>[], bars: BarDef[], stacked: boolean): number[] {\n return axisExtent(data, bars.map((bar) => ({ dataKey: bar.dataKey, stack: barStackOf(bar, stacked) ?? null })));\n}\n\n/** A title line's height, px, in the axis font. */\nconst titleLine = (px: number) => Math.ceil(px * 1.5) + 4;\n/** The same in CSS, for a row chart's height. */\nconst TITLE_LINE_CSS = \"calc(1.5 * var(--ds-font-size-xs) + 4px)\";\n\nexport interface BarChartProps {\n /**\n * Which category ticks show on an axis of dates or numbers. Leave it out: the chart measures its widest label with\n * the chart's font and labels every k-th category from the first, the last only when it falls on the step (Sprint\n * 25.4 C-11, decision 7). A number labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are\n * accepted for compatibility and mean the same measured labelling (round 13). A names axis is never thinned.\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n bars: BarDef[];\n xAxisKey: string;\n /**\n * \"auto\" (the default): the chart sizes itself — sideways, a row per category; upright, two wide to one high. A\n * preset or a number overrides it; inside a ChartContainer, the container's own height wins.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** Every bar without a stackId joins one stack. */\n stacked?: boolean;\n /**\n * Bars running sideways, one row per category. Leave it out: an upright chart of names turns itself sideways when a\n * name would be cut to fewer than six characters, and back when there's room (D8). true or false forces either.\n */\n horizontal?: boolean;\n /**\n * What the categories are. \"names\" are never skipped: each wraps onto two lines, then ends with \"…\", with the full\n * name on hover. \"scale\" (dates, times, numbers) is labelled at an even step. Leave it out: guessed from the labels.\n */\n categoryKind?: \"names\" | \"scale\";\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n /** The category axis's title, as drawn upright (below it). A sideways chart puts the category title above its names. */\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const BarChart = markChart(forwardRef<HTMLDivElement, BarChartProps>(function BarChart({\n data,\n bars,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n horizontal,\n categoryKind,\n showGrid = true,\n showTooltip = true,\n showLegend,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n // its labels' kind: by the server's locale while a server-rendered page hydrates (both sides alike), by the browser's\n // languages from then on, as before 0.27.0 (the review: a German browser's month names on an English page)\n const hydrated = useHydrated();\n const kind = categoryKind ?? guessCategoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? undefined : locale);\n const names = kind === \"names\";\n const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);\n const values = useMemo(() => valueExtent(data ?? [], bars, stacked), [data, bars, stacked]);\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n const axisWidth = useMemo(\n () => (measured.measure ? valueAxisWidth(values, measured.measure, tickFormat) : 0),\n [measured.measure, values, tickFormat],\n );\n const turned = useSidewaysSwitch(horizontal === undefined && names, labels, measured, axisWidth, 8);\n const sideways = horizontal ?? turned;\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways || names ? \"names\" : \"scale\");\n const column = sideways ? nameColumn(labels, measured) : undefined;\n const upright = useMemo(() => namesTick(measured.measure, \"x\"), [measured.measure]);\n const rows = useMemo(() => namesTick(measured.measure, \"y\", column), [measured.measure, column]);\n const solidColors = useChartColors(bars.length, false);\n const softColors = useChartColors(bars.length, true);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const legendVisible = showLegend ?? bars.length >= 2;\n\n // Axis titles follow their data: a chart that turned itself sideways moves the value title under the value axis and\n // the category title above the names. Every title is horizontal (Analysis Function; data_visualisation#22).\n const valueTitle = horizontal === true ? xAxisLabel : yAxisLabel;\n const categoryTitle = horizontal === true ? yAxisLabel : xAxisLabel;\n const topTitle = sideways ? categoryTitle : valueTitle;\n const bottomTitle = sideways ? valueTitle : categoryTitle;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const bottomLabel = bottomTitle ? { value: bottomTitle, position: \"insideBottom\" as const, offset: -2, style: axisLabelStyle } : undefined;\n\n const groups = barGroups(bars, stacked);\n const perCategory = 1 + 0.5 * (groups - 1);\n const titles = [topTitle, bottomTitle].filter(Boolean).length;\n const size = sideways\n ? {\n model: \"rows\" as const,\n units: labels.length * perCategory,\n lines: twoLineNames(labels, column, measured),\n axis: titles ? `calc(${CHART_ROW} + ${titles} * ${TITLE_LINE_CSS})` : CHART_ROW,\n }\n : { model: \"ratio\" as const };\n // bars keep their thickness when the chart grows in a row: the rows spread instead\n const maxBarSize = sideways ? Math.max(4, Math.round((measured.rowPx * perCategory * 0.7) / groups)) : undefined;\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={size}\n chart=\"bar\"\n categoryKind={kind}\n categories={data.length}\n categoryAxis={sideways ? \"y\" : \"x\"}\n sideways={sideways}\n axisTitle={topTitle}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsBarChart\n data={data}\n layout={sideways ? \"vertical\" : \"horizontal\"}\n stackOffset={anyStack(bars, stacked) ? \"sign\" : undefined}\n // names are fitted to their bands, so nothing hangs past the last bar: 4 px, not a margin sized from them\n margin={{ top: 4 + (topTitle ? titleLine(measured.px) : 0), right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} vertical={!sideways} horizontal />\n )}\n {sideways ? (\n <>\n <XAxis type=\"number\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" label={bottomLabel} tickFormatter={tickFormat} />\n <YAxis\n dataKey={xAxisKey}\n type=\"category\"\n width={column ?? \"auto\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n interval={0}\n tick={rows}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={names ? upright : xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={bottomLabel}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n </>\n )}\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={{ fill: \"var(--ds-bg-muted)\", opacity: 0.5 }} />}\n {legendVisible && <ChartLegend order={bars.map((b) => b.dataKey)} />}\n {bars.map((bar, i) => (\n <Bar\n key={bar.dataKey}\n dataKey={bar.dataKey}\n name={bar.label ?? bar.dataKey}\n fill={bar.soft ? softColors[i] : solidColors[i]}\n // a soft fill is a 30% tint: the solid outline keeps the bar's edge at the colour's own contrast (WCAG 1.4.11)\n stroke={bar.soft ? solidColors[i] : undefined}\n strokeWidth={bar.soft ? 1 : undefined}\n shape={barShape(bars, i, stacked, radius, sideways)}\n stackId={barStackOf(bar, stacked)}\n maxBarSize={maxBarSize}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsBarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n LineChart as RechartsLineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, xAxisTick, useCategoryTicks, useAxisMeasure, type XAxisInterval } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface LineDef {\n dataKey: string;\n label?: string;\n dashed?: boolean;\n}\n\nexport interface LineChartProps {\n /**\n * Which category ticks show. Leave it out: the chart measures its widest label with the chart's font and labels every\n * k-th category from the first, the last only when it falls on the step (Sprint 25.4 C-11, decision 7). A number\n * labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are accepted for compatibility and\n * mean the same measured labelling — they never hand the ticks back to Recharts' thinning (round 13).\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n lines: LineDef[];\n xAxisKey: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n curved?: boolean;\n showDots?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const LineChart = markChart(forwardRef<HTMLDivElement, LineChartProps>(function LineChart({\n data,\n lines,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n curved = true,\n showDots = false,\n showGrid = true,\n showTooltip = true,\n showLegend,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const values = useMemo(() => seriesValues(data ?? [], lines.map((s) => s.dataKey), false), [data, lines]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // a line runs over a scale (dates, times, numbers): its labels are thinned at an even step, never fitted as names\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, \"scale\");\n const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);\n const colors = useChartColors(lines.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? lines.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"line\"\n categoryKind=\"scale\"\n categories={data.length}\n categoryAxis=\"x\"\n axisTitle={yAxisLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsLineChart data={data} margin={{ top, right: xTicks.endMargin, bottom: 4, left: 4 }} accessibilityLayer>\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={xAxisLabel ? { value: xAxisLabel, position: \"insideBottom\", offset: -2, style: axisLabelStyle } : undefined}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={lines.map((l) => l.dataKey)} />}\n {lines.map((line, i) => (\n <Line\n key={line.dataKey}\n type={curved ? \"monotone\" : \"linear\"}\n dataKey={line.dataKey}\n name={line.label ?? line.dataKey}\n stroke={colors[i]}\n strokeWidth={2}\n strokeDasharray={line.dashed ? \"5 5\" : undefined}\n dot={showDots}\n activeDot={{ r: 5, strokeWidth: 2 }}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsLineChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId, useMemo, useRef, type Ref } from \"react\";\nimport {\n AreaChart as RechartsAreaChart,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, xAxisTick, useCategoryTicks, useAxisMeasure, type XAxisInterval } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface AreaDef {\n dataKey: string;\n label?: string;\n}\n\nexport interface AreaChartProps {\n /**\n * Which category ticks show. Leave it out: the chart measures its widest label with the chart's font and labels every\n * k-th category from the first, the last only when it falls on the step (Sprint 25.4 C-11, decision 7). A number\n * labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are accepted for compatibility and\n * mean the same measured labelling — they never hand the ticks back to Recharts' thinning (round 13).\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n areas: AreaDef[];\n xAxisKey: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n stacked?: boolean;\n curved?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n gradient?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const AreaChart = markChart(forwardRef<HTMLDivElement, AreaChartProps>(function AreaChart({\n data,\n areas,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n curved = true,\n showGrid = true,\n showTooltip = true,\n showLegend,\n gradient = true,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const values = useMemo(() => seriesValues(data ?? [], areas.map((s) => s.dataKey), stacked), [data, areas, stacked]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // an area runs over a scale (dates, times, numbers): its labels are thinned at an even step, never fitted as names\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, \"scale\");\n const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);\n const instanceId = useId();\n const solidColors = useChartColors(areas.length, false);\n const softColors = useChartColors(areas.length, true);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? areas.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"area\"\n categoryKind=\"scale\"\n categories={data.length}\n categoryAxis=\"x\"\n axisTitle={yAxisLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsAreaChart data={data} margin={{ top, right: xTicks.endMargin, bottom: 4, left: 4 }} accessibilityLayer>\n <defs>\n {areas.map((area, i) => (\n <linearGradient key={area.dataKey} id={`gradient-${instanceId}-${area.dataKey}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={softColors[i]} stopOpacity={1} />\n <stop offset=\"95%\" stopColor={softColors[i]} stopOpacity={0.1} />\n </linearGradient>\n ))}\n </defs>\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={xAxisLabel ? { value: xAxisLabel, position: \"insideBottom\", offset: -2, style: axisLabelStyle } : undefined}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={areas.map((a) => a.dataKey)} />}\n {areas.map((area, i) => (\n <Area\n key={area.dataKey}\n type={curved ? \"monotone\" : \"linear\"}\n dataKey={area.dataKey}\n name={area.label ?? area.dataKey}\n stroke={solidColors[i]}\n strokeWidth={2}\n fill={gradient ? `url(#gradient-${instanceId}-${area.dataKey})` : softColors[i]}\n stackId={stacked ? \"stack\" : undefined}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsAreaChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n PieChart as RechartsPieChart,\n Pie,\n Cell,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface PieChartProps {\n data: { name: string; value: number; [key: string]: unknown }[];\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n donut?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n showLabels?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const PieChart = markChart(forwardRef<HTMLDivElement, PieChartProps>(function PieChart({\n data,\n height = \"auto\",\n donut = false,\n showTooltip = true,\n showLegend = true,\n showLabels = false,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n const renderLabel = showLabels\n ? ({ percent }: { percent?: number }) => `${((percent ?? 0) * 100).toFixed(0)}%`\n : false;\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"pie\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsPieChart accessibilityLayer>\n <Pie\n data={data}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n outerRadius=\"75%\"\n innerRadius={donut ? \"55%\" : 0}\n label={renderLabel}\n labelLine={showLabels}\n isAnimationActive={isAnimated}\n fontSize=\"var(--ds-font-size-xs)\"\n fontFamily=\"var(--ds-font-sans)\"\n >\n {data.map((_, i) => (\n <Cell key={i} fill={colors[i % colors.length]} />\n ))}\n </Pie>\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={data.map((d) => d.name)} by=\"value\" />}\n </RechartsPieChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n ComposedChart,\n Bar,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { categoryKind as guessCategoryKind } from \"../../lib/chart-categories\";\nimport {\n ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useRadius, xAxisTick, namesTick, useCategoryTicks,\n useAxisMeasure, useSidewaysSwitch, valueAxisWidth, nameColumn, twoLineNames, type XAxisInterval,\n} from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisExtent, axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, CHART_ROW, markChart } from \"./ChartWrapper\";\nimport { anyStack, barGroups, barShape, barStackOf, type BarDef } from \"./BarChart\";\nimport type { LineDef } from \"./LineChart\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { useHydrated } from \"../../lib/hydrated\";\n\nexport interface CompositeChartProps {\n /**\n * Which category ticks show on an axis of dates or numbers. Leave it out: the chart measures its widest label with\n * the chart's font and labels every k-th category from the first, the last only when it falls on the step (Sprint\n * 25.4 C-11, decision 7). A number labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are\n * accepted for compatibility and mean the same measured labelling (round 13). A names axis is never thinned.\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n bars: BarDef[];\n lines: LineDef[];\n xAxisKey: string;\n /**\n * \"auto\" (the default): two wide to one high; sideways, a row per category. A preset or a number overrides it; a\n * ChartContainer's own height wins.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** Every bar without a stackId joins one stack; lines draw over it (Sprint 25.7, C4). A bar's stackId works too. */\n stacked?: boolean;\n /**\n * The lines on a second axis of their own, on the right, for a line whose unit differs from the bars'. Default: true\n * for bars side by side, false once the bars stack (`stacked` or a bar's stackId), so a capacity or a target line\n * reads against the stack's own scale. An explicit value wins.\n */\n dualAxis?: boolean;\n /**\n * What the categories are. \"names\" are never skipped: each wraps onto two lines, then ends with \"…\", with the full\n * name on hover. \"scale\" (dates, times, numbers) is labelled at an even step. Leave it out: guessed from the labels.\n */\n categoryKind?: \"names\" | \"scale\";\n /**\n * Bars running sideways, one row per category, with the lines crossing the rows. Leave it out: a chart of names turns\n * itself sideways when a name would be cut to fewer than six characters, and back when there's room (D8). true or\n * false forces either.\n */\n horizontal?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the bars' values read (and the lines', on one axis): \"number\" (the default) is compact on the axis, in the\n * page's language (1M, 750K), and in full in the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function\n * formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n /** How the lines' values read on their own axis (dualAxis), when their unit differs from the bars'. Default: valueFormat. */\n lineValueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const CompositeChart = markChart(forwardRef<HTMLDivElement, CompositeChartProps>(function CompositeChart({\n data,\n bars,\n lines,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n dualAxis = !anyStack(bars, stacked),\n categoryKind,\n horizontal,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n lineValueFormat = valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n // its labels' kind as BarChart reads it: the server's locale while hydrating, the browser's languages from then on\n const hydrated = useHydrated();\n const kind = categoryKind ?? guessCategoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? undefined : locale);\n const names = kind === \"names\";\n const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);\n // the bars' axis (and the lines', on one axis), and the lines' own on the right with a second axis\n const [values, lineValues] = useMemo(() => {\n // the bars' stacks up and down from zero, as BarChart reads them (axisExtent), and the lines on the same axis unless\n // they have their own\n const values = axisExtent(data ?? [], [\n ...bars.map((bar) => ({ dataKey: bar.dataKey, stack: barStackOf(bar, stacked) ?? null })),\n ...(dualAxis ? [] : lines.map((l) => ({ dataKey: l.dataKey, stack: null }))),\n ]);\n const lineValues = (data ?? []).flatMap((row) => lines.map((l) => Number(row[l.dataKey])));\n return [values, lineValues];\n }, [data, bars, lines, stacked, dualAxis]);\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const lineTickFormat = useMemo(() => axisTickFormatter(lineValues, lineValueFormat, locale), [lineValues, lineValueFormat, locale]);\n const fullFormat = useMemo(() => {\n const bar = fullValueFormatter(valueFormat, locale);\n const line = fullValueFormatter(dualAxis ? lineValueFormat : valueFormat, locale);\n const lineKeys = new Set(lines.map((l) => l.dataKey));\n return (value: number, dataKey?: string) => (dataKey && lineKeys.has(dataKey) ? line(value) : bar(value));\n }, [valueFormat, lineValueFormat, dualAxis, lines, locale]);\n // the bars' axis sets the left column's width; with a second axis the lines' ticks take the right edge\n const axisWidth = useMemo(() => {\n if (!measured.measure) return 0;\n return valueAxisWidth(values, measured.measure, tickFormat) + (dualAxis ? valueAxisWidth(lineValues, measured.measure, lineTickFormat) : 0);\n }, [measured.measure, values, lineValues, tickFormat, lineTickFormat, dualAxis]);\n const turned = useSidewaysSwitch(horizontal === undefined && names, labels, measured, axisWidth, 8);\n const sideways = horizontal ?? turned;\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways ? \"names\" : kind);\n const column = sideways ? nameColumn(labels, measured) : undefined;\n const tick = useMemo(() => (names ? namesTick(measured.measure, \"x\") : xAxisTick), [names, measured.measure]);\n const rows = useMemo(() => namesTick(measured.measure, \"y\", column), [measured.measure, column]);\n const barSoftColors = useChartColors(bars.length, true);\n const barSolidColors = useChartColors(bars.length, false);\n const lineColors = useChartColors(lines.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n // axis titles follow their data: sideways, the value title goes under the value axis, the category title above the names\n const topTitle = sideways ? xAxisLabel : yAxisLabel;\n const bottomTitle = sideways ? yAxisLabel : xAxisLabel;\n const bottomLabel = bottomTitle ? { value: bottomTitle, position: \"insideBottom\" as const, offset: -2, style: axisLabelStyle } : undefined;\n const top = 4 + (topTitle ? Math.ceil(measured.px * 1.5) + 4 : 0);\n const groups = barGroups(bars, stacked);\n const perCategory = 1 + 0.5 * (groups - 1);\n const titles = [topTitle, bottomTitle].filter(Boolean).length + (sideways && dualAxis ? 1 : 0);\n const size = sideways\n ? {\n model: \"rows\" as const,\n units: labels.length * perCategory,\n lines: twoLineNames(labels, column, measured),\n axis: titles ? `calc(${CHART_ROW} + ${titles} * calc(1.5 * var(--ds-font-size-xs) + 4px))` : CHART_ROW,\n }\n : { model: \"ratio\" as const };\n const maxBarSize = sideways ? Math.max(4, Math.round((measured.rowPx * perCategory * 0.7) / groups)) : undefined;\n // the bars read against the left (or bottom) axis; the lines against their own when dualAxis\n const barAxis = sideways ? { xAxisId: \"left\" } : { yAxisId: \"left\" };\n const lineAxis = sideways ? { xAxisId: dualAxis ? \"right\" : \"left\" } : { yAxisId: dualAxis ? \"right\" : \"left\" };\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={size}\n chart=\"composite\"\n categoryKind={kind}\n categories={data.length}\n categoryAxis={sideways ? \"y\" : \"x\"}\n sideways={sideways}\n axisTitle={topTitle}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart\n data={data}\n layout={sideways ? \"vertical\" : \"horizontal\"}\n stackOffset={anyStack(bars, stacked) ? \"sign\" : undefined}\n // names are fitted to their bands, so nothing hangs past the last bar\n margin={{ top, right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} vertical={!sideways} horizontal />}\n {sideways ? (\n <>\n <XAxis xAxisId=\"left\" type=\"number\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" label={bottomLabel} tickFormatter={tickFormat} />\n {dualAxis && <XAxis xAxisId=\"right\" type=\"number\" orientation=\"top\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" tickFormatter={lineTickFormat} />}\n <YAxis\n dataKey={xAxisKey}\n type=\"category\"\n width={column ?? \"auto\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n interval={0}\n tick={rows}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={tick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={bottomLabel}\n />\n <YAxis yAxisId=\"left\" width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {dualAxis && (\n <YAxis yAxisId=\"right\" orientation=\"right\" width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={lineTickFormat} />\n )}\n </>\n )}\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={[...bars.map((b) => b.dataKey), ...lines.map((l) => l.dataKey)]} />}\n {bars.map((bar, i) => (\n <Bar\n key={bar.dataKey}\n dataKey={bar.dataKey}\n name={bar.label ?? bar.dataKey}\n fill={barSoftColors[i]}\n // the soft fill is a 30% tint (1.3–1.4:1 on a dark card, Sprint 25.7 C4): the solid outline keeps the bar's\n // edge at the colour's own contrast against the card (WCAG 1.4.11), and separates stacked segments\n stroke={barSolidColors[i]}\n strokeWidth={1}\n shape={barShape(bars, i, stacked, radius, sideways)}\n stackId={barStackOf(bar, stacked)}\n maxBarSize={maxBarSize}\n {...barAxis}\n isAnimationActive={isAnimated}\n />\n ))}\n {lines.map((line, i) => (\n <Line\n key={line.dataKey}\n type=\"monotone\"\n dataKey={line.dataKey}\n name={line.label ?? line.dataKey}\n stroke={lineColors[i]}\n strokeWidth={2}\n strokeDasharray={line.dashed ? \"5 5\" : undefined}\n dot={false}\n {...lineAxis}\n isAnimationActive={isAnimated}\n />\n ))}\n </ComposedChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n ScatterChart as RechartsScatterChart,\n Scatter,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n ZAxis,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useAxisMeasure } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface ScatterSeries {\n name: string;\n points: { x: number; y: number; z?: number }[];\n}\n\nexport interface ScatterChartProps {\n data: ScatterSeries[];\n xLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yLabel?: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n /**\n * How the y values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n /** How the x values read, as valueFormat. Default \"number\". */\n xValueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const ScatterChart = markChart(forwardRef<HTMLDivElement, ScatterChartProps>(function ScatterChart({\n data,\n xLabel,\n yLabel,\n height = \"auto\",\n showGrid = true,\n showTooltip = true,\n showLegend,\n valueFormat,\n xValueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const [xTickFormat, yTickFormat, fullFormat] = useMemo(() => {\n const points = (data ?? []).flatMap((s) => s.points);\n const x = fullValueFormatter(xValueFormat, locale);\n const y = fullValueFormatter(valueFormat, locale);\n return [\n axisTickFormatter(points.map((p) => p.x), xValueFormat, locale),\n axisTickFormatter(points.map((p) => p.y), valueFormat, locale),\n (value: number, dataKey?: string) => (dataKey === \"x\" ? x(value) : dataKey === \"y\" ? y(value) : value.toLocaleString(locale)),\n ];\n }, [data, valueFormat, xValueFormat, locale]);\n const measured = useAxisMeasure(wrapperRef, !!yLabel && (data?.length ?? 0) > 0);\n const colors = useChartColors(data.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? data.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"scatter\"\n axisTitle={yLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsScatterChart\n margin={{ top: 8 + (yLabel ? Math.ceil(measured.px * 1.5) + 4 : 0), right: 8, bottom: xLabel ? 20 : 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n type=\"number\"\n dataKey=\"x\"\n name={xLabel ?? \"x\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tickFormatter={xTickFormat}\n label={xLabel ? { value: xLabel, position: \"bottom\", offset: 0, style: { ...axisLabelStyle, textAnchor: \"middle\" } } : undefined}\n />\n <YAxis\n type=\"number\"\n dataKey=\"y\"\n name={yLabel ?? \"y\"}\n width=\"auto\"\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tickFormatter={yTickFormat}\n />\n <ZAxis type=\"number\" dataKey=\"z\" range={[40, 400]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={data.map((s) => s.name)} by=\"value\" />}\n {data.map((series, i) => (\n <Scatter\n key={series.name}\n name={series.name}\n data={series.points}\n fill={colors[i]}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsScatterChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo } from \"react\";\nimport {\n RadarChart as RechartsRadarChart,\n Radar,\n PolarGrid,\n PolarAngleAxis,\n PolarRadiusAxis,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface RadarDataKey {\n key: string;\n label?: string;\n}\n\nexport interface RadarChartProps {\n data: Record<string, unknown>[];\n dataKeys: RadarDataKey[];\n axisKey: string;\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n filled?: boolean;\n showDots?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n animated?: boolean;\n /** How the values read on the rings and in the tooltip; see ValueFormat (compact numbers by default). */\n valueFormat?: ValueFormat;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const RadarChart = markChart(forwardRef<HTMLDivElement, RadarChartProps>(function RadarChart({\n data,\n dataKeys,\n axisKey,\n height = \"auto\",\n filled = true,\n showDots = true,\n showTooltip = true,\n showLegend,\n animated,\n valueFormat = \"number\",\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const solidColors = useChartColors(dataKeys.length, false);\n const softColors = useChartColors(dataKeys.length, true);\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? dataKeys.length >= 2;\n // the rings are a value axis: compact in the page's language, the tooltip in full (Sprint 25.17's review)\n const values = useMemo(() => seriesValues(data ?? [], dataKeys.map((dk) => dk.key)), [data, dataKeys]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"radar\" className={className} aria-label={ariaLabel} formatValue={fullFormat}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadarChart data={data} cx=\"50%\" cy=\"50%\" outerRadius=\"75%\" accessibilityLayer>\n <PolarGrid stroke=\"var(--ds-border-subtle)\" />\n <PolarAngleAxis\n dataKey={axisKey}\n tick={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: \"var(--ds-text-muted)\" }}\n />\n <PolarRadiusAxis\n tick={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: \"var(--ds-text-muted)\" }}\n tickFormatter={tickFormat}\n axisLine={false}\n />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={dataKeys.map((dk) => dk.key)} />}\n {dataKeys.map((dk, i) => (\n <Radar\n key={dk.key}\n name={dk.label ?? dk.key}\n dataKey={dk.key}\n stroke={solidColors[i]}\n fill={filled ? softColors[i] : \"transparent\"}\n strokeWidth={2}\n dot={showDots ? { r: 3, fill: solidColors[i] } : false}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsRadarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n RadialBarChart as RechartsRadialBarChart,\n RadialBar,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface RadialBarChartProps {\n data: { name: string; value: number; max?: number; [key: string]: unknown }[];\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n showLegend?: boolean;\n showLabels?: boolean;\n startAngle?: number;\n endAngle?: number;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const RadialBarChart = markChart(forwardRef<HTMLDivElement, RadialBarChartProps>(function RadialBarChart({\n data,\n height = \"auto\",\n showTooltip = true,\n showLegend = true,\n showLabels = false,\n startAngle = 90,\n endAngle = -270,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n const chartData = data.map((d, i) => ({\n ...d,\n fill: colors[i % colors.length],\n }));\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"radial-bar\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadialBarChart\n data={chartData}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius=\"20%\"\n outerRadius=\"90%\"\n startAngle={startAngle}\n endAngle={endAngle}\n accessibilityLayer\n >\n <RadialBar\n dataKey=\"value\"\n background={{ fill: \"var(--ds-bg-muted)\" }}\n label={showLabels ? { position: \"insideStart\", fill: \"var(--ds-text-primary)\", fontSize: \"var(--ds-font-size-xs)\" } : false}\n isAnimationActive={isAnimated}\n />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={data.map((d) => d.name)} by=\"value\" />}\n </RechartsRadialBarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n FunnelChart as RechartsFunnelChart,\n Funnel,\n Tooltip,\n LabelList,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\n/** A funnel stage takes a taller row than a sideways bar (Sprint 25.9, A2). */\nconst STAGE_ROWS = 1.5;\n\nexport interface FunnelChartProps {\n data: { name: string; value: number; [key: string]: unknown }[];\n /** \"auto\" (the default): a row per stage. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n /** Kept for compatibility: a funnel has no legend, its labels name the stages (Recharts gives it no legend entries). */\n showLegend?: boolean;\n showLabels?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const FunnelChart = markChart(forwardRef<HTMLDivElement, FunnelChartProps>(function FunnelChart({\n data,\n height = \"auto\",\n showTooltip = true,\n showLabels = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n const chartData = data.map((d, i) => ({\n ...d,\n fill: colors[i % colors.length],\n }));\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"rows\", units: data.length * STAGE_ROWS, axis: \"16px\" }} chart=\"funnel\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsFunnelChart accessibilityLayer>\n <Funnel dataKey=\"value\" data={chartData} isAnimationActive={isAnimated}>\n {showLabels && (\n <LabelList\n dataKey=\"name\"\n position=\"right\"\n fill=\"var(--ds-text-primary)\"\n fontSize=\"var(--ds-font-size-sm)\"\n fontFamily=\"var(--ds-font-sans)\"\n />\n )}\n </Funnel>\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </RechartsFunnelChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","// showcase/src/lib/token-algorithms.ts\n// The one source for all token generation helpers. The platform imports it through\n// platform/src/lib/token-algorithms.ts, a re-export (Sprint 25.7 review, 26 September 2026: no more synced copy).\n\nexport type HoverEffect = 'scale' | 'lift' | 'scale-lift'\n\nfunction hasScaleEffect(effect: HoverEffect): boolean {\n return effect === 'scale' || effect === 'scale-lift'\n}\n\nfunction hasLiftEffect(effect: HoverEffect): boolean {\n return effect === 'lift' || effect === 'scale-lift'\n}\n\nexport interface GradientConfig {\n accentMode: 'solid' | 'gradient'\n endHue: number\n angle: number\n hue: number\n sat: number\n endSat?: number\n endShade?: number\n}\n\nexport interface InteractiveHoverConfig {\n enabled: boolean\n effect: HoverEffect\n speed: number\n ease: string\n scale: number\n lift: number\n pressDepth: number\n}\n\nexport interface AmbientHoverConfig {\n enabled: boolean\n effect: HoverEffect\n speed: number\n ease: string\n scale: number\n lift: number\n}\n\nexport interface MotionDecisions {\n speed: number\n ease: string\n intensity?: 'none' | 'subtle' | 'moderate' | 'expressive'\n interactive?: InteractiveHoverConfig\n ambient?: AmbientHoverConfig\n}\n\n// ---------------------------------------------------------------------------\n// On-fill text (Sprint 20.10)\n// ---------------------------------------------------------------------------\n//\n// The colour of text and icons on a solid fill is decided by contrast, not by\n// preset: white when white reaches WCAG AA (4.5:1) over the fill, otherwise\n// the theme's darkest neutral. One function, `onFillText`, decides for every\n// fill the theme emits — the page accent (`--ds-text-on-primary`), the\n// independent sidebar and header accents, the three status fills and the five\n// palette bold fills — and nothing else decides on-fill colour.\n//\n// The decision uses a real conversion (OKLCH → OKLab → linear sRGB → relative\n// luminance) of the fill as the browser draws it: a colour outside sRGB has\n// each channel clipped, which is what Chrome renders (measured, Sprint 25.7\n// Part D; see oklchToLinearSrgbClamped) — not the chroma reduction CSS Color 4\n// describes, which this used until then. The status palettes are literal\n// OKLCH values at arbitrary lightness, and saturated fills near the gamut\n// edge render lighter than their mapped colour. `estimateContrastRatio` below\n// keeps its L³ proxy for the palette pair code that has always used it.\n\nexport interface Oklch { L: number; C: number; H: number }\n\n/**\n * The --ds-primary-{shade} scale from roots.css: lightness and the chroma\n * multiplier applied to --ds-sat-primary. The one table every literal accent\n * colour (gradient start and end, independent sidebar and header accents) is\n * computed from, so a flip at a given shade is the same flip everywhere.\n * A test pins it against the CSS.\n */\nexport const PRIMARY_SCALE: Record<number, { L: number; c: number }> = {\n 300: { L: 0.77, c: 0.150 },\n 400: { L: 0.66, c: 0.180 },\n 500: { L: 0.55, c: 0.200 },\n 600: { L: 0.47, c: 0.185 },\n 700: { L: 0.40, c: 0.165 },\n 800: { L: 0.33, c: 0.135 },\n 900: { L: 0.25, c: 0.100 },\n}\n\n/** Nearest step of the scale; a missing or malformed shade reads as 500 rather than throwing (stored decisions are read raw). */\nfunction scaleShade(shade: number): number {\n if (!Number.isFinite(shade)) return 500\n const s = Math.max(300, Math.min(900, shade))\n return Math.round(s / 100) * 100\n}\n\n/** The literal OKLCH of --ds-primary-{shade} at a saturation and hue. */\nexport function accentColour(shade: number, sat: number, hue: number): Oklch {\n const { L, c } = PRIMARY_SCALE[scaleShade(shade)]\n return { L, C: c * sat, H: hue }\n}\n\n/** Formats an OKLCH colour the way the emitters always have (L to 3 places, C to 4). */\nexport function oklchCss(colour: Oklch): string {\n return `oklch(${colour.L.toFixed(3)} ${colour.C.toFixed(4)} ${colour.H})`\n}\n\n/** Parses an `oklch(L C H)` literal (optional `/ alpha`). Returns null for anything else, including var() references. */\nexport function parseOklch(value: string): Oklch | null {\n const m = value.trim().match(/^oklch\\(\\s*([\\d.]+)(%?)\\s+([\\d.]+)\\s+([\\d.]+)(?:deg)?\\s*(?:\\/\\s*[\\d.%]+\\s*)?\\)$/i)\n if (!m) return null\n const L = m[2] ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n return { L, C: parseFloat(m[3]), H: parseFloat(m[4]) }\n}\n\nfunction oklchToLinearSrgb({ L, C, H }: Oklch): [number, number, number] {\n const h = (H * Math.PI) / 180\n const a = C * Math.cos(h)\n const b = C * Math.sin(h)\n const l_ = L + 0.3963377774 * a + 0.2158037573 * b\n const m_ = L - 0.1055613458 * a - 0.0638541728 * b\n const s_ = L - 0.0894841775 * a - 1.2914855480 * b\n const l = l_ * l_ * l_\n const m = m_ * m_ * m_\n const s = s_ * s_ * s_\n return [\n +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s,\n ]\n}\n\n/**\n * WCAG relative luminance of an OKLCH colour as the browser draws it: each\n * channel clipped to sRGB (oklchToLinearSrgbClamped) and rounded to the\n * nearest of the 256 steps an 8-bit sRGB surface has, then weighted. Contrast\n * decisions use the range Chrome's rounding can land in (luminanceRange); this\n * is its nearest value.\n */\nexport function oklchToLuminance(colour: Oklch): number {\n return srgbLuminance(oklchToSrgb(colour).map((v) => Math.round(v * 255) / 255) as [number, number, number])\n}\n\n/**\n * Linear sRGB channels as the browser renders them: an out-of-gamut colour has\n * each channel clipped to 0–1. Measured in Chrome 153 (Sprint 25.7 Part D): 211\n * of 211 oklch() colours outside sRGB came back within 1/255 of per-channel\n * clipping, from an sRGB canvas and from a screenshot alike. Reducing chroma to\n * the gamut edge, which this function did until then (CSS Color 4's intent),\n * was up to 82/255 off in a channel, and the full CSS Color 4 gamut-mapping\n * algorithm up to 73/255. Clipping is usually lighter (a negative channel\n * rises to 0), so white text decided on the chroma-reduced colour could miss\n * AA as drawn: 4.41:1 on the palette bold at hue 187.5, which it scored 4.62.\n */\nfunction oklchToLinearSrgbClamped(colour: Oklch): [number, number, number] {\n return oklchToLinearSrgb(colour).map((v) => Math.min(1, Math.max(0, v))) as [number, number, number]\n}\n\nconst gammaEncode = (v: number) => (v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055)\nconst gammaDecode = (v: number) => (v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4))\n\n/** Gamma-encoded sRGB channels (0..1) — the space `opacity` compositing and `color-mix(in srgb)` blend in. */\nfunction oklchToSrgb(colour: Oklch): [number, number, number] {\n return oklchToLinearSrgbClamped(colour).map(gammaEncode) as [number, number, number]\n}\n\nfunction srgbLuminance([r, g, b]: [number, number, number]): number {\n return 0.2126 * gammaDecode(r) + 0.7152 * gammaDecode(g) + 0.0722 * gammaDecode(b)\n}\n\n/**\n * How near a half step (of 1/255) a channel can sit and still come out of\n * Chrome one step either way. Chrome's arithmetic is not this file's: of 2,435\n * colours measured (Sprint 25.7 Part D; 7,305 channels), 39 channels came back\n * one step from the nearest, and every one sat within 0.12 of a step of the\n * half-step boundary.\n * One step is up to 0.05 of contrast near the white crossover, which is where\n * the decisions live, so a decision counts both steps inside this window.\n */\nexport const ROUNDING_WINDOW = 0.25\n\n/** A colour's WCAG luminance as Chrome can draw it: [darkest, lightest] over the 8-bit steps each channel can round to. */\nexport type LuminanceRange = readonly [number, number]\n\n/** The luminance range of gamma-encoded sRGB channels (0–1): each channel's nearest step, or both steps beside it within the window. */\nfunction srgbLuminanceRange(encoded: readonly number[]): LuminanceRange {\n let lo = 0\n let hi = 0\n encoded.forEach((v, i) => {\n const x = Math.min(1, Math.max(0, v)) * 255\n const below = Math.floor(x)\n const [a, b] = Math.abs(x - below - 0.5) <= ROUNDING_WINDOW ? [below, Math.min(255, below + 1)] : [Math.round(x), Math.round(x)]\n const weight = [0.2126, 0.7152, 0.0722][i]\n lo += weight * gammaDecode(a / 255)\n hi += weight * gammaDecode(b / 255)\n })\n return [lo, hi]\n}\n\n/** The luminance range an OKLCH colour can take as Chrome draws it: clipped to sRGB, then rounded to 8 bits. */\nexport function luminanceRange(colour: Oklch): LuminanceRange {\n return srgbLuminanceRange(oklchToSrgb(colour))\n}\n\n/** The lowest contrast two colours can show, every way either can round (1 when their ranges meet). */\nexport function worstContrastOf([t0, t1]: LuminanceRange, [f0, f1]: LuminanceRange): number {\n if (t0 <= f1 && f0 <= t1) return 1\n return t0 > f1 ? contrastRatio(t0, f1) : contrastRatio(t1, f0)\n}\n\n/** WCAG contrast ratio between two relative luminances. */\nexport function contrastRatio(lumA: number, lumB: number): number {\n const lighter = Math.max(lumA, lumB)\n const darker = Math.min(lumA, lumB)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/**\n * Sprint 25.14 A20 (and Sprint 30's P1): colours as the browser has drawn them — 8-bit sRGB channels and an alpha, read\n * from a canvas or a screenshot — composited and compared as WCAG does. A translucent edge is judged over what it sits\n * on: each ground laid under it in gamma-encoded sRGB, the space the browser blends in.\n */\nexport type DrawnColour = readonly [r: number, g: number, b: number, alpha: number]\n\n/** `top` laid over an opaque `ground`, as the browser composites it. */\nexport function drawnOver(top: DrawnColour, ground: DrawnColour): DrawnColour {\n const a = top[3]\n return [0, 1, 2].map((i) => Math.round(top[i] * a + ground[i] * (1 - a))).concat(1) as unknown as DrawnColour\n}\n\n/** WCAG relative luminance of an opaque drawn colour. */\nexport function drawnLuminance([r, g, b]: DrawnColour): number {\n return srgbLuminance([r / 255, g / 255, b / 255])\n}\n\n/** WCAG contrast between two opaque drawn colours. */\nexport function drawnContrast(a: DrawnColour, b: DrawnColour): number {\n return contrastRatio(drawnLuminance(a), drawnLuminance(b))\n}\n\n/** The lowest contrast `edge` shows over each ground (opaque), composited where it is translucent, and the ground it is lowest on. */\nexport function edgeContrast(edge: DrawnColour, grounds: ReadonlyArray<readonly [name: string, ground: DrawnColour]>): { ratio: number; on: string } {\n let worst = { ratio: Infinity, on: \"\" }\n for (const [name, ground] of grounds) {\n const ratio = drawnContrast(drawnOver(edge, ground), ground)\n if (ratio < worst.ratio) worst = { ratio, on: name }\n }\n return worst\n}\n\nexport const WCAG_AA_TEXT = 4.5\n\n/** White text as the emitters write it. */\nexport const ON_FILL_WHITE = 'oklch(1 0 0)'\n/** Last-resort dark text: the theme's darkest neutral. Used only when no tint of the fill's own hue can pass (§ onFillDarkTint). */\nexport const ON_FILL_DARK = 'var(--ds-neutral-950)'\n/**\n * The last-resort candidate as a colour: --ds-neutral-950 is L 0.13 with a\n * chroma of 0.002 × --ds-sat-neutral, which is invisible to the luminance\n * calculation, so the hue does not matter here.\n */\nexport const DARK_TEXT_CANDIDATE: Oklch = { L: 0.13, C: 0.002, H: 0 }\n\n/** The dark tint keeps the fill's hue at this chroma (the palette's `-dark` variant uses 0.10 too); a duller fill keeps its own chroma. */\nexport const ON_FILL_TINT_CHROMA = 0.10\n/** Preferred contrast for the dark tint. Falls back to AA where no dark colour can reach it (fills just above the white crossover). */\nexport const ON_FILL_TINT_TARGET = 5\nconst TINT_L_MAX = 0.45\nconst TINT_L_MIN = 0.10\nconst TINT_L_STEP = 0.01\n\nconst WHITE_RANGE: LuminanceRange = [1, 1]\nconst DARK_RANGE = luminanceRange(DARK_TEXT_CANDIDATE)\n\n/** The worst contrast a text colour gets over one or more fills as Chrome draws them (a gradient passes every colour it paints: gradientFills). */\nfunction minContrast(text: LuminanceRange, fills: Oklch[]): number {\n let min = Infinity\n for (const f of fills) min = Math.min(min, worstContrastOf(text, luminanceRange(f)))\n return min\n}\n\n/**\n * White or dark text over one or more fills (a gradient passes every colour it\n * paints, gradientFills): whichever onFillTextValue emits, so a caller showing the choice (the\n * builder's \"text flips to dark\" note) agrees with the token.\n */\nexport function onFillText(fill: Oklch, ...moreFills: Oklch[]): 'white' | 'dark' {\n return onFillTextValue(fill, ...moreFills) === ON_FILL_WHITE ? 'white' : 'dark'\n}\n\n/**\n * The dark text colour for a fill: a deep shade of the fill's own hue rather\n * than a neutral, so an amber badge reads as amber-on-amber the way the\n * decorative palette pairs `-dark` text with `-subtle` backgrounds. The\n * lightest tint (L 0.45 → 0.10 in 0.01 steps, chroma capped at 0.10) whose\n * worst contrast across the fills reaches 5:1. Contrast comes before colour:\n * where the full-chroma tint cannot reach the target the chroma halves, then\n * quarters (a saturated green tint at L 0.10 is still luminous enough to\n * miss 5:1 over a light green); where no dark colour can reach 5:1 the\n * lightest reaching AA; null when not even AA is reachable (the caller then\n * falls back to --ds-neutral-950). For a gradient the hue is the start\n * colour's; the contrast is checked over every colour it paints (gradientFills).\n */\nexport function onFillDarkTint(fill: Oklch, ...moreFills: Oklch[]): Oklch | null {\n const fills = [fill, ...moreFills]\n const H = fill.H\n const chroma = Math.min(ON_FILL_TINT_CHROMA, fill.C)\n for (const target of [ON_FILL_TINT_TARGET, WCAG_AA_TEXT]) {\n for (const C of [chroma, chroma / 2, chroma / 4]) {\n for (let L = TINT_L_MAX; L >= TINT_L_MIN - 1e-9; L -= TINT_L_STEP) {\n const candidate = { L: +L.toFixed(2), C: +C.toFixed(4), H }\n if (minContrast(luminanceRange(candidate), fills) >= target) return candidate\n }\n }\n }\n return null\n}\n\n/**\n * The CSS value for text on a fill, the one on-fill decision: white where\n * white reaches AA over every fill as drawn; else the dark tint\n * (onFillDarkTint); else --ds-neutral-950 or white, whichever does better.\n * The tints go darker than --ds-neutral-950, so they also cover the sliver\n * around luminance 0.184 where white and the neutral both miss a single fill\n * (a fill at L 0.55 near hue 215). Only a gradient whose colours lie either\n * side of the crossover can leave every colour short of AA; the fill has to\n * change there.\n */\nexport function onFillTextValue(fill: Oklch, ...moreFills: Oklch[]): string {\n const fills = [fill, ...moreFills]\n const whiteMin = minContrast(WHITE_RANGE, fills)\n if (whiteMin >= WCAG_AA_TEXT) return ON_FILL_WHITE\n const tint = onFillDarkTint(fill, ...moreFills)\n if (tint) return oklchCss(tint)\n return minContrast(DARK_RANGE, fills) >= whiteMin ? ON_FILL_DARK : ON_FILL_WHITE\n}\n\n/** How many equal parts a gradient is sampled in, between its two ends (every 5%: a dip can sit at 95% of the way). */\nconst GRADIENT_SAMPLES = 20\n\n/**\n * The colours a gradient paints, for deciding the text over it: its two ends\n * (the start first, so a dark tint keeps the start's hue) and the points\n * between them. Chrome paints a linear-gradient of oklch() colours in Oklab\n * (CSS Color 4's default for colours that are not legacy sRGB): its pixels\n * follow Oklab interpolation to within 0.003 of luminance (measured, Sprint\n * 25.7, 26 September 2026). A point in between can be darker or lighter than\n * both ends, because two saturated ends that sRGB clips meet at a duller colour\n * that clips less: up to 5% darker than the darker end across the accent scale\n * (a violet to a red at primary-600), enough to take text below AA.\n */\nexport function gradientFills(start: Oklch, end: Oklch): [Oklch, Oklch, ...Oklch[]] {\n const lab = ({ L, C, H }: Oklch) => [L, C * Math.cos((H * Math.PI) / 180), C * Math.sin((H * Math.PI) / 180)]\n const [a, b] = [lab(start), lab(end)]\n const between: Oklch[] = []\n for (let i = 1; i < GRADIENT_SAMPLES; i++) {\n const [L, x, y] = a.map((v, k) => v + ((b[k] - v) * i) / GRADIENT_SAMPLES)\n between.push({ L, C: Math.hypot(x, y), H: ((Math.atan2(y, x) * 180) / Math.PI + 360) % 360 })\n }\n return [start, end, ...between]\n}\n\n/* ── Tinted surfaces (subtle colourful header) ──────────────────────────\n A tinted surface is the surface colour (--ds-bg-surface, so it matches the\n cards around it) washed with the accent — the gradient, or the solid accent —\n at one strength. One recipe in both accent modes, so the tint is a pure\n shade of the accent over the paper and its luminance is knowable: the muted\n ink over it is the lightest neutral step that clears AA against the worst\n wash stop. The picker measures against the default surface; a preset that\n overrides --ds-bg-surface (cream, translucent) shifts the real tint a little,\n the same limitation --ds-text-on-primary has under a --ds-gradient override. */\n\n/** Opacity of the accent wash over --ds-tint-base. Shared by the CSS (--ds-tint-strength) and the ink picker. */\nexport const TINT_STRENGTH = 0.15\n/** The default --ds-bg-surface per mode: white in light, --ds-neutral-800 in dark. @sync roots.css (tint-parity.test.ts checks). */\nexport const TINT_BASE: Record<'light' | 'dark', Oklch> = {\n light: { L: 1, C: 0, H: 0 },\n dark: { L: 0.27, C: 0.004, H: 0 },\n}\n/** The CSS for --ds-accent-wash when the accent is solid: a flat image so the overlay reads one token in both modes. */\nexport const SOLID_ACCENT_WASH = 'linear-gradient(var(--ds-accent-primary), var(--ds-accent-primary))'\n\n/** L of the neutral steps: the muted-ink candidates (200–700) and the deep steps that can serve as text on the neutral status fill (chroma ≤ 0.01 × sat, invisible to luminance). @sync roots.css --ds-neutral-* (tint-parity.test.ts checks). */\nexport const NEUTRAL_STEP_L: Record<number, number> = { 200: 0.90, 300: 0.84, 400: 0.71, 500: 0.55, 600: 0.45, 700: 0.37, 800: 0.27, 900: 0.20, 950: 0.13 }\n/** Candidate steps, lightest first: the first that clears AA wins, so hierarchy against --ds-text-secondary is kept where the tint allows. */\nconst MUTED_ON_TINT_STEPS: Record<'light' | 'dark', number[]> = { light: [400, 500, 600, 700], dark: [400, 300, 200] }\n\n/** The tinted surface for one wash colour in gamma sRGB: the base blended with the wash (clipped, as drawn) at TINT_STRENGTH, as the browser composites the overlay. */\nfunction tintSrgb(mode: 'light' | 'dark', wash: Oklch): [number, number, number] {\n const base = oklchToSrgb(TINT_BASE[mode])\n const top = oklchToSrgb(wash)\n return base.map((v, i) => v * (1 - TINT_STRENGTH) + top[i] * TINT_STRENGTH) as [number, number, number]\n}\n\n/** WCAG luminance of the tinted surface for one wash colour, at the nearest 8-bit step (the ink picker uses the range Chrome's rounding can land in). */\nexport function tintLuminance(mode: 'light' | 'dark', wash: Oklch): number {\n return srgbLuminance(tintSrgb(mode, wash).map((v) => Math.round(v * 255) / 255) as [number, number, number])\n}\n\n/**\n * The muted ink for text over a tinted surface: `var(--ds-neutral-NNN)`, the\n * lightest candidate step whose worst contrast across the wash colours (a\n * gradient passes both ends) reaches AA as Chrome draws both. The darkest\n * candidate when none does.\n */\nexport function mutedOnTint(mode: 'light' | 'dark', wash: Oklch, ...moreWashes: Oklch[]): string {\n const surfaces = [wash, ...moreWashes].map((w) => srgbLuminanceRange(tintSrgb(mode, w)))\n const steps = MUTED_ON_TINT_STEPS[mode]\n for (const step of steps) {\n const ink = luminanceRange({ L: NEUTRAL_STEP_L[step], C: 0, H: 0 })\n if (surfaces.every((surface) => worstContrastOf(ink, surface) >= WCAG_AA_TEXT)) return `var(--ds-neutral-${step})`\n }\n return `var(--ds-neutral-${steps[steps.length - 1]})`\n}\n\n/**\n * On-fill tokens for the four status fills that carry text (Badge, Button,\n * Stepper, Dock, the Gantt's bars). Takes the palette's literal values; a value\n * that is not an OKLCH literal keeps white, the roots.css default.\n */\nexport function onStatusFillTokens(sv: { success: string; warning: string; error: string; info: string }): Record<string, string> {\n const pick = (value: string) => {\n const c = parseOklch(value)\n return c ? onFillTextValue(c) : ON_FILL_WHITE\n }\n return {\n '--ds-text-on-success': pick(sv.success),\n '--ds-text-on-warning': pick(sv.warning),\n '--ds-text-on-error': pick(sv.error),\n '--ds-text-on-info': pick(sv.info),\n }\n}\n\n/**\n * The neutral status fill per mode: a mid step of the theme's neutral scale, for\n * an item with no status (\"not started\", a Gantt bar with no known status). Dark\n * mode takes the step one lighter, as every status fill does (500 → 400), so the\n * fill still shows at 3:1 on the dark surfaces (neutral-700 to -900).\n * @sync roots.css --ds-status-neutral (token-algorithms.test.ts checks).\n */\nexport const STATUS_NEUTRAL_STEP: Record<'light' | 'dark', number> = { light: 500, dark: 400 }\n\n/** The deep neutral steps that can carry text on the neutral fill, lightest first. */\nconst NEUTRAL_TEXT_STEPS = [700, 800, 900, 950]\n\n/**\n * The neutral status fill and the text on it, for one mode. The same in every\n * status palette, so roots.css declares the same pair as its defaults. The text\n * is decided as every on-fill colour is (onFillText, onFillDarkTint): white\n * where white reaches AA over the fill; else the lightest deep shade of the\n * fill's own hue reaching 5:1, then AA — for a neutral fill that is a step of\n * the neutral scale, which carries the theme's neutral hue and saturation as the\n * fill does; --ds-neutral-950 as the last resort.\n */\nexport function neutralStatusFillTokens(mode: 'light' | 'dark'): Record<string, string> {\n const step = STATUS_NEUTRAL_STEP[mode]\n const fill: Oklch = { L: NEUTRAL_STEP_L[step], C: 0, H: 0 }\n const text = (): string => {\n if (onFillText(fill) === 'white') return ON_FILL_WHITE\n for (const target of [ON_FILL_TINT_TARGET, WCAG_AA_TEXT]) {\n for (const s of NEUTRAL_TEXT_STEPS) {\n if (s > step && minContrast(luminanceRange({ L: NEUTRAL_STEP_L[s], C: 0, H: 0 }), [fill]) >= target) return `var(--ds-neutral-${s})`\n }\n }\n return ON_FILL_DARK\n }\n return {\n '--ds-status-neutral': `var(--ds-neutral-${step})`,\n '--ds-text-on-neutral': text(),\n }\n}\n\n/**\n * Computes accent tokens from shade + mode.\n * Chart tokens are now generated separately via computeChartTokens (they\n * depend on palette values that don't exist at accent-computation time).\n *\n * With a `gradient` config (which every emitter passes, solid or gradient,\n * because it carries the hue and saturation) the set also includes\n * `--ds-text-on-primary`, decided by `onFillText` over the accent — or over\n * every colour a gradient paints (gradientFills). Without one the token is\n * left to roots.css (white).\n */\nexport function getAccentTokens(\n shade: number,\n mode: 'light' | 'dark',\n gradient?: GradientConfig\n): Record<string, string> {\n const s = Math.max(300, Math.min(900, shade))\n const hover = mode === 'dark' ? Math.max(300, s - 100) : Math.min(950, s + 100)\n const active = mode === 'dark' ? Math.max(300, s - 200) : Math.min(950, s + 200)\n\n const tokens: Record<string, string> = {\n '--ds-accent-primary': `var(--ds-primary-${s})`,\n '--ds-accent-primary-hover': `var(--ds-primary-${hover})`,\n '--ds-accent-primary-active': `var(--ds-primary-${active})`,\n '--ds-border-focus': `var(--ds-primary-${s})`,\n // Every stroke-based active state pairs the solid --ds-border-focus stroke with this soft halo.\n '--ds-ring-active': 'var(--ds-accent-soft)',\n '--ds-input-focus-ring': 'var(--ds-ring-active)',\n '--ds-shadow-focus': `0 0 0 2px var(--ds-primary-${s})`,\n // Tinted surfaces: --ds-tint-base is var(--ds-bg-surface) in roots.css; only the strength is emitted (see mutedOnTint).\n '--ds-tint-strength': String(TINT_STRENGTH),\n }\n\n if (gradient?.accentMode === 'gradient') {\n const startHue = gradient.hue ?? gradient.endHue\n const start = accentColour(s, gradient.sat, startHue)\n const startColor = `oklch(${start.L} ${start.C.toFixed(4)} ${startHue})`\n\n const endShade = Math.max(300, Math.min(900, gradient.endShade ?? s))\n const endSat = gradient.endSat ?? gradient.sat\n const end = accentColour(endShade, endSat, gradient.endHue)\n const endColor = oklchCss(end)\n tokens['--ds-gradient'] = `linear-gradient(${gradient.angle}deg, ${startColor}, ${endColor})`\n // The two ends as their own tokens so SVG gradients (icon strokes) can follow the theme.\n tokens['--ds-gradient-start'] = startColor\n tokens['--ds-gradient-end'] = endColor\n tokens['--ds-text-on-primary'] = onFillTextValue(...gradientFills(start, end))\n // Reads the gradient token (not the literal) so a preset override of --ds-gradient washes the tint too.\n tokens['--ds-accent-wash'] = 'var(--ds-gradient)'\n tokens['--ds-text-muted-on-tint'] = mutedOnTint(mode, start, end)\n } else {\n tokens['--ds-gradient'] = 'none'\n tokens['--ds-gradient-start'] = 'var(--ds-accent-primary)'\n tokens['--ds-gradient-end'] = 'var(--ds-accent-primary)'\n tokens['--ds-accent-wash'] = SOLID_ACCENT_WASH\n if (gradient) {\n const solid = accentColour(s, gradient.sat, gradient.hue)\n tokens['--ds-text-on-primary'] = onFillTextValue(solid)\n tokens['--ds-text-muted-on-tint'] = mutedOnTint(mode, solid)\n }\n }\n\n return tokens\n}\n\nconst DEFAULT_INTERACTIVE: InteractiveHoverConfig = {\n enabled: true, effect: 'scale-lift', speed: 150, ease: 'ease-out', scale: 1.02, lift: 2, pressDepth: 1,\n}\n\nconst DEFAULT_AMBIENT: AmbientHoverConfig = {\n enabled: true, effect: 'lift', speed: 250, ease: 'cubic-bezier(0.33, 1, 0.68, 1)', scale: 1, lift: 1,\n}\n\nconst INTENSITY_PRESETS: Record<string, Record<string, string>> = {\n none: { '--ds-hover-scale': '1', '--ds-hover-lift': '0px', '--ds-press-depth': '0px', '--ds-ambient-hover-scale': '1', '--ds-ambient-hover-lift': '0px' },\n subtle: { '--ds-hover-scale': '1.02', '--ds-hover-lift': '2px', '--ds-press-depth': '1px', '--ds-ambient-hover-scale': '1', '--ds-ambient-hover-lift': '1px' },\n moderate: { '--ds-hover-scale': '1.035', '--ds-hover-lift': '3px', '--ds-press-depth': '1px', '--ds-ambient-hover-scale': '1.01', '--ds-ambient-hover-lift': '2px' },\n expressive: { '--ds-hover-scale': '1.05', '--ds-hover-lift': '6px', '--ds-press-depth': '2px', '--ds-ambient-hover-scale': '1.015', '--ds-ambient-hover-lift': '3px' },\n}\n\n/**\n * Computes hover motion tokens from structured config.\n * Handles both modern (interactive + ambient) and legacy (intensity) input shapes.\n */\nexport function computeHoverTokens(motion: MotionDecisions): Record<string, string> {\n const i = motion.interactive\n const a = motion.ambient\n\n if (i || a) {\n const interactive = i ?? DEFAULT_INTERACTIVE\n const ambient = a ?? DEFAULT_AMBIENT\n const hasScale = interactive.enabled && hasScaleEffect(interactive.effect)\n const hasILift = interactive.enabled && hasLiftEffect(interactive.effect)\n const hasAScale = ambient.enabled && hasScaleEffect(ambient.effect)\n const hasALift = ambient.enabled && hasLiftEffect(ambient.effect)\n return {\n '--ds-hover-scale': hasScale ? String(interactive.scale) : '1',\n '--ds-hover-lift': hasILift ? `${interactive.lift}px` : '0px',\n '--ds-press-depth': interactive.enabled ? `${interactive.pressDepth}px` : '0px',\n '--ds-interactive-hover-speed': `${interactive.speed}ms`,\n '--ds-interactive-hover-ease': interactive.ease,\n '--ds-ambient-hover-scale': hasAScale ? String(ambient.scale) : '1',\n '--ds-ambient-hover-lift': hasALift ? `${ambient.lift}px` : '0px',\n '--ds-ambient-hover-speed': `${ambient.speed}ms`,\n '--ds-ambient-hover-ease': ambient.ease,\n }\n }\n\n const base = INTENSITY_PRESETS[motion.intensity ?? 'subtle'] ?? INTENSITY_PRESETS['subtle']\n return {\n ...base,\n '--ds-interactive-hover-speed': `${motion.speed}ms`,\n '--ds-interactive-hover-ease': motion.ease,\n '--ds-ambient-hover-speed': `${Math.round(motion.speed * 1.5)}ms`,\n '--ds-ambient-hover-ease': 'cubic-bezier(0.33, 1, 0.68, 1)',\n }\n}\n\n/**\n * Computes the accent colour of an independent-mode sidebar (or header) from\n * the target palette, as a literal because it comes from the *other* palette.\n * Since Sprint 20.10 it sits on the same --ds-primary-{shade} scale as the\n * page accent (it used to be a lighter curve, 0.597 at 500 against 0.55), so\n * the on-accent text decision flips at the same shade everywhere.\n * `onAccent` is the text colour over the accent, emitted as\n * --ds-sidebar-text-on-accent / --ds-header-text-on-accent.\n * Used by runtime DOM writers and static CSS generator.\n */\nexport function computeSidebarAccent(\n shade: number,\n satPrimary: number,\n huePrimary: number\n): { accent: string; accentSubtle: string; onAccent: string } {\n const colour = accentColour(shade, satPrimary, huePrimary)\n const accent = oklchCss(colour)\n const accentSubtle = `color-mix(in srgb, ${accent} 10%, transparent)`\n return { accent, accentSubtle, onAccent: onFillTextValue(colour) }\n}\n\n// Status hue positions (fixed, not configurable)\nconst STATUS_HUES = { success: 142, warning: 86, error: 25, info: 255 }\nconst STATUS_HUE_VALUES = Object.values(STATUS_HUES)\n\nconst GOLDEN_ANGLE = 137.508\n\n/**\n * Normalise a hue to [0, 360).\n */\nfunction normaliseHue(h: number): number {\n return ((h % 360) + 360) % 360\n}\n\n/**\n * Angular distance on the hue wheel (0–180).\n */\nfunction hueDistance(a: number, b: number): number {\n const diff = Math.abs(normaliseHue(a) - normaliseHue(b))\n return diff > 180 ? 360 - diff : diff\n}\n\n/**\n * Distributes 5 palette hues around the OKLCH hue wheel using golden-angle\n * spacing. Avoids the primary hue neighbourhood and status hue positions.\n *\n * @param primaryHue The user's primary accent hue (0–360)\n * @param exclusionRadius Minimum angular distance from primary and status hues (default 20°)\n * @returns Array of 5 hue values, each in [0, 360)\n */\nexport function computePaletteHues(\n primaryHue: number,\n exclusionRadius = 20\n): number[] {\n const hues: number[] = []\n const excluded = [normaliseHue(primaryHue), ...STATUS_HUE_VALUES]\n\n function isColliding(h: number): boolean {\n return excluded.some(ex => hueDistance(h, ex) < exclusionRadius) ||\n hues.some(existing => hueDistance(h, existing) < exclusionRadius)\n }\n\n // Start opposite the primary hue for maximum initial separation\n const cursor = normaliseHue(primaryHue + 180)\n\n for (let i = 0; i < 5; i++) {\n let candidate = normaliseHue(cursor + i * GOLDEN_ANGLE)\n\n // Nudge colliding candidates by +5° increments, up to a full rotation\n let attempts = 0\n while (isColliding(candidate) && attempts < 72) {\n candidate = normaliseHue(candidate + 5)\n attempts++\n }\n\n hues.push(candidate)\n }\n\n return hues\n}\n\n// Palette generation lightness/chroma targets\nconst PALETTE_BOLD_L = 0.55\nconst PALETTE_BOLD_C = 0.12\nconst PALETTE_SUBTLE_L = 0.92\nconst PALETTE_SUBTLE_C = 0.03\nconst PALETTE_DARK_L = 0.35\nconst PALETTE_DARK_C = 0.10\n\n/**\n * How far a palette bold may darken to keep white text (the owner's call, 26\n * September 2026). Teals and cyans near the sRGB edge (hues 170–216.5 at the\n * constants above) clip lighter than white allows at PALETTE_BOLD_L, and one\n * step of PALETTE_BOLD_STEP brings each to AA as drawn, so a row of Badges and\n * Tags keeps one text colour. A bold that no step up to this brings to AA keeps\n * its lightness and takes a tint of its hue.\n */\nexport const PALETTE_BOLD_MAX_DARKEN = 0.02\nconst PALETTE_BOLD_STEP = 0.01\n\n/**\n * A bold fill for white text: darkened by the smallest step (PALETTE_BOLD_STEP) that brings white to AA as drawn,\n * never by more than maxDarken; a fill no darkening within the cap brings there is returned as it was, and its text\n * takes a tint (onFillTextValue). getPaletteTokens passes PALETTE_BOLD_MAX_DARKEN; the cap is a parameter so a fill\n * that needs more than it can be tested (no palette hue does at today's constants).\n */\nexport function boldForWhiteText(fill: Oklch, maxDarken: number = PALETTE_BOLD_MAX_DARKEN): Oklch {\n let L = fill.L\n while (onFillText({ ...fill, L }) === 'dark' && fill.L - L < maxDarken - 1e-9) L = +(L - PALETTE_BOLD_STEP).toFixed(2)\n return onFillText({ ...fill, L }) === 'dark' ? fill : { ...fill, L }\n}\n\n/**\n * The lightness a chart series needs in dark mode to show at 3:1 against the surfaces a chart sits on (WCAG 1.4.11):\n * every hue at C 0.12 clears 3:1 on the elevated surface (neutral-700) and 4.5:1 on the card (neutral-800). It is\n * primary-400's lightness, as the light-mode series (the palette bold, 0.55, a step darker for the teals) is\n * primary-500's (Sprint 25.7).\n */\nexport const CHART_SERIES_DARK_L = 0.66\n\n/**\n * Generates the 5 palette tokens (bold/subtle/dark/bg/text) for a single hue.\n * Validates subtle/dark contrast and clamps chroma if needed.\n *\n * @param hue The palette hue value (0–360)\n * @param index Palette index (1–5) for token naming\n * @param mode 'light' | 'dark' — determines bg/text alias direction\n * @returns Record of CSS custom properties for this palette hue\n */\n/**\n * The soft pair of a hue (the supporting colours' step, Sprint 25.18's one rule for coloured text on a coloured ground,\n * the owner's D50): a pale fill and a deep text at fixed lightnesses, the gap widened until the pair reaches AA (4.5:1),\n * which these lightnesses already clear for every hue. `chroma` caps the two chromas: the supporting colours pass none\n * (their own constants); the accent passes its own chroma, so a grey accent gives a grey pair. Light mode draws the\n * pale one as the fill and the deep one as the text; dark mode swaps them.\n */\nexport function softPair(hue: number, chroma = Infinity): { subtle: string; dark: string } {\n const h = normaliseHue(hue)\n let subtleL = PALETTE_SUBTLE_L\n let darkL = PALETTE_DARK_L\n let ratio = estimateContrastRatio(subtleL, darkL)\n while (ratio < 4.5 && subtleL < 0.98 && darkL > 0.20) {\n subtleL = Math.min(0.98, subtleL + 0.02)\n darkL = Math.max(0.20, darkL - 0.02)\n ratio = estimateContrastRatio(subtleL, darkL)\n }\n const c = (constant: number) => Math.max(0, Math.min(constant, chroma)).toFixed(4)\n return {\n subtle: `oklch(${subtleL.toFixed(2)} ${c(PALETTE_SUBTLE_C)} ${h})`,\n dark: `oklch(${darkL.toFixed(2)} ${c(PALETTE_DARK_C)} ${h})`,\n }\n}\n\n/** The soft pair's lightnesses and chromas, for the stylesheet's own reading of the step (roots.css derives the accent's pair from them). */\nexport const SOFT_PAIR = { subtleL: PALETTE_SUBTLE_L, subtleC: PALETTE_SUBTLE_C, darkL: PALETTE_DARK_L, darkC: PALETTE_DARK_C } as const\n\n/**\n * The accent's soft pair (Sprint 25.18 A15, the owner's D51): the supporting colours' step applied to the accent, its\n * chroma capped by the accent's own (the primary scale's chroma at the accent's shade, times the saturation), so the\n * accent's tint and text are one more supporting colour. `--ds-accent-bg` is the fill, `--ds-accent-text` the text on it\n * (readable on the page and a card too); a Calendar event in the accent draws with them.\n */\nexport function getAccentPairTokens(shade: number, sat: number, hue: number, mode: 'light' | 'dark'): Record<string, string> {\n const { subtle, dark } = softPair(hue, accentColour(shade, sat, hue).C)\n return {\n '--ds-accent-bg': mode === 'light' ? subtle : dark,\n '--ds-accent-text': mode === 'light' ? dark : subtle,\n }\n}\n\nexport function getPaletteTokens(\n hue: number,\n index: number,\n mode: 'light' | 'dark'\n): Record<string, string> {\n const h = normaliseHue(hue)\n\n // Bold: white text as drawn, darkened within PALETTE_BOLD_MAX_DARKEN where the fill clips too light for it; past the\n // cap it keeps its lightness and its text takes a tint (below)\n const boldFill = boldForWhiteText({ L: PALETTE_BOLD_L, C: PALETTE_BOLD_C, H: h })\n const boldL = boldFill.L\n\n // Subtle/dark: the soft pair, at AA (softPair)\n const { subtle, dark } = softPair(h)\n const bold = `oklch(${boldL.toFixed(2)} ${PALETTE_BOLD_C.toFixed(4)} ${h})`\n\n const prefix = `--ds-palette-${index}`\n\n return {\n [`${prefix}-bold`]: bold,\n [`${prefix}-subtle`]: subtle,\n [`${prefix}-dark`]: dark,\n [`${prefix}-bg`]: mode === 'light' ? `var(${prefix}-subtle)` : `var(${prefix}-dark)`,\n [`${prefix}-text`]: mode === 'light' ? `var(${prefix}-dark)` : `var(${prefix}-subtle)`,\n // The chart series colour: the bold in light mode; lifted in dark, where the bold sinks into a dark card\n // (2.9:1 for reds and magentas on neutral-800). Badges and Tags keep the bold, for their white text.\n [`${prefix}-chart`]: mode === 'light' ? `var(${prefix}-bold)` : `oklch(${CHART_SERIES_DARK_L.toFixed(2)} ${PALETTE_BOLD_C.toFixed(4)} ${h})`,\n // Text on the bold fill (Badge / Tag colour variants), decided by contrast as\n // drawn: white, the teals and cyans that clip too light for it one step\n // darker (above); a deep tint of the hue only where no step within\n // PALETTE_BOLD_MAX_DARKEN brings white to AA.\n [`${prefix}-on-bold`]: onFillTextValue(boldFill),\n }\n}\n\n/**\n * The primary step chart-1 draws in: the accent's own when it shows at 3:1 on the mode's surfaces — 500 or darker on\n * a light card (PRIMARY_SCALE L 0.55 and below, the palette bold's lightness), 400 or lighter on a dark one (L 0.66\n * and above, CHART_SERIES_DARK_L) — else the nearest step that does.\n */\nexport function chartAccentShade(accentShade: number, mode: 'light' | 'dark'): number {\n const s = scaleShade(accentShade)\n return mode === 'dark' ? Math.min(s, 400) : Math.max(s, 500)\n}\n\n/**\n * Generates chart tokens that reference accent and palette values via var(). All values are CSS variable references,\n * not computed colours — the palette tokens must already exist in the same scope. chart-1 is the accent unless the\n * accent is too light (light mode) or too dark (dark mode) for a series, and then the nearest primary step that shows\n * (chartAccentShade); chart-2–6 are the palette's chart colours. Without an accent shade, chart-1 is the accent.\n *\n * @returns Record of 14 CSS custom properties (12 chart tokens + 2 backwards-compat aliases)\n */\nexport function computeChartTokens(accentShade?: number, mode: 'light' | 'dark' = 'light'): Record<string, string> {\n const series = accentShade == null ? null : chartAccentShade(accentShade, mode)\n const accent = series == null || series === scaleShade(accentShade!) ? 'var(--ds-accent-primary)' : `var(--ds-primary-${series})`\n const tokens: Record<string, string> = {\n '--ds-chart-1': accent,\n '--ds-chart-1-soft': `color-mix(in oklch, ${accent} 30%, transparent)`,\n }\n\n for (let i = 1; i <= 5; i++) {\n tokens[`--ds-chart-${i + 1}`] = `var(--ds-palette-${i}-chart)`\n tokens[`--ds-chart-${i + 1}-soft`] = `color-mix(in oklch, var(--ds-palette-${i}-chart) 30%, transparent)`\n }\n\n // Backwards-compat aliases\n tokens['--ds-chart-fill'] = `var(--ds-chart-1)`\n tokens['--ds-chart-fill-soft'] = `var(--ds-chart-1-soft)`\n\n return tokens\n}\n\n/**\n * Approximate WCAG contrast ratio between two OKLCH lightness values.\n * Uses L³ as a luminance proxy (OKLCH lightness is perceptual, L³ ≈ relative luminance).\n * Returns estimated ratio (1.0 to 21.0). Kept for the palette subtle/dark\n * pair, which only needs a ranking; on-fill text decisions use\n * `oklchToLuminance` + `contrastRatio` (Sprint 20.10), which account for hue,\n * chroma and gamut.\n */\nexport function estimateContrastRatio(L1: number, L2: number): number {\n const lum1 = Math.pow(Math.max(0, Math.min(1, L1)), 3)\n const lum2 = Math.pow(Math.max(0, Math.min(1, L2)), 3)\n const lighter = Math.max(lum1, lum2)\n const darker = Math.min(lum1, lum2)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/**\n * Approximate WCAG contrast ratio between an oklch colour and white.\n * Delegates to estimateContrastRatio with L2 = 1.0 (white).\n */\nexport function estimateContrastVsWhite(oklchL: number): number {\n return estimateContrastRatio(oklchL, 1.0)\n}\n\n// ---------------------------------------------------------------------------\n// Navigation active styles (Sprint 20.8)\n// ---------------------------------------------------------------------------\n//\n// The *shape* of an active navigation item is a theme decision, not a per-page\n// one. Three decisions (sidebar, in-page horizontal, in-page vertical) resolve\n// to 24 CSS custom properties that SidebarNav, Tabs and TreeView read. Every\n// value is a var() of an existing mode-aware token or a plain length, so the\n// set has one body — but because var() inside a custom property is substituted\n// where it is *declared*, emitters must declare the set in every scope that\n// redeclares one of its inputs (:root, [data-mode], [data-ds-overlay]).\n//\n// The defaults reproduce today's rendering exactly (sprint §0.1). Do not\n// \"improve\" a default value here — that is a product change with its own\n// changelog entry.\n\nexport type SidebarActiveStyle = 'rail' | 'tint' | 'pill'\nexport type InPageHorizontalStyle = 'underline' | 'tint' | 'pill'\nexport type InPageVerticalStyle = 'rail' | 'tint' | 'pill'\n\nexport interface NavStyleInput {\n sidebarActiveStyle?: SidebarActiveStyle\n /** Only used to derive the default and the coercion: minimal and compact sidebars have no edge to stroke, so their default is tint and an explicit rail resolves to tint. */\n sidebarType?: 'traditional' | 'compact' | 'minimal'\n inPageHorizontal?: InPageHorizontalStyle\n inPageVertical?: InPageVerticalStyle\n}\n\nexport interface ResolvedNavStyles {\n sidebarActiveStyle: SidebarActiveStyle\n inPageHorizontal: InPageHorizontalStyle\n inPageVertical: InPageVerticalStyle\n}\n\n/**\n * The only place the missing-field defaults and the no-edge coercion (minimal\n * and compact sidebars) live. Every reader (deserialisers, Worker readers, CSS emitters, the rules\n * file) calls this — nobody writes `?? 'rail'` anywhere else.\n *\n * The coercion is render-time only: stored state keeps the user's choice so\n * switching a minimal or compact sidebar back to traditional restores the rail.\n */\nexport function resolveNavStyles(input: NavStyleInput): ResolvedNavStyles {\n const noEdge = input.sidebarType === 'minimal' || input.sidebarType === 'compact'\n let sidebarActiveStyle: SidebarActiveStyle = input.sidebarActiveStyle ?? (noEdge ? 'tint' : 'rail')\n if (noEdge && sidebarActiveStyle === 'rail') sidebarActiveStyle = 'tint'\n return {\n sidebarActiveStyle,\n inPageHorizontal: input.inPageHorizontal ?? 'underline',\n inPageVertical: input.inPageVertical ?? 'rail',\n }\n}\n\nconst ON_PRIMARY = 'var(--ds-text-on-primary)'\nconst SIDEBAR_ON_ACCENT = 'var(--ds-sidebar-text-on-accent)'\nconst ACCENT = 'var(--ds-accent-primary)'\nconst ACCENT_SUBTLE = 'var(--ds-accent-subtle)'\nconst PILL_BADGE_BG = 'color-mix(in oklab, var(--ds-bg-canvas) 20%, transparent)'\n\n/**\n * The 25 tokens of sprint §4 for the resolved styles (24, plus the sidebar\n * pill's gradient image — September 2026).\n */\nexport function getNavStyleTokens(input: NavStyleInput): Record<string, string> {\n const { sidebarActiveStyle, inPageHorizontal, inPageVertical } = resolveNavStyles(input)\n const tokens: Record<string, string> = {}\n\n // ── In-page horizontal (Tabs) ─────────────────────────────────────────\n switch (inPageHorizontal) {\n case 'underline':\n tokens['--ds-nav-h-active-bg'] = 'transparent'\n tokens['--ds-nav-h-active-text'] = 'var(--ds-text-primary)'\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-muted)'\n tokens['--ds-nav-h-indicator'] = 'calc(var(--ds-border-width) * 3)'\n tokens['--ds-nav-h-item-radius'] = '0px'\n tokens['--ds-nav-h-hover-bg'] = 'transparent'\n tokens['--ds-nav-h-track-border'] = 'var(--ds-border-width)'\n tokens['--ds-nav-h-track-gap'] = '0px'\n tokens['--ds-nav-h-badge-bg'] = ACCENT\n break\n case 'tint':\n tokens['--ds-nav-h-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-nav-h-active-text'] = ACCENT\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-h-indicator'] = '0px'\n tokens['--ds-nav-h-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-h-hover-bg'] = 'var(--ds-tab-hover-bg)'\n tokens['--ds-nav-h-track-border'] = '0px'\n tokens['--ds-nav-h-track-gap'] = 'var(--ds-space-1)'\n tokens['--ds-nav-h-badge-bg'] = ACCENT\n break\n case 'pill':\n tokens['--ds-nav-h-active-bg'] = ACCENT\n tokens['--ds-nav-h-active-text'] = ON_PRIMARY\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-h-indicator'] = '0px'\n tokens['--ds-nav-h-item-radius'] = 'var(--ds-radius-md)'\n tokens['--ds-nav-h-hover-bg'] = 'var(--ds-tab-hover-bg)'\n tokens['--ds-nav-h-track-border'] = '0px'\n tokens['--ds-nav-h-track-gap'] = 'var(--ds-space-1)'\n tokens['--ds-nav-h-badge-bg'] = PILL_BADGE_BG\n break\n }\n\n // ── In-page vertical (Tabs rail) ──────────────────────────────────────\n switch (inPageVertical) {\n case 'rail':\n tokens['--ds-nav-v-active-bg'] = 'var(--ds-tab-active-bg)'\n tokens['--ds-nav-v-active-text'] = ACCENT\n tokens['--ds-nav-v-active-rail'] = 'var(--ds-border-width-thick)'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = 'var(--ds-space-1)'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-v-badge-bg'] = ACCENT\n break\n case 'tint':\n tokens['--ds-nav-v-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-nav-v-active-text'] = ACCENT\n tokens['--ds-nav-v-active-rail'] = '0px'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-md)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = '0px'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-v-badge-bg'] = ACCENT\n break\n case 'pill':\n tokens['--ds-nav-v-active-bg'] = ACCENT\n tokens['--ds-nav-v-active-text'] = ON_PRIMARY\n tokens['--ds-nav-v-active-rail'] = '0px'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = '0px'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'color-mix(in srgb, var(--ds-text-on-primary) 80%, transparent)'\n tokens['--ds-nav-v-badge-bg'] = PILL_BADGE_BG\n break\n }\n\n // ── Tree ──────────────────────────────────────────────────────────────\n // `-muted` is the chevron on the selected row: muted grey today, on-primary\n // under pill so it stays visible on the full-width accent bar.\n switch (inPageVertical) {\n case 'rail':\n tokens['--ds-tree-active-bg'] = 'var(--ds-tab-active-bg)'\n tokens['--ds-tree-active-text'] = ACCENT\n tokens['--ds-tree-active-muted'] = 'var(--ds-text-muted)'\n tokens['--ds-tree-active-rail'] = 'var(--ds-border-width-thick)'\n break\n case 'tint':\n tokens['--ds-tree-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-tree-active-text'] = ACCENT\n tokens['--ds-tree-active-muted'] = 'var(--ds-text-muted)'\n tokens['--ds-tree-active-rail'] = '0px'\n break\n case 'pill':\n tokens['--ds-tree-active-bg'] = ACCENT\n tokens['--ds-tree-active-text'] = ON_PRIMARY\n tokens['--ds-tree-active-muted'] = ON_PRIMARY\n tokens['--ds-tree-active-rail'] = '0px'\n break\n }\n\n // ── Sidebar ───────────────────────────────────────────────────────────\n // Decision 21: the active root label takes the sidebar accent for rail and\n // tint, matching Tabs, TreeView and NavItem (pre-20.8 it stayed neutral with\n // only the icon in accent). A deliberate default change, recorded in the\n // changelog.\n switch (sidebarActiveStyle) {\n case 'rail':\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent-subtle)'\n tokens['--ds-sidebar-active-text'] = 'var(--ds-sidebar-accent)'\n tokens['--ds-sidebar-active-accent'] = 'var(--ds-sidebar-accent)'\n tokens['--ds-sidebar-active-rail'] = 'var(--ds-border-width-thick)'\n tokens['--ds-sidebar-active-image'] = 'none'\n break\n case 'tint':\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent-subtle)'\n tokens['--ds-sidebar-active-text'] = 'var(--ds-sidebar-accent)'\n tokens['--ds-sidebar-active-accent'] = 'var(--ds-sidebar-accent)'\n tokens['--ds-sidebar-active-rail'] = '0px'\n tokens['--ds-sidebar-active-image'] = 'none'\n break\n case 'pill':\n // The sidebar accent may come from the other palette (independent mode),\n // so its on-accent text is the scoped token, which roots.css defaults to\n // --ds-text-on-primary for match mode.\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_ON_ACCENT\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_ON_ACCENT\n tokens['--ds-sidebar-active-rail'] = '0px'\n // The pill takes the accent gradient like Button does: --ds-sidebar-gradient\n // is the page gradient in match mode and the target palette's gradient in\n // an independent mode (none when the accent is solid).\n tokens['--ds-sidebar-active-image'] = 'var(--ds-sidebar-gradient)'\n break\n }\n\n return tokens\n}\n\n/**\n * Sprint 25.14 A20: the switch's off look — no fill, and the strong edge colour for its outline and its knob, as Fluent\n * 2's off switch is. Only the theme writers emit these (generateTokensCss and ThemeContext, beside the nav style set, so\n * each scope resolves them against its own edge), never roots.css: an app that upgrades the library without\n * regenerating its stylesheet keeps the switch its stylesheet draws (the Toggle falls back to the filled one without it).\n * Sprint 25.19 K2: the edge is `--ds-control-edge-strong`, the theme's 3:1 edge, since a field's resting edge\n * (`--ds-input-border`) is the soft border again; the generator writes the strong edge in every mode's block, so a\n * stylesheet made by 0.27.0 resolves it with an earlier library's roots.css too.\n *\n * The knob is the lightest shade of the edge that still reaches 3:1 on every ground (the owner, 30 September: the black\n * knob of a black-edged theme was \"very bold, unnecessarily so\"): the edge mixed toward the surface, keeping\n * `--ds-switch-knob-share` of it. A preset whose edge is far past 3:1 sets the share per mode (neo-brutalist light keeps\n * under half its black); everywhere else it is the edge itself. The knob's place is the switch's state, so it needs\n * the 3:1 an outline does. Declared with the set, the mix reads each scope's own edge and surface.\n */\nexport const SWITCH_TOKENS: Record<string, string> = {\n '--ds-switch-off-fill': 'transparent',\n '--ds-switch-off-edge': 'var(--ds-control-edge-strong)',\n '--ds-switch-off-knob': 'color-mix(in oklab, var(--ds-control-edge-strong) var(--ds-switch-knob-share, 100%), var(--ds-bg-surface))',\n}\n\n/**\n * The checked colour (a checked box, a selected radio's dot, a switch's track when on) and its mark: the accent, unless\n * the preset sets its own for the mode. roots.css declares them once, at the root (@sync, check-tokens.test.ts checks).\n * A writer redeclares them in every block that redeclares the accent for another scope (the other mode's block, a dark\n * portal, a project's theme wrapper), before that scope's preset overrides, so they follow the scope's accent, not the\n * page's (the review of 30 September: since A20 a dark sidebar's switch on a light page took the light check colour).\n * Never under NAV_STYLE_SCOPE_SELECTOR: a same-mode wrapper or an overlay would lose the page preset's own check colour,\n * which some presets set for 3:1. --ds-check-gradient is left to inherit: a scope may take the page's `none`, a look\n * without the gradient, never a weaker fill.\n */\nexport const CHECK_TOKENS: Record<string, string> = {\n '--ds-check-bg': 'var(--ds-accent-primary)',\n '--ds-check-fg': 'var(--ds-text-on-primary)',\n '--ds-check-border': 'var(--ds-accent-primary)',\n}\n\n/**\n * Selector under which every emitter declares the nav style set. One rule\n * reaching the root, every nested mode wrapper and every overlay portal, so\n * the var() aliases resolve against each scope's own inputs.\n */\nexport const NAV_STYLE_SCOPE_SELECTOR = ':root, [data-mode], [data-ds-overlay]'\n","import { onFillTextValue, parseOklch } from \"../../lib/token-algorithms\";\nimport { forwardRef, useLayoutEffect, useRef, useState } from \"react\";\nimport {\n Treemap,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, useRadius } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface TreemapNode {\n name: string;\n value?: number;\n children?: TreemapNode[];\n [key: string]: unknown;\n}\n\nexport interface TreemapChartProps {\n data: TreemapNode[];\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\ninterface TreemapContentProps {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n name?: string;\n depth?: number;\n colors: string[];\n radius: number;\n index?: number;\n /** The label's line height and font size in px, read from the page (null until read). */\n metrics: LabelMetrics | null;\n}\n\ninterface LabelMetrics { lineHeight: number; fontSize: number }\n\n/** A label's inset from its cell's edges. */\nconst LABEL_INSET = 4;\n\n/**\n * How many lines of a label a cell holds (Sprint 25.17 A25, R28-55): as many as its height takes inside the inset; none\n * when it can't hold one line, or is narrower than about three characters, since a sliver of a word reads as nothing.\n */\nexport function treemapLabelLines(width: number, height: number, metrics: LabelMetrics): number {\n if (width - 2 * LABEL_INSET < metrics.fontSize * 3) return 0;\n return Math.max(0, Math.floor((height - 2 * LABEL_INSET) / metrics.lineHeight));\n}\n\n/** Colours as the browser computes them, once each: a token's var() and calc() resolved (\"oklch(0.66 calc(0.18 * 1) 280)\"). */\nconst computedColors = new Map<string, string>();\nfunction computedColor(css: string): string {\n if (typeof document === \"undefined\") return css;\n let value = computedColors.get(css);\n if (value === undefined) {\n const probe = document.createElement(\"span\");\n probe.style.color = css;\n document.body.appendChild(probe);\n value = getComputedStyle(probe).color;\n probe.remove();\n computedColors.set(css, value);\n }\n return value;\n}\n\n/**\n * The label's colour over its cell: the library's one on-fill decision (onFillTextValue: white where it reaches AA, else\n * a deep tint of the fill), for the theme's oklch fills, read as the browser computes them (Sprint 25.17's review: read\n * as hex, every label was white, under 4.5:1 on the lighter cells of every dark preset; a fill with a calc() in it didn't\n * parse); any other colour by its brightness.\n */\nfunction labelColorOn(fill: string): string {\n const parsed = parseOklch(fill) ?? parseOklch(computedColor(fill));\n return parsed ? onFillTextValue(parsed) : contrastColor(computedColor(fill));\n}\n\n/** Dark or white text by a colour's brightness: a hex colour, or rgb() as the browser writes one. */\nfunction contrastColor(color: string): string {\n const rgb = /^rgba?\\(\\s*(\\d+)[\\s,]+(\\d+)[\\s,]+(\\d+)/.exec(color);\n const c = color.replace(\"#\", \"\");\n const [r, g, b] = rgb ? [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])] : c.length >= 6 ? [parseInt(c.substring(0, 2), 16), parseInt(c.substring(2, 4), 16), parseInt(c.substring(4, 6), 16)] : [0, 0, 0];\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n return luminance > 0.55 ? \"#1f2937\" : \"#ffffff\";\n}\n\nfunction TreemapContent({ x = 0, y = 0, width = 0, height: h = 0, name, depth, colors, radius, index = 0, metrics }: TreemapContentProps) {\n const fill = colors[index % colors.length];\n // the label wraps onto the lines the cell holds, then ends in \"…\", and never leaves the cell (the owner: \"wrap and\n // truncate like our other items\"); SVG text doesn't wrap, so it is HTML in the cell, clamped as the library's other\n // labels are. A word too long for the cell is hyphenated where the page's language allows, else broken. The tooltip\n // keeps the full name.\n const lines = metrics && name ? treemapLabelLines(width, h, metrics) : 0;\n const labelColor = labelColorOn(fill);\n\n return (\n <g>\n <rect\n x={x}\n y={y}\n width={width}\n height={h}\n fill={fill}\n stroke=\"var(--ds-bg-surface)\"\n strokeWidth={2}\n rx={depth === 1 ? radius : 0}\n style={{ opacity: depth === 1 ? 1 : 0.85 }}\n />\n {lines > 0 && (\n <foreignObject x={x} y={y} width={width} height={h} style={{ pointerEvents: \"none\" }}>\n <div className=\"flex h-full w-full items-center justify-center overflow-hidden text-center\" style={{ padding: LABEL_INSET }}>\n <span\n data-treemap-label=\"\"\n className={LABEL_TEXT}\n style={{ color: labelColor, display: \"-webkit-box\", WebkitBoxOrient: \"vertical\", WebkitLineClamp: lines, overflow: \"hidden\", overflowWrap: \"anywhere\", hyphens: \"auto\" }}\n >\n {name}\n </span>\n </div>\n </foreignObject>\n )}\n </g>\n );\n}\n\nfunction addFillToNodes(nodes: TreemapNode[], colors: string[], counter = { i: 0 }): TreemapNode[] {\n return nodes.map((node) => {\n if (node.children) {\n return { ...node, children: addFillToNodes(node.children, colors, counter) };\n }\n const fill = colors[counter.i % colors.length];\n counter.i++;\n return { ...node, fill };\n });\n}\n\n/** The label's type: the theme's small size, its sans font, tight lines. */\nconst LABEL_TEXT = \"text-xs leading-tight font-[family-name:var(--ds-font-sans)]\";\n\n/** The label's line height and font size as the page draws them, read from a hidden sample after each render (a theme change re-renders the chart). */\nfunction useLabelMetrics(): [React.RefObject<HTMLSpanElement | null>, LabelMetrics | null] {\n const probe = useRef<HTMLSpanElement | null>(null);\n const [metrics, setMetrics] = useState<LabelMetrics | null>(null);\n // after every render: a theme's type can change with no prop of the chart's changing; the equality check below ends\n // the chain once the reading holds\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(() => {\n const el = probe.current;\n if (!el) return;\n const cs = getComputedStyle(el);\n const fontSize = parseFloat(cs.fontSize);\n const lineHeight = parseFloat(cs.lineHeight) || el.getBoundingClientRect().height;\n if (!(fontSize > 0) || !(lineHeight > 0)) return;\n if (!metrics || metrics.fontSize !== fontSize || metrics.lineHeight !== lineHeight) setMetrics({ fontSize, lineHeight });\n });\n return [probe, metrics];\n}\n\nexport const TreemapChart = markChart(forwardRef<HTMLDivElement, TreemapChartProps>(function TreemapChart({\n data,\n height = \"auto\",\n showTooltip = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(6, false);\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const [probe, metrics] = useLabelMetrics();\n\n const chartData = addFillToNodes(data, colors);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"ratio\" }} chart=\"treemap\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <Treemap\n data={chartData}\n dataKey=\"value\"\n nameKey=\"name\"\n aspectRatio={4 / 3}\n stroke=\"var(--ds-bg-surface)\"\n isAnimationActive={isAnimated}\n content={<TreemapContent colors={colors} radius={radius} metrics={metrics} />}\n >\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </Treemap>\n </ResponsiveContainer>\n <span ref={probe} aria-hidden className={LABEL_TEXT} style={{ position: \"absolute\", visibility: \"hidden\", pointerEvents: \"none\" }}>M</span>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n Sankey as RechartsSankey,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useResolvedToken } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface SankeyChartProps {\n data: {\n nodes: { name: string }[];\n links: { source: number; target: number; value: number }[];\n };\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const SankeyChart = markChart(forwardRef<HTMLDivElement, SankeyChartProps>(function SankeyChart({\n data,\n height = \"auto\",\n showTooltip = true,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.nodes.length, false);\n const linkStroke = useResolvedToken(\"--ds-border-subtle\");\n\n const nodesWithColor = data.nodes.map((node, i) => ({\n ...node,\n fill: colors[i % colors.length],\n }));\n\n const sankeyData = {\n nodes: nodesWithColor,\n links: data.links,\n };\n\n if (!data?.nodes?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"ratio\" }} chart=\"sankey\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsSankey\n data={sankeyData}\n nodeWidth={10}\n nodePadding={24}\n margin={{ top: 8, right: 8, bottom: 8, left: 8 }}\n link={{ stroke: linkStroke, strokeOpacity: 0.4 }}\n >\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </RechartsSankey>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId } from \"react\";\nimport {\n LineChart,\n Line,\n AreaChart,\n Area,\n BarChart,\n Bar,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { useResolvedToken, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { useInsideChartContainer } from \"./ChartWrapper\";\n\nexport interface SparklineProps {\n data: number[];\n variant?: \"line\" | \"area\" | \"bar\";\n color?: 1 | 2 | 3 | 4 | 5 | 6;\n height?: number;\n width?: number | \"100%\";\n showTooltip?: boolean;\n curved?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const Sparkline = forwardRef<HTMLDivElement, SparklineProps>(function Sparkline({\n data,\n variant = \"line\",\n color = 1,\n height = 40,\n width = \"100%\",\n showTooltip = false,\n curved = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const instanceId = useId();\n const isAnimated = useChartAnimation(animated);\n const insideContainer = useInsideChartContainer();\n\n const tokenName = `--ds-chart-${color}` as const;\n const softTokenName = `--ds-chart-${color}-soft` as const;\n const chartColor = useResolvedToken(tokenName);\n const softColor = useResolvedToken(softTokenName);\n const chartData = data.map((value, i) => ({ value, index: i }));\n\n const containerStyle = insideContainer\n ? { width: \"100%\", height: \"100%\" }\n : { width: typeof width === \"number\" ? `${width}px` : width, height: `${height}px` };\n\n if (!data?.length) return null;\n\n if (variant === \"bar\") {\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={chartData} margin={{ top: 0, right: 0, bottom: 0, left: 0 }}>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Bar\n dataKey=\"value\"\n fill={chartColor}\n radius={[2, 2, 0, 0]}\n isAnimationActive={isAnimated}\n />\n </BarChart>\n </ResponsiveContainer>\n </div>\n );\n }\n\n if (variant === \"area\") {\n const gradientId = `sparkline-gradient-${instanceId}-${color}`;\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={chartData} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={softColor} stopOpacity={1} />\n <stop offset=\"95%\" stopColor={softColor} stopOpacity={0.1} />\n </linearGradient>\n </defs>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide domain={[\"dataMin - 1\", \"dataMax + 1\"]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Area\n type={curved ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke={chartColor}\n strokeWidth={1.5}\n fill={`url(#${gradientId})`}\n dot={false}\n activeDot={showTooltip ? { r: 3, fill: chartColor } : false}\n isAnimationActive={isAnimated}\n />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n );\n }\n\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={chartData} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide domain={[\"dataMin - 1\", \"dataMax + 1\"]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Line\n type={curved ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke={chartColor}\n strokeWidth={1.5}\n dot={false}\n activeDot={showTooltip ? { r: 3, fill: chartColor } : false}\n isAnimationActive={isAnimated}\n />\n </LineChart>\n </ResponsiveContainer>\n </div>\n );\n});\n","import { useId, useMemo, type ReactNode } from \"react\";\nimport { cn, GLASS_SURFACE } from \"../lib/utils\";\nimport { TITLE_TEXT } from \"../lib/title-text\";\nimport { Skeleton } from \"./Skeleton\";\nimport { CHART_HEIGHTS, ChartContainerContext, fixedChartHeight, isLibraryChart, type ChartContainerValue } from \"./charts/ChartWrapper\";\n\n/**\n * CardTitle's classes (Card.tsx) without its line clamp: a chart's title states its insight, its message\n * (data_visualisation#3), so it is never cut. Kept equal to CardTitle's by a test.\n */\nexport const CHART_TITLE_CLASSES = TITLE_TEXT;\n\nexport interface ChartContainerProps {\n /**\n * \"auto\" (the default): the chart sizes itself from its type and its data (Sprint 25.9, A2) — a row per item for\n * sideways bars and funnels, two wide to one high for charts over dates or numbers, square for round charts — and in\n * a row its frame matches the tallest block while the chart grows only to its bound. \"fill\" means the same as \"auto\".\n * A preset (sm, md, lg) or a number of px sets this chart's height instead, and beats the chart's own.\n */\n height?: \"auto\" | \"fill\" | \"sm\" | \"md\" | \"lg\" | number;\n /** The insight, as a heading (h3) in the card-title style, never cut. The chart's graphic is named by it. */\n title?: string;\n loading?: boolean;\n emptyState?: ReactNode;\n /** \"default\" is a card surface. \"ghost\" drops surface, border, shadow and padding for charts embedded in another container. */\n variant?: \"default\" | \"ghost\";\n children: ReactNode;\n className?: string;\n}\n\nexport function ChartContainer({\n height = \"auto\",\n title,\n loading = false,\n emptyState,\n variant = \"default\",\n children,\n className,\n}: ChartContainerProps) {\n const titleId = useId();\n const fixed = fixedChartHeight(height);\n // A library chart sizes itself (its mark). Anything else — a hand-built chart, an EmptyState, a Sparkline, several\n // children — keeps an area of the preset's height, else md, and fills it.\n const sizesItself = !loading && !!children && isLibraryChart(children);\n const area = fixed ?? CHART_HEIGHTS.md;\n const context = useMemo<ChartContainerValue>(\n () => ({ height: fixed, titleId: title ? titleId : undefined, fillArea: !sizesItself }),\n [fixed, title, titleId, sizesItself],\n );\n\n let body: ReactNode = null;\n if (loading) {\n body = (\n <div className=\"absolute inset-0 flex flex-col justify-end gap-ds-2 px-ds-2\">\n <div className=\"flex items-end h-full gap-ds-1\">\n {[65, 40, 80, 55, 72, 45, 60].map((h, i) => (\n <Skeleton key={i} variant=\"custom\" className=\"flex-1\" height={`${h}%`} />\n ))}\n </div>\n <Skeleton variant=\"text\" lines={1} className=\"w-full\" />\n </div>\n );\n } else if (children) {\n body = (\n <ChartContainerContext.Provider value={context}>\n {sizesItself ? children : (\n // the area is absolute, so a child that fills 100% has a definite height to fill\n <div className=\"absolute inset-0\">\n <div className=\"h-full w-full\">{children}</div>\n </div>\n )}\n </ChartContainerContext.Provider>\n );\n } else if (emptyState) {\n body = <div className=\"flex flex-1 items-center justify-center\">{emptyState}</div>;\n }\n\n return (\n <div\n data-card=\"\"\n data-gs=\"chart\"\n className={cn(\n \"flex flex-col\",\n variant === \"ghost\"\n ? \"bg-transparent\"\n : cn(\n // CardHeader's inset, so titles inside frames line up in a row (A1)\n \"rounded-[var(--ds-radius-md)] px-ds-5 py-ds-4\",\n \"bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n GLASS_SURFACE,\n ),\n className,\n )}\n >\n {title && (\n <h3 id={titleId} className={cn(CHART_TITLE_CLASSES, \"mb-ds-4\")}>\n {title}\n </h3>\n )}\n <div\n data-chart-body=\"\"\n className=\"relative flex min-w-0 flex-col\"\n style={{ flex: \"1 1 0%\", minHeight: sizesItself ? undefined : area }}\n >\n {body}\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/chart-utils.ts","../../../showcase/src/lib/chart-categories.ts","../../../showcase/src/components/charts/ChartWrapper.tsx","../../../showcase/src/components/charts/value-format.ts","../../../showcase/src/components/charts/ChartPrimitives.tsx","../../../showcase/src/components/charts/BarChart.tsx","../../../showcase/src/components/charts/LineChart.tsx","../../../showcase/src/components/charts/AreaChart.tsx","../../../showcase/src/components/charts/PieChart.tsx","../../../showcase/src/components/charts/CompositeChart.tsx","../../../showcase/src/components/charts/ScatterChart.tsx","../../../showcase/src/components/charts/RadarChart.tsx","../../../showcase/src/components/charts/RadialBarChart.tsx","../../../showcase/src/components/charts/FunnelChart.tsx","../../../showcase/src/lib/token-algorithms.ts","../../../showcase/src/components/charts/TreemapChart.tsx","../../../showcase/src/components/charts/SankeyChart.tsx","../../../showcase/src/components/charts/Sparkline.tsx","../../../showcase/src/components/ChartContainer.tsx"],"names":["k","ChartWrapper","categoryKind","useState","useLayoutEffect","useContext","jsxs","jsx","useMemo","useEffect","forwardRef","BarChart","useRef","RechartsBarChart","Fragment","LineChart","ResponsiveContainer","RechartsLineChart","CartesianGrid","XAxis","YAxis","Tooltip","AreaChart","RechartsAreaChart","PieChart","RechartsPieChart","CompositeChart","values","lineValues","Bar","Line","ScatterChart","RechartsScatterChart","RadarChart","RechartsRadarChart","RadialBarChart","RechartsRadialBarChart","FunnelChart","RechartsFunnelChart","TreemapChart","SankeyChart","RechartsSankey","Sparkline","useId","Area"],"mappings":"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","file":"charts.js","sourcesContent":["import { useState, useLayoutEffect, useSyncExternalStore } from \"react\";\n\nconst CHART_TOKENS = [\n \"--ds-chart-1\",\n \"--ds-chart-2\",\n \"--ds-chart-3\",\n \"--ds-chart-4\",\n \"--ds-chart-5\",\n \"--ds-chart-6\",\n] as const;\n\nconst CHART_TOKENS_SOFT = [\n \"--ds-chart-1-soft\",\n \"--ds-chart-2-soft\",\n \"--ds-chart-3-soft\",\n \"--ds-chart-4-soft\",\n \"--ds-chart-5-soft\",\n \"--ds-chart-6-soft\",\n] as const;\n\nconst FALLBACK_COLORS: Record<string, string> = {\n \"--ds-chart-1\": \"#6366f1\",\n \"--ds-chart-2\": \"#d97706\",\n \"--ds-chart-3\": \"#059669\",\n \"--ds-chart-4\": \"#dc2626\",\n \"--ds-chart-5\": \"#0891b2\",\n \"--ds-chart-6\": \"#7c3aed\",\n \"--ds-chart-1-soft\": \"rgba(99, 102, 241, 0.3)\",\n \"--ds-chart-2-soft\": \"rgba(217, 119, 6, 0.3)\",\n \"--ds-chart-3-soft\": \"rgba(5, 150, 105, 0.3)\",\n \"--ds-chart-4-soft\": \"rgba(220, 38, 38, 0.3)\",\n \"--ds-chart-5-soft\": \"rgba(8, 145, 178, 0.3)\",\n \"--ds-chart-6-soft\": \"rgba(124, 58, 237, 0.3)\",\n \"--ds-bg-surface\": \"#ffffff\",\n \"--ds-border-subtle\": \"#e5e7eb\",\n \"--ds-text-primary\": \"#111827\",\n \"--ds-text-secondary\": \"#6b7280\",\n \"--ds-text-muted\": \"#9ca3af\",\n};\n\ntype Subscriber = () => void;\n\nlet modeVersion = 0;\nconst subscribers = new Set<Subscriber>();\nlet observerAttached = false;\n\nfunction attachObserver() {\n if (observerAttached || typeof document === \"undefined\") return;\n observerAttached = true;\n\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n if (m.attributeName === \"data-mode\") {\n modeVersion++;\n for (const sub of subscribers) sub();\n break;\n }\n }\n });\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-mode\"],\n });\n}\n\nfunction subscribe(cb: Subscriber) {\n attachObserver();\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n}\n\nfunction getSnapshot() {\n return modeVersion;\n}\n\nfunction getServerSnapshot() {\n return 0;\n}\n\nexport function resolveToken(token: string): string {\n if (typeof document === \"undefined\") return FALLBACK_COLORS[token] ?? \"#6366f1\";\n const val = getComputedStyle(document.documentElement).getPropertyValue(token).trim();\n return val || FALLBACK_COLORS[token] || \"#6366f1\";\n}\n\nexport function useChartColors(count: number, soft = false): string[] {\n const version = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [colors, setColors] = useState<string[]>(() => fallbackColors(count, soft));\n\n // Reads computed CSS custom properties, which only exist after the theme's\n // style tag is committed — this has to be a post-layout effect.\n /* eslint-disable react-hooks/set-state-in-effect -- token resolution is a DOM read after commit */\n useLayoutEffect(() => {\n setColors(resolveColors(count, soft));\n }, [count, soft, version]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n return colors;\n}\n\nfunction fallbackColors(count: number, soft: boolean): string[] {\n const tokens = soft ? CHART_TOKENS_SOFT : CHART_TOKENS;\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const token = tokens[i % tokens.length];\n result.push(FALLBACK_COLORS[token] ?? \"#6366f1\");\n }\n return result;\n}\n\nfunction resolveColors(count: number, soft: boolean): string[] {\n const tokens = soft ? CHART_TOKENS_SOFT : CHART_TOKENS;\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const token = tokens[i % tokens.length];\n result.push(resolveToken(token));\n }\n return result;\n}\n\nexport function useResolvedToken(token: string): string {\n const version = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [value, setValue] = useState(() => FALLBACK_COLORS[token] ?? \"#6366f1\");\n\n /* eslint-disable react-hooks/set-state-in-effect -- token resolution is a DOM read after commit */\n useLayoutEffect(() => {\n setValue(resolveToken(token));\n }, [token, version]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n return value;\n}\n\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n });\n\n useLayoutEffect(() => {\n const mql = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const handler = (e: MediaQueryListEvent) => setReduced(e.matches);\n mql.addEventListener(\"change\", handler);\n return () => mql.removeEventListener(\"change\", handler);\n }, []);\n\n return reduced;\n}\n\nexport const useChartAnimation = (animated?: boolean): boolean => {\n const reduced = useReducedMotion();\n return animated !== false && !reduced;\n};\n","/**\n * Sprint 25.9, A3 — what a chart's category axis holds, and how its labels fit. No Recharts here: the charts entry and\n * the tests import it, and it never measures on its own (the measurer is handed in).\n *\n * - `categoryKind(labels)`: \"scale\" when every non-empty label is a date, a time, a period or a number, else \"names\".\n * Anchored patterns only — never `Date.parse`, which V8 lets read \"Tier 1\", \"Sprint 1\" and \"Northern Region 2\" as dates.\n * - `createAxisMeasurer(el)`: canvas text widths in the axis's resolved font, read from a probe that carries\n * `font-size: var(--ds-font-size-xs)`, so a `calc()` token (`calc(16px * .75)`, a 14 px base) measures right.\n * - `fitLabel(name, width, measure)`: one line; else two lines split at a space; else \"…\" on the second. Never drops it.\n */\n\nexport type CategoryKind = \"names\" | \"scale\";\n\n/** A text's width in px in the axis font. */\nexport type Measure = (text: string) => number;\n\nconst ENGLISH_MONTHS = [\n \"january\", \"february\", \"march\", \"april\", \"may\", \"june\", \"july\", \"august\", \"september\", \"october\", \"november\", \"december\",\n \"jan\", \"feb\", \"mar\", \"apr\", \"jun\", \"jul\", \"aug\", \"sep\", \"sept\", \"oct\", \"nov\", \"dec\",\n];\nconst ENGLISH_WEEKDAYS = [\n \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\",\n \"mon\", \"tue\", \"tues\", \"wed\", \"thu\", \"thur\", \"thurs\", \"fri\", \"sat\", \"sun\",\n];\n\nconst escape = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nconst clean = (s: string) => s.trim().toLowerCase().replace(/\\.$/, \"\");\n\nfunction intlNames(locale: string, kind: \"month\" | \"weekday\"): string[] {\n const out: string[] = [];\n try {\n for (const width of [\"short\", \"long\"] as const) {\n const fmt = new Intl.DateTimeFormat(locale, kind === \"month\" ? { month: width, timeZone: \"UTC\" } : { weekday: width, timeZone: \"UTC\" });\n // 2026-01-05 is a Monday: seven days give the weekdays, the 15th of each month the months\n const count = kind === \"month\" ? 12 : 7;\n for (let i = 0; i < count; i++) {\n const date = kind === \"month\" ? new Date(Date.UTC(2026, i, 15)) : new Date(Date.UTC(2026, 0, 5 + i));\n out.push(clean(fmt.format(date)));\n }\n }\n } catch {\n // an unknown locale tag: English covers it\n }\n return out;\n}\n\n/**\n * The languages whose month and weekday names count: English, and the locale given (a chart's locale while a\n * server-rendered page hydrates, the same on both sides: Sprint 25.20); with none given, the runtime's, the browser's and\n * the page's, as an app's own call and a chart in the browser read them (labels in the visitor's own language count).\n */\nfunction locales(given?: string): string[] {\n const out = new Set<string>([\"en\"]);\n if (given !== undefined) {\n out.add(given);\n return [...out];\n }\n try { out.add(new Intl.DateTimeFormat().resolvedOptions().locale); } catch { /* no Intl locale */ }\n if (typeof navigator !== \"undefined\" && navigator.language) out.add(navigator.language);\n if (typeof document !== \"undefined\" && document.documentElement?.lang) out.add(document.documentElement.lang);\n return [...out];\n}\n\ninterface Patterns { key: string; list: RegExp[] }\nlet cached: Patterns | null = null;\n\nfunction patterns(given?: string): Patterns {\n const tags = locales(given);\n const key = tags.join(\"|\");\n if (cached?.key === key) return cached;\n const months = new Set(ENGLISH_MONTHS);\n const weekdays = new Set(ENGLISH_WEEKDAYS);\n for (const tag of tags) {\n for (const m of intlNames(tag, \"month\")) if (m) months.add(m);\n for (const d of intlNames(tag, \"weekday\")) if (d) weekdays.add(d);\n }\n // the longest first, so \"sept\" wins over \"sep\" and \"june\" over \"jun\"\n const alt = (set: Set<string>) => [...set].sort((a, b) => b.length - a.length).map(escape).join(\"|\");\n const M = `(?:${alt(months)})\\\\.?`;\n const D = `(?:${alt(weekdays)})\\\\.?`;\n const day = String.raw`\\d{1,2}(?:st|nd|rd|th|\\.)?`;\n const year = String.raw`'?\\d{2,4}`;\n const list = [\n // dates in digits: 2026-09-21, 21/09, 09/21/2026, 21.09.2026, an ISO date-time\n /^\\d{4}[-/.]\\d{1,2}(?:[-/.]\\d{1,2})?$/,\n /^\\d{1,2}[-/.]\\d{1,2}(?:[-/.]\\d{2,4})?$/,\n /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{1,2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:?\\d{2})?$/,\n // a day and a month in either order, and a month alone or with its year: 16 Sep, 21. Sept., Sept 21, March 2026\n new RegExp(`^${day}\\\\s*${M}(?:,?\\\\s+${year})?$`, \"iu\"),\n new RegExp(`^${M}\\\\s*${day}(?:,?\\\\s+${year})?$`, \"iu\"),\n new RegExp(`^${M}(?:\\\\s*${year})?$`, \"iu\"),\n // CJK dates: 9月21日, 2026年9月, 9월 21일\n /^(?:\\d{4}年)?\\d{1,2}月(?:\\d{1,2}日)?$/u,\n /^\\d{4}年(?:\\d{1,2}月)?$/u,\n /^(?:\\d{4}년\\s?)?\\d{1,2}월(?:\\s?\\d{1,2}일)?$/u,\n // a quarter or a half: Q3, Q3 2026, Q3 FY26, 2026 Q3, 3Q26, H1 2026\n /^Q[1-4](?:\\s*[-/']?\\s*(?:FY\\s?)?'?\\d{2,4})?$/i,\n /^[1-4]Q\\s*'?\\d{0,4}$/i,\n /^(?:FY\\s?)?'?\\d{2,4}\\s*[-/]?\\s*Q[1-4]$/i,\n /^H[12](?:\\s*'?\\d{2,4})?$/i,\n // a year or a fiscal year: 2026, FY26, FY 2025/26, 2025/26, 2025-2026\n /^(?:19|20)\\d{2}$/,\n /^FY\\s?'?\\d{2,4}(?:\\s?[-/]\\s?'?\\d{2,4})?$/i,\n /^(?:19|20)\\d{2}\\s?[-/–]\\s?(?:(?:19|20)?\\d{2})$/,\n // a week: W12, Wk 3, Week 12, Week 12 2026, 2026-W12\n /^(?:W|Wk|Week)\\.?\\s?\\d{1,2}(?:\\s*[,/-]?\\s*\\d{4})?$/i,\n /^\\d{4}-?W\\d{1,2}(?:-?\\d)?$/i,\n // a weekday: Mon, Tuesday, and the runtime and page locales' own\n new RegExp(`^${D}$`, \"iu\"),\n // a time: 09:00, 9:30 pm, 9am, 14h\n /^\\d{1,2}:\\d{2}(?::\\d{2})?\\s?(?:[ap]\\.?m\\.?)?$/i,\n /^\\d{1,2}\\s?[ap]\\.?m\\.?$/i,\n /^\\d{1,2}h(?:\\d{2})?$/i,\n // a number, a percentage or an amount: 12, -3.5, 1,200, 12%, $5k, €1.2m, 5 €, a bin (10–20, <10, 50+)\n /^[<>≤≥~]?\\s?[+\\-−]?\\s?[$€£¥₹]?\\s?\\d[\\d,. \\u00a0\\u202f]*(?:\\s?(?:k|m|mn|bn|b|t))?\\s?(?:%|[$€£¥₹])?\\+?$/iu,\n /^[$€£¥₹]?\\d[\\d,.]*\\s?[-–]\\s?[$€£¥₹]?\\d[\\d,.]*\\s?(?:k|m|bn|%)?$/iu,\n ];\n cached = { key, list };\n return cached;\n}\n\n/**\n * Whether a category axis holds names or a scale (dates, times, periods, numbers). Every non-empty label must match an\n * anchored pattern to be \"scale\"; an all-empty set is \"scale\". LineChart and AreaChart are always \"scale\"; BarChart and\n * CompositeChart guess with this, and their `categoryKind` prop overrides the guess.\n */\nexport function categoryKind(labels: ReadonlyArray<unknown>, locale?: string): CategoryKind {\n const { list } = patterns(locale);\n for (const raw of labels) {\n if (raw == null) continue;\n if (typeof raw === \"number\") { if (Number.isFinite(raw)) continue; return \"names\"; }\n if (raw instanceof Date) continue;\n const text = String(raw).trim();\n if (!text) continue;\n if (!list.some((re) => re.test(text))) return \"names\";\n }\n return \"scale\";\n}\n\n/* ── Measuring ──────────────────────────────────────────────────────────── */\n\n/** The axis font as the page resolves it: size and family from a probe carrying the chart's tick tokens. */\nexport function resolvedAxisFont(el: Element): { font: string; px: number } {\n const doc = el.ownerDocument;\n const view = doc.defaultView;\n let probe = el.querySelector<HTMLElement>(\"[data-chart-probe]\");\n let temporary = false;\n if (!probe) {\n probe = doc.createElement(\"span\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n probe.style.cssText = \"position:absolute;visibility:hidden;pointer-events:none;white-space:nowrap;font-size:var(--ds-font-size-xs);font-family:var(--ds-font-sans)\";\n el.appendChild(probe);\n temporary = true;\n }\n const cs = view?.getComputedStyle(probe);\n const px = parseFloat(cs?.fontSize ?? \"\") || 12;\n const family = (cs?.fontFamily ?? \"\").trim() || \"sans-serif\";\n const style = cs?.fontStyle && cs.fontStyle !== \"normal\" ? `${cs.fontStyle} ` : \"\";\n const weight = cs?.fontWeight && cs.fontWeight !== \"400\" && cs.fontWeight !== \"normal\" ? `${cs.fontWeight} ` : \"\";\n if (temporary) probe.remove();\n return { font: `${style}${weight}${px}px ${family}`, px };\n}\n\n/** One 2D context for every chart, kept per getContext implementation (a test may swap it for a stub). */\nlet shared: { getContext: unknown; ctx: CanvasRenderingContext2D | null } | null = null;\n\nfunction canvasContext(): CanvasRenderingContext2D | null {\n if (typeof document === \"undefined\") return null;\n const getContext = (globalThis as { HTMLCanvasElement?: { prototype: { getContext?: unknown } } }).HTMLCanvasElement?.prototype.getContext;\n if (shared && shared.getContext === getContext) return shared.ctx;\n let ctx: CanvasRenderingContext2D | null = null;\n try { ctx = document.createElement(\"canvas\").getContext?.(\"2d\") ?? null; } catch { ctx = null; }\n shared = { getContext, ctx };\n return ctx;\n}\n\n/**\n * A text measurer in the chart's own axis font, or null where there is no canvas (jsdom): the charts then show every\n * label in full on one line and leave the thinning to nobody.\n */\nexport function createAxisMeasurer(el: Element): { measure: Measure; px: number; font: string } | null {\n const ctx = canvasContext();\n if (!ctx) return null;\n const { font, px } = resolvedAxisFont(el);\n ctx.font = font;\n const widths = new Map<string, number>();\n const measure: Measure = (text) => {\n let w = widths.get(text);\n if (w === undefined) {\n // the context is shared: another chart may have set its own font since\n ctx.font = font;\n w = ctx.measureText(text).width;\n widths.set(text, w);\n }\n return w;\n };\n return { measure, px, font };\n}\n\n/* ── Fitting a name ─────────────────────────────────────────────────────── */\n\nexport const ELLIPSIS = \"…\";\n\nexport interface FittedLabel {\n /** One or two lines; the second ends with \"…\" when the name was cut. */\n lines: string[];\n cut: boolean;\n /** Characters of the name that show, spaces and the ellipsis left out. */\n shown: number;\n}\n\nconst letters = (s: string) => s.replace(/\\s+/g, \"\").replace(/…/g, \"\").length;\n\n/** The longest prefix of `text` that fits `width` (at least one character). */\nfunction prefixThatFits(text: string, width: number, measure: Measure, suffix = \"\"): number {\n let lo = 1;\n let hi = text.length;\n let best = 0;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (measure(text.slice(0, mid).trimEnd() + suffix) <= width) { best = mid; lo = mid + 1; } else hi = mid - 1;\n }\n return best;\n}\n\n/**\n * A name fitted to `width`: one line when it fits; else two lines split at a space; else the second line ends with \"…\".\n * A first word wider than the line breaks where the line ends, with a hyphen, so it reads as one word going on. The\n * name is never dropped, and without a measurer it shows in full on one line.\n */\nexport function fitLabel(name: string, width: number, measure: Measure | null): FittedLabel {\n const text = name.replace(/\\s+/g, \" \").trim();\n if (!measure || !text || width <= 0 || measure(text) <= width) return { lines: [text], cut: false, shown: letters(text) };\n const words = text.split(\" \");\n let first = \"\";\n let firstShown = \"\";\n let rest = \"\";\n for (let i = words.length - 1; i >= 1; i--) {\n const candidate = words.slice(0, i).join(\" \");\n if (measure(candidate) <= width) { first = firstShown = candidate; rest = words.slice(i).join(\" \"); break; }\n }\n if (!first) {\n // the first word alone is too wide: the first line holds what fits of it and a hyphen\n const k = Math.max(1, prefixThatFits(text, width, measure, \"-\"));\n firstShown = text.slice(0, k).trimEnd();\n rest = text.slice(k).trimStart();\n first = rest && !text.slice(k - 1, k + 1).includes(\" \") ? `${firstShown}-` : firstShown;\n }\n if (!rest) return { lines: [first], cut: false, shown: letters(firstShown) };\n if (measure(rest) <= width) return { lines: [first, rest], cut: false, shown: letters(firstShown) + letters(rest) };\n const k = prefixThatFits(rest, width, measure, ELLIPSIS);\n const kept = k > 0 ? rest.slice(0, k).trimEnd() : \"\";\n return { lines: [first, kept + ELLIPSIS], cut: true, shown: letters(firstShown) + letters(kept) };\n}\n\n/** D8: fewer visible characters than this on a cut name turns an upright chart of names sideways. */\nexport const MIN_NAME_CHARS = 6;\n\n/** Whether any name, fitted to `width`, would be cut to fewer than MIN_NAME_CHARS characters. */\nexport function namesCutShort(names: ReadonlyArray<string>, width: number, measure: Measure): boolean {\n return names.some((n) => {\n const fit = fitLabel(n, width, measure);\n return fit.cut && fit.shown < MIN_NAME_CHARS;\n });\n}\n","import {\n Children, createContext, forwardRef, isValidElement, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState,\n type CSSProperties, type KeyboardEvent, type ReactNode, type Ref,\n} from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { elementType } from \"../../lib/element-type\";\nimport { mergeRefs } from \"../../lib/slot\";\n\n/* ── Heights ────────────────────────────────────────────────────────────── */\n\n/** A chart's height: \"auto\" (the default) sizes it from its type and its data; a preset or a number overrides. */\nexport type ChartHeight = \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n\nexport const CHART_HEIGHTS = {\n sm: \"var(--ds-chart-height-sm)\",\n md: \"var(--ds-chart-height-md)\",\n lg: \"var(--ds-chart-height-lg)\",\n} as const;\n\n/** One row of a row chart (a sideways bar, a funnel stage). */\nexport const CHART_ROW = \"var(--ds-chart-row, 2rem)\";\n\n/** A preset or a number as a CSS height; \"auto\" has none (the chart sizes itself). */\nexport function fixedChartHeight(height: ChartHeight | undefined): string | undefined {\n if (typeof height === \"number\") return `${height}px`;\n if (height === \"sm\" || height === \"md\" || height === \"lg\") return CHART_HEIGHTS[height];\n return undefined;\n}\n\n/**\n * How a chart sizes itself (Sprint 25.9, A2, P2):\n * - \"rows\" (a sideways BarChart, a FunnelChart): a row per item, never under sm; `units` rows, `lines` extra label lines\n * (a two-line name makes its row one line taller), `axis` the value axis and titles below or above the rows;\n * - \"ratio\" (charts over dates or numbers, Treemap, Sankey): two wide to one high, between sm and lg;\n * - \"square\" (Pie, Radar, RadialBar): as tall as wide, between sm and lg.\n */\nexport type ChartSize =\n | { model: \"ratio\" }\n | { model: \"square\" }\n | { model: \"rows\"; units: number; lines?: number; axis?: string };\n\nconst SM = CHART_HEIGHTS.sm;\nconst LG = CHART_HEIGHTS.lg;\n\n/**\n * The plot box's height and its bound in a row. `cqi` resolves against the chart's wrapper, the size container, because\n * the plot box is its child (on the wrapper itself it would read the page's container). The box is `flex: 1 0 auto`,\n * never `flex-1`: its drawing is absolute, so a zero basis would collapse it (R5). In a row it grows to the row's\n * height up to a bound: a ratio chart to square, a row chart to twice its height, a round chart not at all.\n */\nexport function plotBoxStyle(size: ChartSize, fixed: string | undefined): CSSProperties {\n if (size.model === \"square\") {\n return { height: fixed ?? `clamp(${SM}, 100cqi, ${LG})`, flex: \"0 0 auto\" };\n }\n if (size.model === \"rows\") {\n const lines = size.lines ? ` + ${size.lines} * 1.25 * var(--ds-font-size-xs)` : \"\";\n const height = fixed ?? `max(${SM}, calc(${size.units} * ${CHART_ROW}${lines} + ${size.axis ?? CHART_ROW}))`;\n return { height, maxHeight: `calc(2 * ${height})`, flex: \"1 0 auto\" };\n }\n return { height: fixed ?? `clamp(${SM}, 50cqi, ${LG})`, maxHeight: `max(${fixed ?? LG}, 100cqi)`, flex: \"1 0 auto\" };\n}\n\n/* ── The chart mark ─────────────────────────────────────────────────────── */\n\n/**\n * Marks the library's charts, so ChartContainer knows its child sizes itself and needs no minimum area of its own.\n * `Symbol.for`, as PAGE_HEADER_MARK, so a second copy of the module still matches. A hand-built chart, an EmptyState\n * or a Sparkline carries no mark and keeps the container's area.\n */\nexport const CHART_MARK: unique symbol = Symbol.for(\"gridsmith.Chart\") as never;\n\nexport function markChart<T extends object>(component: T): T {\n Object.assign(component, { [CHART_MARK]: true });\n return component;\n}\n\n/** A single library chart (not a Fragment, a wrapper of the builder's or a list of children). */\nexport function isLibraryChart(children: ReactNode): boolean {\n const kids = Children.toArray(children);\n if (kids.length !== 1) return false;\n const only = kids[0];\n if (!isValidElement(only)) return false;\n const type = elementType(only.type) as Record<symbol, unknown> | string | null;\n return !!type && typeof type !== \"string\" && type[CHART_MARK] === true;\n}\n\n/* ── Context ────────────────────────────────────────────────────────────── */\n\nexport interface ChartContainerValue {\n /** The container's own height (a preset or a number, as CSS): it beats the chart's. */\n height?: string;\n /** The container title's id: the chart's graphic is named by it. */\n titleId?: string;\n /** The chart is not the container's only child (or is wrapped): it fills the container's area instead of sizing itself. */\n fillArea?: boolean;\n}\n\nexport const ChartContainerContext = createContext<ChartContainerValue | null>(null);\n\nexport function useInsideChartContainer(): boolean {\n return useContext(ChartContainerContext) !== null;\n}\n\n/** The chart's slots outside its drawing: the legend (Recharts' Legend portals into it) and the tooltip's live region. */\nexport interface ChartFrame {\n legend: HTMLElement | null;\n live: HTMLElement | null;\n /** A value in full, with its unit, for the tooltip and what the chart says (Sprint 25.17 A27); toLocaleString without one. */\n formatValue?: (value: number, dataKey?: string) => string;\n}\n\nexport const ChartFrameContext = createContext<ChartFrame>({ legend: null, live: null });\n\n/* ── Keyboard ───────────────────────────────────────────────────────────── */\n\nconst REMAPPED = new WeakSet<Event>();\n\n/**\n * A sideways chart lists its rows top to bottom. Recharts maps only ArrowLeft and ArrowRight, and in that layout reads\n * ArrowRight as the row above. Down and Right move to the next row, Up and Left to the one before, in reading order.\n */\nfunction remapRowKeys(e: KeyboardEvent<HTMLDivElement>) {\n if (REMAPPED.has(e.nativeEvent)) return;\n const next = e.key === \"ArrowDown\" || e.key === \"ArrowRight\";\n const previous = e.key === \"ArrowUp\" || e.key === \"ArrowLeft\";\n if (!next && !previous) return;\n const target = e.target as Element;\n if (!target.closest?.(\".recharts-wrapper\")) return;\n e.preventDefault();\n e.stopPropagation();\n const View = target.ownerDocument.defaultView ?? window;\n const event = new View.KeyboardEvent(\"keydown\", { key: next ? \"ArrowLeft\" : \"ArrowRight\", bubbles: true, cancelable: true });\n REMAPPED.add(event);\n target.dispatchEvent(event);\n}\n\n/* ── The wrapper ────────────────────────────────────────────────────────── */\n\nexport interface ChartWrapperProps {\n /** The chart's own height prop. A ChartContainer's preset or number beats it. */\n height?: ChartHeight;\n /** How the chart sizes itself when no height is set. */\n size: ChartSize;\n /** The chart type, for `data-gs-chart` (the bench reads it). */\n chart: string;\n /** A cartesian category axis: its kind and its categories (`data-category-kind`, `data-categories`). */\n categoryKind?: \"names\" | \"scale\";\n categories?: number;\n /** Which axis carries the categories, for the label counts (`data-labels-shown`, `data-labels-cut`). */\n categoryAxis?: \"x\" | \"y\";\n /** The rows run top to bottom (a sideways BarChart): the arrow keys follow them. */\n sideways?: boolean;\n /** The value axis's title, drawn horizontally above the axis (the chart leaves room at the top). */\n axisTitle?: string;\n className?: string;\n children: ReactNode;\n /** The chart's values in full, for its tooltip, by series (Sprint 25.17 A27). */\n formatValue?: (value: number, dataKey?: string) => string;\n \"aria-label\"?: string;\n}\n\n/**\n * Sprint 25.9, A2: the chart's frame and its size container. It holds the plot box (the Recharts drawing sits absolutely\n * inside it), the legend's slot below and the tooltip's live region, and owns the height, with or without a\n * ChartContainer. `min-inline-size` keeps a shrink-to-fit parent from collapsing it.\n */\nexport const ChartWrapper = forwardRef<HTMLDivElement, ChartWrapperProps>(function ChartWrapper({\n height = \"auto\",\n size,\n chart,\n categoryKind,\n categories,\n categoryAxis,\n sideways = false,\n axisTitle,\n className,\n children,\n formatValue,\n \"aria-label\": ariaLabel,\n}, ref) {\n const container = useContext(ChartContainerContext);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const plotRef = useRef<HTMLDivElement | null>(null);\n const [legend, setLegend] = useState<HTMLDivElement | null>(null);\n const [live, setLive] = useState<HTMLDivElement | null>(null);\n const frame = useMemo<ChartFrame>(() => ({ legend, live, formatValue }), [legend, live, formatValue]);\n // The drawing never shrinks below the plot box's last real size. A box sized with `cqi` reports a width of 0 for a\n // moment while headless Chrome takes a full-page screenshot; handed to Recharts, that cleared the drawing, so the\n // screenshot showed an empty chart or bars growing again from zero (measured). A reading of 0 is no layout: the\n // drawing keeps its size, grows at once and shrinks a frame later.\n const [drawn, setDrawn] = useState<{ width: number; height: number } | null>(null);\n useLayoutEffect(() => {\n const plot = plotRef.current;\n if (!plot || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver((entries) => {\n const box = entries[entries.length - 1]?.contentRect;\n if (!box || box.width <= 0 || box.height <= 0) return;\n setDrawn((prev) => (prev && Math.abs(prev.width - box.width) < 0.5 && Math.abs(prev.height - box.height) < 0.5 ? prev : { width: box.width, height: box.height }));\n });\n observer.observe(plot);\n return () => observer.disconnect();\n }, []);\n\n const fill = container?.fillArea === true;\n const fixed = container?.height ?? fixedChartHeight(height);\n const plotStyle: CSSProperties = fill ? { flex: \"1 1 0%\", minHeight: 0 } : plotBoxStyle(size, fixed);\n\n // The graphic is named by the chart's own label, else by its container's title (A1).\n const named = ariaLabel\n ? { role: \"img\", \"aria-label\": ariaLabel }\n : container?.titleId\n ? { role: \"img\", \"aria-labelledby\": container.titleId }\n : {};\n\n // A8: how many category labels show, and how many were shortened, counted on the rendered ticks.\n useEffect(() => {\n const root = rootRef.current;\n const plot = plotRef.current;\n if (!root || !plot || !categoryAxis || typeof MutationObserver === \"undefined\") return;\n const selector = `.recharts-${categoryAxis}Axis-tick-labels .recharts-cartesian-axis-tick-value`;\n const count = () => {\n const labels = Array.from(plot.querySelectorAll(selector)).filter((el) => (el.textContent ?? \"\").trim() !== \"\");\n const shown = String(labels.length);\n const cut = String(labels.filter((el) => el.hasAttribute(\"data-cut\")).length);\n if (root.getAttribute(\"data-labels-shown\") !== shown) root.setAttribute(\"data-labels-shown\", shown);\n if (root.getAttribute(\"data-labels-cut\") !== cut) root.setAttribute(\"data-labels-cut\", cut);\n };\n count();\n const observer = new MutationObserver(count);\n observer.observe(plot, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: [\"data-cut\"] });\n return () => observer.disconnect();\n }, [categoryAxis]);\n\n return (\n <div\n ref={mergeRefs(ref as Ref<HTMLElement>, rootRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n data-gs-chart={chart}\n data-category-kind={categoryKind}\n data-categories={categories}\n className={cn(\"relative flex w-full flex-col\", fill && \"h-full\", className)}\n style={{ containerType: \"inline-size\", minInlineSize: \"min(100%, 16rem)\", ...(fill ? {} : { flex: \"1 0 auto\" }) }}\n >\n <div\n ref={plotRef}\n data-chart-plot=\"\"\n className=\"relative w-full\"\n style={plotStyle}\n onKeyDownCapture={sideways ? remapRowKeys : undefined}\n {...named}\n >\n {axisTitle && (\n <span data-chart-axis-title=\"\" className=\"absolute left-0 top-0 whitespace-nowrap text-xs text-[var(--ds-text-muted)] font-[family-name:var(--ds-font-sans)] leading-normal\">\n {axisTitle}\n </span>\n )}\n <div className=\"absolute inset-0\" style={drawn ? { minWidth: drawn.width, minHeight: drawn.height } : undefined}>\n <ChartFrameContext.Provider value={frame}>{children}</ChartFrameContext.Provider>\n </div>\n </div>\n <div ref={setLegend} data-chart-legend=\"\" />\n <div ref={setLive} role=\"status\" aria-live=\"polite\" className=\"sr-only\" />\n {/* the axis font and one row, as the page resolves them (useAxisMeasure reads it) */}\n <span\n data-chart-probe=\"\"\n aria-hidden=\"true\"\n className=\"pointer-events-none invisible absolute left-0 top-0\"\n style={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", height: CHART_ROW, width: 0 }}\n />\n </div>\n );\n});\n","import { getNiceTickValues } from \"recharts\";\n\n/**\n * How a chart's values read (Sprint 25.17 A27, R28-50, P21). \"number\" (the default): plain numbers, compact on the axis\n * from five digits up (1M, 750K; 1,234 as it is). \"percent\": values are percentages out of 100 (45 reads 45%; multiply a fraction by\n * 100 first). \"milliseconds\": durations in ms (120 ms, 1.5 s, 2 min). \"bytes\": sizes in bytes, in the units of 1,000 the\n * browser's own formats name (1.5 MB). A function formats both the axis and the tooltip itself. Everything is in the\n * page's language (its `lang`, in the visitor's formats where they speak it: formatLocale).\n */\nexport type ValueFormat = \"number\" | \"percent\" | \"milliseconds\" | \"bytes\" | ((value: number) => string);\n\n/** Recharts draws a value axis with five ticks on a nice scale that includes 0 (its default domain, [0, \"auto\"]). */\nconst TICK_COUNT = 5;\n\nconst TIME_UNITS: Array<[unit: string, ms: number]> = [[\"hour\", 3_600_000], [\"minute\", 60_000], [\"second\", 1_000], [\"millisecond\", 1]];\nconst BYTE_UNITS: Array<[unit: string, bytes: number]> = [[\"petabyte\", 1e15], [\"terabyte\", 1e12], [\"gigabyte\", 1e9], [\"megabyte\", 1e6], [\"kilobyte\", 1e3], [\"byte\", 1]];\n\n/** Fraction digits tried before giving up on an exact label (a value with more is shown to this many). */\nconst MAX_FRACTION = 10;\n\n/**\n * A value as `format` writes it with the fewest fraction digits that show it exactly, in the locale's own notation:\n * 2,500 is \"2.5K\" in English and 15,000 \"1.5万\" in Japanese, 0.0004 is \"0.0004\" — never a rounded \"3K\", \"2万\" or \"0\"\n * (Sprint 25.17's review: digits counted in thousands misread the locales that group by 万 or by lakh, and a cap of\n * three turned small rates into a row of zeros). Exact means more digits change nothing.\n */\nfunction exact(format: (digits: number) => string, maxDigits = MAX_FRACTION): string {\n for (let digits = 0; digits < maxDigits; digits++) {\n const label = format(digits);\n if (label === format(digits + 6)) return label;\n }\n return format(maxDigits);\n}\n\nconst unitFormat = (unit: string, value: number, locale: string | undefined) => (digits: number) =>\n new Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay: \"short\", maximumFractionDigits: digits }).format(value);\n\nconst unitsOf = (format: \"milliseconds\" | \"bytes\") => (format === \"bytes\" ? BYTE_UNITS : TIME_UNITS);\n\n/** The largest unit a value reaches (1.5 MB, 120 ms), for a value read on its own. */\nfunction unitReached(units: Array<[string, number]>, value: number): [string, number] {\n return units.find(([, size]) => Math.abs(value) >= size) ?? units[units.length - 1];\n}\n\n/**\n * One unit for a whole axis (the review: \"0 ms, 25 sec, 1.25 min\" chose it tick by tick): the largest its biggest tick\n * reaches in which every tick reads exactly in two fraction digits or fewer, so 25 s and 75 s stay seconds where minutes\n * would read 0.417.\n */\nfunction axisUnit(units: Array<[string, number]>, ticks: number[]): [string, number] {\n const largest = Math.max(0, ...ticks.map(Math.abs));\n const exactIn = (size: number) => ticks.every((t) => Math.abs((t / size) * 100 - Math.round((t / size) * 100)) < 1e-6);\n return units.find(([, size]) => largest / size >= 1 && exactIn(size)) ?? units[units.length - 1];\n}\n\n/** The ticks Recharts draws for these values on a value axis. */\nexport function valueAxisTicks(values: number[]): number[] {\n const finite = values.filter(Number.isFinite);\n if (!finite.length) return [];\n const lo = Math.min(0, ...finite);\n const hi = Math.max(0, ...finite);\n if (lo === hi) return [lo];\n return getNiceTickValues([lo, hi], TICK_COUNT, true).map(Number);\n}\n\n/**\n * A value axis's tick labels: compact from five digits up, in the chart's locale (its useFormatLocale(), Sprint 25.20),\n * each exact (formatted as Recharts draws it, whatever ticks it picks); a duration or a size in one unit for the axis.\n */\nexport function axisTickFormatter(values: number[], format: ValueFormat | undefined, locale: string | undefined): (value: number) => string {\n if (typeof format === \"function\") return format;\n if (format === \"percent\") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: \"percent\", maximumFractionDigits: d }).format(value / 100));\n if (format === \"milliseconds\" || format === \"bytes\") {\n const [unit, size] = axisUnit(unitsOf(format), valueAxisTicks(values));\n return (value) => exact(unitFormat(unit, value / size, locale));\n }\n const compact = (value: number) => exact((d) => new Intl.NumberFormat(locale, { notation: \"compact\", maximumFractionDigits: d }).format(value));\n const plain = (value: number) => exact((d) => new Intl.NumberFormat(locale, { maximumFractionDigits: d }).format(value));\n // compact where it pays, from five digits up (250k for 250,000); below, the number as people write it: 1,234, never\n // 1.234K, which is longer and reads worse (the 25.17 second review). Read from the values, so a domain of the page's own\n // (2018 to 2024) is read as Recharts draws it.\n const largest = Math.max(0, ...values.filter(Number.isFinite).map(Math.abs));\n return largest >= COMPACT_FROM ? compact : plain;\n}\n\n/** The size from which a value axis's numbers read compact (Sprint 25.17's second review). */\nconst COMPACT_FROM = 10_000;\n\n/** A value in full, as the tooltip shows it, in the chart's locale: every digit of a number (grouped); a duration's or a size's, exactly, in the largest unit it reaches. */\nexport function fullValueFormatter(format: ValueFormat | undefined, locale: string | undefined): (value: number) => string {\n if (typeof format === \"function\") return format;\n if (format === undefined || format === \"number\") return (value) => value.toLocaleString(locale);\n if (format === \"percent\") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: \"percent\", maximumFractionDigits: d }).format(value / 100), 4);\n return (value) => {\n const [unit, size] = unitReached(unitsOf(format), value);\n return exact(unitFormat(unit, value / size, locale), 4);\n };\n}\n\n/** A series a value axis draws: its key, and the stack it sits in (null: on its own). */\nexport interface AxisSeries {\n dataKey: string;\n stack: string | null;\n}\n\n/**\n * The values a value axis spans: each value of a series drawn on its own, and each stack's positive values summed up from\n * 0 and its negative values down — the charts stack both ways from zero (Sprint 25.17's review: a stack of 6,500 up and\n * 2,500 down was read as one sum of 4,000). One reading for every chart.\n */\nexport function axisExtent(data: Record<string, unknown>[], series: AxisSeries[]): number[] {\n return data.flatMap((row) => {\n const own: number[] = [];\n const up = new Map<string, number>();\n const down = new Map<string, number>();\n for (const s of series) {\n const raw = row[s.dataKey];\n const v = typeof raw === \"number\" ? raw : typeof raw === \"string\" && raw.trim() !== \"\" ? Number(raw) : NaN;\n if (!Number.isFinite(v)) continue;\n if (s.stack == null) own.push(v);\n else if (v >= 0) up.set(s.stack, (up.get(s.stack) ?? 0) + v);\n else down.set(s.stack, (down.get(s.stack) ?? 0) + v);\n }\n return [...own, ...up.values(), ...down.values()];\n });\n}\n\n/** The values a value axis spans for these series: each on its own, or one stack of them all. */\nexport function seriesValues(data: Record<string, unknown>[], keys: string[], stacked = false): number[] {\n return axisExtent(data, keys.map((dataKey) => ({ dataKey, stack: stacked ? \"stack\" : null })));\n}\n","import { useContext, useEffect, useLayoutEffect, useMemo, useState, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Legend, Text } from \"recharts\";\nimport { useResolvedToken } from \"../../lib/chart-utils\";\nimport { createAxisMeasurer, fitLabel, namesCutShort, type CategoryKind, type Measure } from \"../../lib/chart-categories\";\nimport { ChartFrameContext } from \"./ChartWrapper\";\nimport { valueAxisTicks } from \"./value-format\";\nimport { formatLocale } from \"../../lib/format-locale\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\ninterface TooltipEntry {\n name: string;\n value: number | string;\n color: string;\n dataKey?: string;\n payload?: Record<string, unknown>;\n}\n\ninterface ChartTooltipContentProps {\n active?: boolean;\n payload?: TooltipEntry[];\n label?: string;\n}\n\nconst hasLabel = (label: unknown) => label != null && label !== \"\" && typeof label !== \"number\";\n/**\n * A series' name. A chart without a category label (a pie's slice, a funnel's stage, a treemap's tile) names the item by\n * its row's `name`; on an axis chart the row's `name` is the category, already shown as the label, so the series keeps\n * its own (a row keyed by `name` read \"Alice: Alice 20\" instead of \"Alice: Hours 20\").\n */\nconst entryName = (entry: TooltipEntry, label: unknown) =>\n (!hasLabel(label) && typeof entry.payload?.name === \"string\" && entry.payload.name) || entry.name;\n/** A value as the tooltip shows it: in full, with the chart's unit (Sprint 25.17 A27), else grouped in the locale given. */\nconst entryValue = (entry: TooltipEntry, format: ((value: number, dataKey?: string) => string) | undefined, locale: string | undefined) =>\n (typeof entry.value === \"number\" ? (format ? format(entry.value, entry.dataKey) : entry.value.toLocaleString(locale)) : entry.value);\n\n/** What the live region says for the active point: its category, then each series' name and value. */\nexport function tooltipAnnouncement(label: unknown, payload: TooltipEntry[] | undefined, format?: (value: number, dataKey?: string) => string, locale: string | undefined = formatLocale()): string {\n if (!payload?.length) return \"\";\n const values = payload.map((entry) => `${entryName(entry, label)} ${entryValue(entry, format, locale)}`).join(\", \");\n return hasLabel(label) ? `${String(label)}: ${values}` : values;\n}\n\n/**\n * The chart's tooltip box. What it shows is also said in the chart's `role=\"status\"` `aria-live=\"polite\"` region, which\n * sits outside the drawing (a graphic's children are presentational) and starts empty, so the category and the values\n * are heard as the pointer or the arrow keys move (WCAG 4.1.3). Outside a library chart the region wraps the box.\n */\nexport function ChartTooltipContent({ active, payload, label }: ChartTooltipContentProps) {\n const bgSurface = useResolvedToken(\"--ds-bg-surface\");\n const borderSubtle = useResolvedToken(\"--ds-border-subtle\");\n const textPrimary = useResolvedToken(\"--ds-text-primary\");\n const textSecondary = useResolvedToken(\"--ds-text-secondary\");\n const { live, formatValue } = useContext(ChartFrameContext);\n // the values in the chart's locale (Sprint 25.20)\n const locale = useFormatLocale();\n\n const on = !!active && !!payload?.length;\n const showLabel = hasLabel(label);\n\n const box = on ? (\n <div\n className=\"rounded-[var(--ds-radius-md)] shadow-[var(--ds-shadow-popover)] font-[family-name:var(--ds-font-sans)] text-sm\"\n style={{\n backgroundColor: bgSurface,\n border: `var(--ds-border-width) solid ${borderSubtle}`,\n padding: \"var(--ds-space-2) var(--ds-space-3)\",\n }}\n >\n {showLabel && (\n <p className=\"font-medium mb-ds-1\" style={{ color: textPrimary }}>\n {label}\n </p>\n )}\n {payload!.map((entry, i) => {\n const dotColor = (entry.payload?.fill as string) || entry.color || textSecondary;\n return (\n <div key={i} className=\"flex items-center gap-ds-2\" style={{ marginTop: i > 0 ? 2 : 0 }}>\n <span\n className=\"shrink-0 rounded-[var(--ds-radius-full)]\"\n style={{ width: 8, height: 8, backgroundColor: dotColor }}\n />\n <span style={{ color: textSecondary }}>{entryName(entry, label)}:</span>\n <span className=\"tabular-nums\" style={{ color: textPrimary }}>\n {entryValue(entry, formatValue, locale)}\n </span>\n </div>\n );\n })}\n </div>\n ) : null;\n\n if (live) {\n return (\n <>\n {box}\n {createPortal(on ? tooltipAnnouncement(label, payload, formatValue, locale) : \"\", live)}\n </>\n );\n }\n return (\n <div role=\"status\" aria-live=\"polite\">\n {box}\n </div>\n );\n}\n\ninterface ChartLegendContentProps {\n payload?: Array<{\n value: string;\n color: string;\n dataKey?: string;\n }>;\n}\n\n/** A legend entry's outline: the series' stroke when it has one (a soft bar's solid edge, a line), else its colour. */\nfunction swatchEdge(entry: { color?: string; payload?: unknown }): string | undefined {\n const stroke = (entry.payload as { stroke?: unknown } | undefined)?.stroke;\n return typeof stroke === \"string\" ? stroke : entry.color;\n}\n\nexport function ChartLegendContent({ payload }: ChartLegendContentProps) {\n const textSecondary = useResolvedToken(\"--ds-text-secondary\");\n\n if (!payload?.length) return null;\n\n return (\n <div className=\"flex flex-wrap justify-center gap-y-ds-1 gap-x-ds-4 font-[family-name:var(--ds-font-sans)] text-sm\">\n {payload.map((entry, i) => (\n <div key={i} className=\"flex items-center gap-ds-1.5\">\n <span\n className=\"shrink-0 rounded-[var(--ds-radius-full)]\"\n // the series' own fill inside its outline (a soft bar's solid stroke), so a 30% tint stays visible (C4)\n style={{ width: 10, height: 10, backgroundColor: entry.color, border: `1.5px solid ${swatchEdge(entry)}` }}\n />\n <span style={{ color: textSecondary }}>{entry.value}</span>\n </div>\n ))}\n </div>\n );\n}\n\n/** Legend items in the order the chart draws its series: by dataKey (bars, lines, areas, radars) or by name (a pie's slices). */\nexport function seriesSorter(order: ReadonlyArray<string>, by: \"dataKey\" | \"value\" = \"dataKey\") {\n return (item: { dataKey?: unknown; value?: unknown }) => {\n const key = by === \"dataKey\" ? item.dataKey : item.value;\n const i = order.indexOf(String(key));\n return i < 0 ? order.length : i;\n };\n}\n\n/**\n * Sprint 25.9, A2: the chart's legend is Recharts' own Legend portalled into the slot below the drawing, so it no longer\n * takes its height from the plot. It keeps ChartLegendContent and its swatch, and follows the series' order, not the\n * alphabet (Recharts' default `itemSorter: \"value\"`). Rendered once the slot exists, so it never lands in the drawing.\n */\nexport function ChartLegend({ order, by = \"dataKey\" }: { order: ReadonlyArray<string>; by?: \"dataKey\" | \"value\" }) {\n const { legend } = useContext(ChartFrameContext);\n const orderKey = order.join(\"\\u0001\");\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the order is compared by value\n const sorter = useMemo(() => seriesSorter(order, by), [orderKey, by]);\n if (!legend) return null;\n return <Legend portal={legend} content={<ChartLegendContent />} itemSorter={sorter} wrapperStyle={{ paddingTop: \"var(--ds-space-3)\" }} />;\n}\n\nexport function useGridStroke(): string {\n return useResolvedToken(\"--ds-border-subtle\");\n}\n\nexport function useAxisStyle() {\n const textMuted = useResolvedToken(\"--ds-text-muted\");\n\n return {\n tick: {\n fontSize: \"var(--ds-font-size-xs)\",\n fontFamily: \"var(--ds-font-sans)\",\n fill: textMuted,\n // Sprint 25.9: Recharts paints a default tick's text with the axis stroke (#666 unless set), not with fill, so the\n // value axes drew their numbers at about 2.6:1 on dark cards (WCAG 1.4.3 asks 4.5:1). Every axis that spreads this\n // hides its axis and tick lines, so the stroke only colours the text.\n stroke: textMuted,\n },\n };\n}\n\nexport function useRadius(): number {\n const val = useResolvedToken(\"--ds-radius-md\");\n const parsed = parseInt(val, 10);\n return isNaN(parsed) ? 6 : parsed;\n}\n/**\n * Recharts' `tick` prop as an object only passes SVG-valid properties.\n * Props like `maxLines`, `verticalAnchor` are stripped. We must use a\n * function to pass them to the internal Text component.\n */\nexport function xAxisTick(props: Record<string, unknown>) {\n // No width box (Sprint 25.3 C12): with one, Recharts measured \"20 Aug\" in a hidden span that did not carry the\n // chart's font, judged it too wide for its share of the axis and wrapped or truncated it. Without a width Text never\n // wraps or truncates; `interval` (preserveStartEnd) thins colliding ticks and keeps the first and last. Recharts' own\n // Text keeps the axis's auto height right, which a bare <text> does not (the label was clipped 8px in the pass).\n // Scale axes (dates, numbers) keep this tick; a names axis takes namesTick.\n const { x, y, payload, width: _width, visibleTicksCount: _count, ...rest } = props as {\n x: number; y: number; payload: { value: string };\n width?: number; visibleTicksCount?: number; [k: string]: unknown;\n };\n return (\n <Text {...rest} x={x} y={y} textAnchor=\"middle\" verticalAnchor=\"start\">\n {payload.value}\n </Text>\n );\n}\n\nexport function yAxisTick(props: Record<string, unknown>) {\n const { x, y, payload, ...rest } = props as { x: number; y: number; payload: { value: string };[k: string]: unknown };\n return (\n <Text {...rest} x={x} y={y} textAnchor=\"end\" verticalAnchor=\"middle\" width={200} maxLines={2}>\n {payload.value}\n </Text>\n );\n}\n\n/* ── Names on a category axis (Sprint 25.9, A3) ─────────────────────────── */\n\n/** The line height of a two-line name, in em. */\nconst LINE_EM = 1.2;\n/** The least space between two names under an upright chart. */\nexport const NAME_GAP = 8;\n/**\n * A sideways name's inset from its column: Recharts draws it tickSize + tickMargin (8 px) left of the axis edge, and\n * the chart's own margin leaves 4 px on the left.\n */\nexport const NAME_COLUMN_INSET = 12;\n\n/**\n * The tick for a names axis: each name fitted to its band — one line; else two lines split at a space; else \"…\" on\n * the second — inside one `<g className={props.className}>`, so Recharts sizes the axis for both lines (two Texts each\n * carrying the tick's class leave the axis sized for one, and the second line clipped). The full name is the label's\n * `<title>`. Upright, the band is the axis width over the ticks it draws; sideways it is the name column the chart sets.\n * Without a measurer (no canvas) every name shows in full on one line.\n */\nexport function namesTick(measure: Measure | null, orientation: \"x\" | \"y\", column?: number) {\n return function NamesTick(props: Record<string, unknown>) {\n const { x, y, payload, width, visibleTicksCount, className, fill, fontSize, fontFamily } = props as {\n x: number; y: number; payload?: { value?: unknown }; width?: number; visibleTicksCount?: number;\n className?: string; fill?: string; fontSize?: string | number; fontFamily?: string;\n };\n const name = String(payload?.value ?? \"\");\n const room = orientation === \"x\"\n ? (Number(width) || 0) / Math.max(1, Number(visibleTicksCount) || 1) - NAME_GAP\n : (column ?? (Number(width) || 0)) - NAME_COLUMN_INSET;\n const fit = fitLabel(name, room, measure);\n const text = { fill, fontSize, fontFamily, stroke: \"none\" };\n // upright: the first line's top at y (Recharts' verticalAnchor \"start\"); sideways: the lines centred on the row\n const firstDy = orientation === \"x\" ? 0.71 : 0.355 - ((fit.lines.length - 1) * LINE_EM) / 2;\n return (\n <g className={className} data-cut={fit.cut ? \"\" : undefined} data-lines={fit.lines.length}>\n <title>{name}</title>\n {fit.lines.map((line, i) => (\n <text key={i} x={x} y={y} dy={`${firstDy + i * LINE_EM}em`} textAnchor={orientation === \"x\" ? \"middle\" : \"end\"} {...text}>\n {line}\n </text>\n ))}\n </g>\n );\n };\n}\n\nexport type XAxisInterval = number | \"preserveStart\" | \"preserveEnd\" | \"preserveStartEnd\" | \"equidistantPreserveStart\";\n\nexport interface AxisMeasure {\n /** Text widths in the axis's resolved font, or null (no canvas: jsdom). */\n measure: Measure | null;\n /** The resolved axis font size, px. */\n px: number;\n /** One row of a row chart, px (--ds-chart-row as the page resolves it). */\n rowPx: number;\n /** The chart wrapper's width, px. */\n width: number;\n}\n\ntype FontSet = { ready: Promise<unknown>; addEventListener?: (t: string, f: () => void) => void; removeEventListener?: (t: string, f: () => void) => void };\n\n/**\n * The chart's measurer: the axis font read from the wrapper's probe (so `calc()` font tokens measure right), and the\n * wrapper's width. Re-read when the wrapper resizes and when web fonts land (the same font string then measures\n * differently, so the cache starts again).\n */\nexport function useAxisMeasure(ref: RefObject<HTMLDivElement | null>, enabled = true): AxisMeasure {\n const [state, setState] = useState<AxisMeasure>({ measure: null, px: 12, rowPx: 32, width: 0 });\n useLayoutEffect(() => {\n const el = ref.current;\n if (!enabled || !el) return;\n let live = true;\n let font = \"\";\n const update = (fresh = false) => {\n if (!live) return;\n const measured = el.clientWidth;\n const probe = el.querySelector<HTMLElement>(\"[data-chart-probe]\");\n const row = probe?.getBoundingClientRect().height ?? 0;\n const next = createAxisMeasurer(el);\n setState((prev) => {\n // no width is no layout (a hidden tab, or the moment headless Chrome takes a full-page screenshot): keep the last\n const width = measured > 0 ? measured : prev.width;\n const rowPx = row > 0 ? row : prev.rowPx;\n if (!next) return prev.width === width ? prev : { ...prev, width };\n if (!fresh && next.font === font && prev.measure && prev.width === width && prev.rowPx === rowPx) return prev;\n const keep = !fresh && next.font === font && prev.measure;\n font = next.font;\n return { measure: keep ? prev.measure : next.measure, px: next.px, rowPx, width };\n });\n };\n update(true);\n const ro = typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(() => update()) : null;\n ro?.observe(el);\n const fonts = (typeof document !== \"undefined\" ? (document as Document & { fonts?: FontSet }).fonts : undefined);\n const landed = () => update(true);\n fonts?.ready.then(landed, () => {});\n fonts?.addEventListener?.(\"loadingdone\", landed);\n return () => {\n live = false;\n ro?.disconnect();\n fonts?.removeEventListener?.(\"loadingdone\", landed);\n };\n }, [ref, enabled]);\n return state;\n}\n\n/** The value axis's width on an upright chart: its widest tick label, as the axis formats it (Sprint 25.17 A27). */\nexport function valueAxisWidth(values: number[], measure: Measure, format: (value: number) => string = String): number {\n const ticks = valueAxisTicks(values);\n if (!ticks.length) return Math.ceil(measure(format(0))) + 8;\n return Math.ceil(Math.max(...ticks.map((t) => measure(format(t))))) + 8;\n}\n\n/** How far the switch looks back before turning an automatic sideways chart upright again (no flip at the boundary). */\nconst SWITCH_HYSTERESIS = 32;\n\n/**\n * D8: an upright chart of names turns sideways when a name would be cut to fewer than six characters at the chart's\n * width, and back when there's room: it turns upright again only once names would also fit a little narrower, so a\n * scrollbar appearing does not flip it back. The last decision is kept as state (information from the previous render).\n */\nexport function useSidewaysSwitch(enabled: boolean, names: string[], m: AxisMeasure, axisWidth: number, sideMargins: number): boolean {\n const [turned, setTurned] = useState(false);\n const key = names.join(\"\\u0001\");\n const cut = useMemo(() => {\n if (!enabled || !m.measure || m.width <= 0 || names.length === 0) return { here: false, narrower: false };\n const cutAt = (width: number) => namesCutShort(names, (width - sideMargins - axisWidth) / names.length - NAME_GAP, m.measure!);\n return { here: cutAt(m.width), narrower: cutAt(m.width - SWITCH_HYSTERESIS) };\n // names are compared by value\n }, [enabled, key, m.measure, m.width, axisWidth, sideMargins]); // eslint-disable-line react-hooks/exhaustive-deps\n // sideways as soon as names are cut short here; upright only when they fit here and a little narrower (no flip-flop)\n const decision = turned ? cut.here || cut.narrower : cut.here;\n if (decision !== turned) setTurned(decision);\n return decision;\n}\n\n/** A sideways chart's name column: its widest name, at most a third of the chart's width. */\nexport function nameColumn(names: string[], m: AxisMeasure): number | undefined {\n if (!m.measure || m.width <= 0) return undefined;\n const widest = names.reduce((w, n) => Math.max(w, m.measure!(n.replace(/\\s+/g, \" \").trim())), 0);\n return Math.max(24, Math.min(Math.ceil(widest) + NAME_COLUMN_INSET, Math.floor(m.width / 3)));\n}\n\n/** How many names take two lines in a name column (each makes its row one line taller). */\nexport function twoLineNames(names: string[], column: number | undefined, m: AxisMeasure): number {\n if (!m.measure || column === undefined) return 0;\n return names.filter((n) => fitLabel(n, column - NAME_COLUMN_INSET, m.measure).lines.length > 1).length;\n}\n\n/** The widest label in the chart's own axis font (canvas measureText), or null where there is no canvas (jsdom). */\nfunction widestLabel(el: HTMLElement, labels: string[]): number | null {\n const measurer = createAxisMeasurer(el);\n if (!measurer) return null;\n return labels.reduce((w, l) => Math.max(w, measurer.measure(l)), 0);\n}\n\nconst TICK_GAP = 12; // the least space between two labels\nconst AXIS_RESERVE = 48; // the y-axis column and the chart's side margins\n\n/**\n * Sprint 25.4 C-11 (decision 7): the category ticks a chart shows. Recharts' preserveStartEnd thins colliding ticks\n * by its own measurement (without the chart's font) and keeps the last tick, so the labels fall unevenly (round 5:\n * 14 and 15 September missing). The chart measures its widest label with the resolved axis font, picks the step\n * that fits the axis width, and labels every step from the first category — the last only when it falls on the step.\n * Re-measured when the wrapper resizes and when the web fonts land. A numeric `override` (the chart's xAxisInterval\n * prop) is every Nth category and skips the measurement; the Recharts strings are treated as \"measured\" (round 13).\n *\n * Sprint 25.9, A3: this thinning is for dates and numbers only. A names axis (`kind` \"names\") is never thinned: every\n * name from the first render (interval 0, no explicit ticks, so duplicate names keep their own bands), each fitted to\n * its band by namesTick. The font is the axis font as the page resolves it (a probe), so `calc()` tokens measure right.\n */\nexport function useCategoryTicks(\n data: ReadonlyArray<Record<string, unknown>> | undefined,\n xAxisKey: string,\n ref: RefObject<HTMLDivElement | null>,\n override?: XAxisInterval,\n kind: CategoryKind = \"scale\",\n): { ticks?: string[]; interval: XAxisInterval; endMargin: number } {\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n const labelsKey = labels.join(\"\\u0001\");\n const [ticks, setTicks] = useState<string[] | undefined>(undefined);\n // Half the widest label: the chart's right margin, so the last label (centred on the last point) is not clipped.\n const [endMargin, setEndMargin] = useState(4);\n // Only a number is an override (every Nth category). The Recharts strings — \"preserveStartEnd\" and friends — are the\n // thinning this hook replaced (round 13: a builder passed the old default by name and got uneven labels again), so\n // they mean \"measured\" too.\n const numeric = typeof override === \"number\" ? override : undefined;\n const names = kind === \"names\";\n useEffect(() => {\n const el = ref.current;\n if (names || numeric !== undefined || !el || labels.length === 0) return;\n let live = true;\n const compute = () => {\n if (!live) return;\n // no width is no layout (a hidden tab, or the moment headless Chrome takes a full-page screenshot): keep the last\n if (el.clientWidth <= 0) return;\n const widest = widestLabel(el, labels);\n const plot = el.clientWidth - AXIS_RESERVE;\n if (widest == null || plot <= 0) { setTicks(undefined); return; }\n setEndMargin(Math.max(4, Math.ceil(widest / 2)));\n const fits = Math.max(1, Math.floor(plot / (widest + TICK_GAP)));\n const step = Math.ceil(labels.length / fits);\n // every k-th label from the first, explicitly — an explicit list keeps Recharts from thinning on its own\n // measurement even when every label fits (round 5: \"16 Sep\" dropped at full width)\n setTicks(labels.filter((_, i) => i % step === 0));\n };\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(compute);\n ro.observe(el);\n const fonts = (document as Document & { fonts?: { ready: Promise<unknown> } }).fonts;\n fonts?.ready.then(compute, () => {});\n return () => { live = false; ro.disconnect(); };\n // labels are compared by value\n }, [labelsKey, numeric, names, ref]); // eslint-disable-line react-hooks/exhaustive-deps\n if (names) return { interval: 0, endMargin: 4 };\n if (numeric !== undefined) return { interval: numeric, endMargin: 4 };\n return ticks ? { ticks, interval: 0, endMargin } : { interval: \"preserveStartEnd\", endMargin: 4 };\n}\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n BarChart as RechartsBarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Rectangle,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { categoryKind as guessCategoryKind } from \"../../lib/chart-categories\";\nimport {\n ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useRadius, xAxisTick, namesTick, useCategoryTicks,\n useAxisMeasure, useSidewaysSwitch, valueAxisWidth, nameColumn, twoLineNames, type XAxisInterval,\n} from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisExtent, axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, CHART_ROW, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { useHydrated } from \"../../lib/hydrated\";\n\nexport interface BarDef {\n dataKey: string;\n label?: string;\n soft?: boolean;\n /**\n * Bars with the same stackId stack into one column (Sprint 25.7, C4); a bar without one stands alone. BarChart's\n * `stacked` puts every bar without a stackId into one stack. The same field works in CompositeChart, where lines\n * draw over the stacks.\n */\n stackId?: string;\n}\n\n/** The stack a bar joins: its own stackId, else the one `stacked` makes for every bar. */\nexport function barStackOf(bar: BarDef, stacked: boolean): string | undefined {\n return bar.stackId ?? (stacked ? \"stack\" : undefined);\n}\n\n/** Some bar stacks. Its chart then stacks both ways from zero (stackOffset \"sign\"), so a negative series sits below it. */\nexport function anyStack(bars: BarDef[], stacked: boolean): boolean {\n return bars.some((bar) => barStackOf(bar, stacked) != null);\n}\n\n/** How many bars stand side by side in one category: one per stack, one per bar on its own. */\nexport function barGroups(bars: BarDef[], stacked: boolean): number {\n return Math.max(1, new Set(bars.map((bar, i) => barStackOf(bar, stacked) ?? `\\u0000${i}`)).size);\n}\n\n/**\n * The bar's shape: only the end segment of each stack is rounded, per column and per side of zero — the top of the\n * positive side, the bottom of the negative one — so a stack whose last series is zero in a column rounds the segment\n * that ends it there. A bar on its own rounds its end.\n */\nexport function barShape(bars: BarDef[], index: number, stacked: boolean, radius: number, horizontal = false) {\n const round: [number, number, number, number] = horizontal ? [0, radius, radius, 0] : [radius, radius, 0, 0];\n const square: [number, number, number, number] = [0, 0, 0, 0];\n const stack = barStackOf(bars[index], stacked);\n const above = stack == null ? [] : bars.filter((b, j) => j > index && barStackOf(b, stacked) === stack);\n // Recharts hands the shape the bar's geometry and its row of data; it draws a negative bar's rounded corners at its\n // far end itself\n const Shape = (props: unknown) => {\n const p = props as { payload?: Record<string, unknown> };\n const row = p.payload ?? {};\n const down = Number(row[bars[index].dataKey]) < 0;\n const onTop = above.every((b) => {\n const value = Number(row[b.dataKey]);\n return !(down ? value < 0 : value > 0);\n });\n return <Rectangle {...(props as object)} radius={onTop ? round : square} />;\n };\n return Shape;\n}\n\n/** The values the value axis must reach: each bar on its own, and each stack up and down from zero (axisExtent). */\nfunction valueExtent(data: Record<string, unknown>[], bars: BarDef[], stacked: boolean): number[] {\n return axisExtent(data, bars.map((bar) => ({ dataKey: bar.dataKey, stack: barStackOf(bar, stacked) ?? null })));\n}\n\n/** A title line's height, px, in the axis font. */\nconst titleLine = (px: number) => Math.ceil(px * 1.5) + 4;\n/** The same in CSS, for a row chart's height. */\nconst TITLE_LINE_CSS = \"calc(1.5 * var(--ds-font-size-xs) + 4px)\";\n\nexport interface BarChartProps {\n /**\n * Which category ticks show on an axis of dates or numbers. Leave it out: the chart measures its widest label with\n * the chart's font and labels every k-th category from the first, the last only when it falls on the step (Sprint\n * 25.4 C-11, decision 7). A number labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are\n * accepted for compatibility and mean the same measured labelling (round 13). A names axis is never thinned.\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n bars: BarDef[];\n xAxisKey: string;\n /**\n * \"auto\" (the default): the chart sizes itself — sideways, a row per category; upright, two wide to one high. A\n * preset or a number overrides it; inside a ChartContainer, the container's own height wins.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** Every bar without a stackId joins one stack. */\n stacked?: boolean;\n /**\n * Bars running sideways, one row per category. Leave it out: an upright chart of names turns itself sideways when a\n * name would be cut to fewer than six characters, and back when there's room (D8). true or false forces either.\n */\n horizontal?: boolean;\n /**\n * What the categories are. \"names\" are never skipped: each wraps onto two lines, then ends with \"…\", with the full\n * name on hover. \"scale\" (dates, times, numbers) is labelled at an even step. Leave it out: guessed from the labels.\n */\n categoryKind?: \"names\" | \"scale\";\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n /** The category axis's title, as drawn upright (below it). A sideways chart puts the category title above its names. */\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const BarChart = markChart(forwardRef<HTMLDivElement, BarChartProps>(function BarChart({\n data,\n bars,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n horizontal,\n categoryKind,\n showGrid = true,\n showTooltip = true,\n showLegend,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n // its labels' kind: by the server's locale while a server-rendered page hydrates (both sides alike), by the browser's\n // languages from then on, as before 0.27.0 (the review: a German browser's month names on an English page)\n const hydrated = useHydrated();\n const kind = categoryKind ?? guessCategoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? undefined : locale);\n const names = kind === \"names\";\n const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);\n const values = useMemo(() => valueExtent(data ?? [], bars, stacked), [data, bars, stacked]);\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n const axisWidth = useMemo(\n () => (measured.measure ? valueAxisWidth(values, measured.measure, tickFormat) : 0),\n [measured.measure, values, tickFormat],\n );\n const turned = useSidewaysSwitch(horizontal === undefined && names, labels, measured, axisWidth, 8);\n const sideways = horizontal ?? turned;\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways || names ? \"names\" : \"scale\");\n const column = sideways ? nameColumn(labels, measured) : undefined;\n const upright = useMemo(() => namesTick(measured.measure, \"x\"), [measured.measure]);\n const rows = useMemo(() => namesTick(measured.measure, \"y\", column), [measured.measure, column]);\n const solidColors = useChartColors(bars.length, false);\n const softColors = useChartColors(bars.length, true);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const legendVisible = showLegend ?? bars.length >= 2;\n\n // Axis titles follow their data: a chart that turned itself sideways moves the value title under the value axis and\n // the category title above the names. Every title is horizontal (Analysis Function; data_visualisation#22).\n const valueTitle = horizontal === true ? xAxisLabel : yAxisLabel;\n const categoryTitle = horizontal === true ? yAxisLabel : xAxisLabel;\n const topTitle = sideways ? categoryTitle : valueTitle;\n const bottomTitle = sideways ? valueTitle : categoryTitle;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const bottomLabel = bottomTitle ? { value: bottomTitle, position: \"insideBottom\" as const, offset: -2, style: axisLabelStyle } : undefined;\n\n const groups = barGroups(bars, stacked);\n const perCategory = 1 + 0.5 * (groups - 1);\n const titles = [topTitle, bottomTitle].filter(Boolean).length;\n const size = sideways\n ? {\n model: \"rows\" as const,\n units: labels.length * perCategory,\n lines: twoLineNames(labels, column, measured),\n axis: titles ? `calc(${CHART_ROW} + ${titles} * ${TITLE_LINE_CSS})` : CHART_ROW,\n }\n : { model: \"ratio\" as const };\n // bars keep their thickness when the chart grows in a row: the rows spread instead\n const maxBarSize = sideways ? Math.max(4, Math.round((measured.rowPx * perCategory * 0.7) / groups)) : undefined;\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={size}\n chart=\"bar\"\n categoryKind={kind}\n categories={data.length}\n categoryAxis={sideways ? \"y\" : \"x\"}\n sideways={sideways}\n axisTitle={topTitle}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsBarChart\n data={data}\n layout={sideways ? \"vertical\" : \"horizontal\"}\n stackOffset={anyStack(bars, stacked) ? \"sign\" : undefined}\n // names are fitted to their bands, so nothing hangs past the last bar: 4 px, not a margin sized from them\n margin={{ top: 4 + (topTitle ? titleLine(measured.px) : 0), right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} vertical={!sideways} horizontal />\n )}\n {sideways ? (\n <>\n <XAxis type=\"number\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" label={bottomLabel} tickFormatter={tickFormat} />\n <YAxis\n dataKey={xAxisKey}\n type=\"category\"\n width={column ?? \"auto\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n interval={0}\n tick={rows}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={names ? upright : xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={bottomLabel}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n </>\n )}\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={{ fill: \"var(--ds-bg-muted)\", opacity: 0.5 }} />}\n {legendVisible && <ChartLegend order={bars.map((b) => b.dataKey)} />}\n {bars.map((bar, i) => (\n <Bar\n key={bar.dataKey}\n dataKey={bar.dataKey}\n name={bar.label ?? bar.dataKey}\n fill={bar.soft ? softColors[i] : solidColors[i]}\n // a soft fill is a 30% tint: the solid outline keeps the bar's edge at the colour's own contrast (WCAG 1.4.11)\n stroke={bar.soft ? solidColors[i] : undefined}\n strokeWidth={bar.soft ? 1 : undefined}\n shape={barShape(bars, i, stacked, radius, sideways)}\n stackId={barStackOf(bar, stacked)}\n maxBarSize={maxBarSize}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsBarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n LineChart as RechartsLineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, xAxisTick, useCategoryTicks, useAxisMeasure, type XAxisInterval } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface LineDef {\n dataKey: string;\n label?: string;\n dashed?: boolean;\n}\n\nexport interface LineChartProps {\n /**\n * Which category ticks show. Leave it out: the chart measures its widest label with the chart's font and labels every\n * k-th category from the first, the last only when it falls on the step (Sprint 25.4 C-11, decision 7). A number\n * labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are accepted for compatibility and\n * mean the same measured labelling — they never hand the ticks back to Recharts' thinning (round 13).\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n lines: LineDef[];\n xAxisKey: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n curved?: boolean;\n showDots?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const LineChart = markChart(forwardRef<HTMLDivElement, LineChartProps>(function LineChart({\n data,\n lines,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n curved = true,\n showDots = false,\n showGrid = true,\n showTooltip = true,\n showLegend,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const values = useMemo(() => seriesValues(data ?? [], lines.map((s) => s.dataKey), false), [data, lines]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // a line runs over a scale (dates, times, numbers): its labels are thinned at an even step, never fitted as names\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, \"scale\");\n const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);\n const colors = useChartColors(lines.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? lines.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"line\"\n categoryKind=\"scale\"\n categories={data.length}\n categoryAxis=\"x\"\n axisTitle={yAxisLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsLineChart data={data} margin={{ top, right: xTicks.endMargin, bottom: 4, left: 4 }} accessibilityLayer>\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={xAxisLabel ? { value: xAxisLabel, position: \"insideBottom\", offset: -2, style: axisLabelStyle } : undefined}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={lines.map((l) => l.dataKey)} />}\n {lines.map((line, i) => (\n <Line\n key={line.dataKey}\n type={curved ? \"monotone\" : \"linear\"}\n dataKey={line.dataKey}\n name={line.label ?? line.dataKey}\n stroke={colors[i]}\n strokeWidth={2}\n strokeDasharray={line.dashed ? \"5 5\" : undefined}\n dot={showDots}\n activeDot={{ r: 5, strokeWidth: 2 }}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsLineChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId, useMemo, useRef, type Ref } from \"react\";\nimport {\n AreaChart as RechartsAreaChart,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, xAxisTick, useCategoryTicks, useAxisMeasure, type XAxisInterval } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface AreaDef {\n dataKey: string;\n label?: string;\n}\n\nexport interface AreaChartProps {\n /**\n * Which category ticks show. Leave it out: the chart measures its widest label with the chart's font and labels every\n * k-th category from the first, the last only when it falls on the step (Sprint 25.4 C-11, decision 7). A number\n * labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are accepted for compatibility and\n * mean the same measured labelling — they never hand the ticks back to Recharts' thinning (round 13).\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n areas: AreaDef[];\n xAxisKey: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n stacked?: boolean;\n curved?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n gradient?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const AreaChart = markChart(forwardRef<HTMLDivElement, AreaChartProps>(function AreaChart({\n data,\n areas,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n curved = true,\n showGrid = true,\n showTooltip = true,\n showLegend,\n gradient = true,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const values = useMemo(() => seriesValues(data ?? [], areas.map((s) => s.dataKey), stacked), [data, areas, stacked]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n // an area runs over a scale (dates, times, numbers): its labels are thinned at an even step, never fitted as names\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, \"scale\");\n const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);\n const instanceId = useId();\n const solidColors = useChartColors(areas.length, false);\n const softColors = useChartColors(areas.length, true);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? areas.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n const top = 4 + (yAxisLabel ? Math.ceil(measured.px * 1.5) + 4 : 0);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"area\"\n categoryKind=\"scale\"\n categories={data.length}\n categoryAxis=\"x\"\n axisTitle={yAxisLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsAreaChart data={data} margin={{ top, right: xTicks.endMargin, bottom: 4, left: 4 }} accessibilityLayer>\n <defs>\n {areas.map((area, i) => (\n <linearGradient key={area.dataKey} id={`gradient-${instanceId}-${area.dataKey}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={softColors[i]} stopOpacity={1} />\n <stop offset=\"95%\" stopColor={softColors[i]} stopOpacity={0.1} />\n </linearGradient>\n ))}\n </defs>\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={xAxisTick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={xAxisLabel ? { value: xAxisLabel, position: \"insideBottom\", offset: -2, style: axisLabelStyle } : undefined}\n />\n <YAxis width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={areas.map((a) => a.dataKey)} />}\n {areas.map((area, i) => (\n <Area\n key={area.dataKey}\n type={curved ? \"monotone\" : \"linear\"}\n dataKey={area.dataKey}\n name={area.label ?? area.dataKey}\n stroke={solidColors[i]}\n strokeWidth={2}\n fill={gradient ? `url(#gradient-${instanceId}-${area.dataKey})` : softColors[i]}\n stackId={stacked ? \"stack\" : undefined}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsAreaChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n PieChart as RechartsPieChart,\n Pie,\n Cell,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface PieChartProps {\n data: { name: string; value: number; [key: string]: unknown }[];\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n donut?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n showLabels?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const PieChart = markChart(forwardRef<HTMLDivElement, PieChartProps>(function PieChart({\n data,\n height = \"auto\",\n donut = false,\n showTooltip = true,\n showLegend = true,\n showLabels = false,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n const renderLabel = showLabels\n ? ({ percent }: { percent?: number }) => `${((percent ?? 0) * 100).toFixed(0)}%`\n : false;\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"pie\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsPieChart accessibilityLayer>\n <Pie\n data={data}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n outerRadius=\"75%\"\n innerRadius={donut ? \"55%\" : 0}\n label={renderLabel}\n labelLine={showLabels}\n isAnimationActive={isAnimated}\n fontSize=\"var(--ds-font-size-xs)\"\n fontFamily=\"var(--ds-font-sans)\"\n >\n {data.map((_, i) => (\n <Cell key={i} fill={colors[i % colors.length]} />\n ))}\n </Pie>\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={data.map((d) => d.name)} by=\"value\" />}\n </RechartsPieChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n ComposedChart,\n Bar,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { categoryKind as guessCategoryKind } from \"../../lib/chart-categories\";\nimport {\n ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useRadius, xAxisTick, namesTick, useCategoryTicks,\n useAxisMeasure, useSidewaysSwitch, valueAxisWidth, nameColumn, twoLineNames, type XAxisInterval,\n} from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisExtent, axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, CHART_ROW, markChart } from \"./ChartWrapper\";\nimport { anyStack, barGroups, barShape, barStackOf, type BarDef } from \"./BarChart\";\nimport type { LineDef } from \"./LineChart\";\nimport { useFormatLocale } from \"../../lib/locale\";\nimport { useHydrated } from \"../../lib/hydrated\";\n\nexport interface CompositeChartProps {\n /**\n * Which category ticks show on an axis of dates or numbers. Leave it out: the chart measures its widest label with\n * the chart's font and labels every k-th category from the first, the last only when it falls on the step (Sprint\n * 25.4 C-11, decision 7). A number labels every Nth category instead. The Recharts strings (\"preserveStartEnd\") are\n * accepted for compatibility and mean the same measured labelling (round 13). A names axis is never thinned.\n */\n xAxisInterval?: XAxisInterval;\n data: Record<string, unknown>[];\n bars: BarDef[];\n lines: LineDef[];\n xAxisKey: string;\n /**\n * \"auto\" (the default): two wide to one high; sideways, a row per category. A preset or a number overrides it; a\n * ChartContainer's own height wins.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** Every bar without a stackId joins one stack; lines draw over it (Sprint 25.7, C4). A bar's stackId works too. */\n stacked?: boolean;\n /**\n * The lines on a second axis of their own, on the right, for a line whose unit differs from the bars'. Default: true\n * for bars side by side, false once the bars stack (`stacked` or a bar's stackId), so a capacity or a target line\n * reads against the stack's own scale. An explicit value wins.\n */\n dualAxis?: boolean;\n /**\n * What the categories are. \"names\" are never skipped: each wraps onto two lines, then ends with \"…\", with the full\n * name on hover. \"scale\" (dates, times, numbers) is labelled at an even step. Leave it out: guessed from the labels.\n */\n categoryKind?: \"names\" | \"scale\";\n /**\n * Bars running sideways, one row per category, with the lines crossing the rows. Leave it out: a chart of names turns\n * itself sideways when a name would be cut to fewer than six characters, and back when there's room (D8). true or\n * false forces either.\n */\n horizontal?: boolean;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n xAxisLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yAxisLabel?: string;\n /**\n * How the bars' values read (and the lines', on one axis): \"number\" (the default) is compact on the axis, in the\n * page's language (1M, 750K), and in full in the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function\n * formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n /** How the lines' values read on their own axis (dualAxis), when their unit differs from the bars'. Default: valueFormat. */\n lineValueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const CompositeChart = markChart(forwardRef<HTMLDivElement, CompositeChartProps>(function CompositeChart({\n data,\n bars,\n lines,\n xAxisKey,\n xAxisInterval,\n height = \"auto\",\n stacked = false,\n dualAxis = !anyStack(bars, stacked),\n categoryKind,\n horizontal,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n xAxisLabel,\n yAxisLabel,\n valueFormat,\n lineValueFormat = valueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? \"\")), [data, xAxisKey]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n // its labels' kind as BarChart reads it: the server's locale while hydrating, the browser's languages from then on\n const hydrated = useHydrated();\n const kind = categoryKind ?? guessCategoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? undefined : locale);\n const names = kind === \"names\";\n const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);\n // the bars' axis (and the lines', on one axis), and the lines' own on the right with a second axis\n const [values, lineValues] = useMemo(() => {\n // the bars' stacks up and down from zero, as BarChart reads them (axisExtent), and the lines on the same axis unless\n // they have their own\n const values = axisExtent(data ?? [], [\n ...bars.map((bar) => ({ dataKey: bar.dataKey, stack: barStackOf(bar, stacked) ?? null })),\n ...(dualAxis ? [] : lines.map((l) => ({ dataKey: l.dataKey, stack: null }))),\n ]);\n const lineValues = (data ?? []).flatMap((row) => lines.map((l) => Number(row[l.dataKey])));\n return [values, lineValues];\n }, [data, bars, lines, stacked, dualAxis]);\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const lineTickFormat = useMemo(() => axisTickFormatter(lineValues, lineValueFormat, locale), [lineValues, lineValueFormat, locale]);\n const fullFormat = useMemo(() => {\n const bar = fullValueFormatter(valueFormat, locale);\n const line = fullValueFormatter(dualAxis ? lineValueFormat : valueFormat, locale);\n const lineKeys = new Set(lines.map((l) => l.dataKey));\n return (value: number, dataKey?: string) => (dataKey && lineKeys.has(dataKey) ? line(value) : bar(value));\n }, [valueFormat, lineValueFormat, dualAxis, lines, locale]);\n // the bars' axis sets the left column's width; with a second axis the lines' ticks take the right edge\n const axisWidth = useMemo(() => {\n if (!measured.measure) return 0;\n return valueAxisWidth(values, measured.measure, tickFormat) + (dualAxis ? valueAxisWidth(lineValues, measured.measure, lineTickFormat) : 0);\n }, [measured.measure, values, lineValues, tickFormat, lineTickFormat, dualAxis]);\n const turned = useSidewaysSwitch(horizontal === undefined && names, labels, measured, axisWidth, 8);\n const sideways = horizontal ?? turned;\n const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, sideways ? \"names\" : kind);\n const column = sideways ? nameColumn(labels, measured) : undefined;\n const tick = useMemo(() => (names ? namesTick(measured.measure, \"x\") : xAxisTick), [names, measured.measure]);\n const rows = useMemo(() => namesTick(measured.measure, \"y\", column), [measured.measure, column]);\n const barSoftColors = useChartColors(bars.length, true);\n const barSolidColors = useChartColors(bars.length, false);\n const lineColors = useChartColors(lines.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n // axis titles follow their data: sideways, the value title goes under the value axis, the category title above the names\n const topTitle = sideways ? xAxisLabel : yAxisLabel;\n const bottomTitle = sideways ? yAxisLabel : xAxisLabel;\n const bottomLabel = bottomTitle ? { value: bottomTitle, position: \"insideBottom\" as const, offset: -2, style: axisLabelStyle } : undefined;\n const top = 4 + (topTitle ? Math.ceil(measured.px * 1.5) + 4 : 0);\n const groups = barGroups(bars, stacked);\n const perCategory = 1 + 0.5 * (groups - 1);\n const titles = [topTitle, bottomTitle].filter(Boolean).length + (sideways && dualAxis ? 1 : 0);\n const size = sideways\n ? {\n model: \"rows\" as const,\n units: labels.length * perCategory,\n lines: twoLineNames(labels, column, measured),\n axis: titles ? `calc(${CHART_ROW} + ${titles} * calc(1.5 * var(--ds-font-size-xs) + 4px))` : CHART_ROW,\n }\n : { model: \"ratio\" as const };\n const maxBarSize = sideways ? Math.max(4, Math.round((measured.rowPx * perCategory * 0.7) / groups)) : undefined;\n // the bars read against the left (or bottom) axis; the lines against their own when dualAxis\n const barAxis = sideways ? { xAxisId: \"left\" } : { yAxisId: \"left\" };\n const lineAxis = sideways ? { xAxisId: dualAxis ? \"right\" : \"left\" } : { yAxisId: dualAxis ? \"right\" : \"left\" };\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={size}\n chart=\"composite\"\n categoryKind={kind}\n categories={data.length}\n categoryAxis={sideways ? \"y\" : \"x\"}\n sideways={sideways}\n axisTitle={topTitle}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart\n data={data}\n layout={sideways ? \"vertical\" : \"horizontal\"}\n stackOffset={anyStack(bars, stacked) ? \"sign\" : undefined}\n // names are fitted to their bands, so nothing hangs past the last bar\n margin={{ top, right: sideways || names ? 4 : xTicks.endMargin, bottom: 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} vertical={!sideways} horizontal />}\n {sideways ? (\n <>\n <XAxis xAxisId=\"left\" type=\"number\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" label={bottomLabel} tickFormatter={tickFormat} />\n {dualAxis && <XAxis xAxisId=\"right\" type=\"number\" orientation=\"top\" {...axisStyle.tick} axisLine={false} tickLine={false} height=\"auto\" tickFormatter={lineTickFormat} />}\n <YAxis\n dataKey={xAxisKey}\n type=\"category\"\n width={column ?? \"auto\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n interval={0}\n tick={rows}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey={xAxisKey}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tick={tick}\n interval={xTicks.interval}\n ticks={xTicks.ticks}\n height=\"auto\"\n label={bottomLabel}\n />\n <YAxis yAxisId=\"left\" width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={tickFormat} />\n {dualAxis && (\n <YAxis yAxisId=\"right\" orientation=\"right\" width=\"auto\" {...axisStyle.tick} axisLine={false} tickLine={false} tickFormatter={lineTickFormat} />\n )}\n </>\n )}\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={[...bars.map((b) => b.dataKey), ...lines.map((l) => l.dataKey)]} />}\n {bars.map((bar, i) => (\n <Bar\n key={bar.dataKey}\n dataKey={bar.dataKey}\n name={bar.label ?? bar.dataKey}\n fill={barSoftColors[i]}\n // the soft fill is a 30% tint (1.3–1.4:1 on a dark card, Sprint 25.7 C4): the solid outline keeps the bar's\n // edge at the colour's own contrast against the card (WCAG 1.4.11), and separates stacked segments\n stroke={barSolidColors[i]}\n strokeWidth={1}\n shape={barShape(bars, i, stacked, radius, sideways)}\n stackId={barStackOf(bar, stacked)}\n maxBarSize={maxBarSize}\n {...barAxis}\n isAnimationActive={isAnimated}\n />\n ))}\n {lines.map((line, i) => (\n <Line\n key={line.dataKey}\n type=\"monotone\"\n dataKey={line.dataKey}\n name={line.label ?? line.dataKey}\n stroke={lineColors[i]}\n strokeWidth={2}\n strokeDasharray={line.dashed ? \"5 5\" : undefined}\n dot={false}\n {...lineAxis}\n isAnimationActive={isAnimated}\n />\n ))}\n </ComposedChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo, useRef, type Ref } from \"react\";\nimport {\n ScatterChart as RechartsScatterChart,\n Scatter,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n ZAxis,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend, useGridStroke, useAxisStyle, useAxisMeasure } from \"./ChartPrimitives\";\nimport { mergeRefs } from \"../../lib/slot\";\nimport { axisTickFormatter, fullValueFormatter, type ValueFormat } from \"./value-format\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface ScatterSeries {\n name: string;\n points: { x: number; y: number; z?: number }[];\n}\n\nexport interface ScatterChartProps {\n data: ScatterSeries[];\n xLabel?: string;\n /** The value axis's title, drawn horizontally above the axis. */\n yLabel?: string;\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showGrid?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n /**\n * How the y values read: \"number\" (the default) is compact on the axis from five digits up, in the page's language (1M, 750K), and in full in\n * the tooltip; \"percent\", \"milliseconds\" or \"bytes\" add their unit; a function formats both itself (Sprint 25.17 A27).\n */\n valueFormat?: ValueFormat;\n /** How the x values read, as valueFormat. Default \"number\". */\n xValueFormat?: ValueFormat;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const ScatterChart = markChart(forwardRef<HTMLDivElement, ScatterChartProps>(function ScatterChart({\n data,\n xLabel,\n yLabel,\n height = \"auto\",\n showGrid = true,\n showTooltip = true,\n showLegend,\n valueFormat,\n xValueFormat,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const [xTickFormat, yTickFormat, fullFormat] = useMemo(() => {\n const points = (data ?? []).flatMap((s) => s.points);\n const x = fullValueFormatter(xValueFormat, locale);\n const y = fullValueFormatter(valueFormat, locale);\n return [\n axisTickFormatter(points.map((p) => p.x), xValueFormat, locale),\n axisTickFormatter(points.map((p) => p.y), valueFormat, locale),\n (value: number, dataKey?: string) => (dataKey === \"x\" ? x(value) : dataKey === \"y\" ? y(value) : value.toLocaleString(locale)),\n ];\n }, [data, valueFormat, xValueFormat, locale]);\n const measured = useAxisMeasure(wrapperRef, !!yLabel && (data?.length ?? 0) > 0);\n const colors = useChartColors(data.length, false);\n const gridStroke = useGridStroke();\n const axisStyle = useAxisStyle();\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? data.length >= 2;\n const axisLabelStyle = { fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: axisStyle.tick.fill };\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper\n ref={mergeRefs(ref as Ref<HTMLElement>, wrapperRef as Ref<HTMLElement>) as Ref<HTMLDivElement>}\n height={height}\n size={{ model: \"ratio\" }}\n chart=\"scatter\"\n axisTitle={yLabel}\n formatValue={fullFormat}\n className={className}\n aria-label={ariaLabel}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsScatterChart\n margin={{ top: 8 + (yLabel ? Math.ceil(measured.px * 1.5) + 4 : 0), right: 8, bottom: xLabel ? 20 : 4, left: 4 }}\n accessibilityLayer\n >\n {showGrid && <CartesianGrid strokeDasharray=\"3 3\" stroke={gridStroke} />}\n <XAxis\n type=\"number\"\n dataKey=\"x\"\n name={xLabel ?? \"x\"}\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tickFormatter={xTickFormat}\n label={xLabel ? { value: xLabel, position: \"bottom\", offset: 0, style: { ...axisLabelStyle, textAnchor: \"middle\" } } : undefined}\n />\n <YAxis\n type=\"number\"\n dataKey=\"y\"\n name={yLabel ?? \"y\"}\n width=\"auto\"\n {...axisStyle.tick}\n axisLine={false}\n tickLine={false}\n tickFormatter={yTickFormat}\n />\n <ZAxis type=\"number\" dataKey=\"z\" range={[40, 400]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={data.map((s) => s.name)} by=\"value\" />}\n {data.map((series, i) => (\n <Scatter\n key={series.name}\n name={series.name}\n data={series.points}\n fill={colors[i]}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsScatterChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useMemo } from \"react\";\nimport {\n RadarChart as RechartsRadarChart,\n Radar,\n PolarGrid,\n PolarAngleAxis,\n PolarRadiusAxis,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\nimport { axisTickFormatter, fullValueFormatter, seriesValues, type ValueFormat } from \"./value-format\";\nimport { useFormatLocale } from \"../../lib/locale\";\n\nexport interface RadarDataKey {\n key: string;\n label?: string;\n}\n\nexport interface RadarChartProps {\n data: Record<string, unknown>[];\n dataKeys: RadarDataKey[];\n axisKey: string;\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n filled?: boolean;\n showDots?: boolean;\n showTooltip?: boolean;\n showLegend?: boolean;\n animated?: boolean;\n /** How the values read on the rings and in the tooltip; see ValueFormat (compact numbers by default). */\n valueFormat?: ValueFormat;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const RadarChart = markChart(forwardRef<HTMLDivElement, RadarChartProps>(function RadarChart({\n data,\n dataKeys,\n axisKey,\n height = \"auto\",\n filled = true,\n showDots = true,\n showTooltip = true,\n showLegend,\n animated,\n valueFormat = \"number\",\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const solidColors = useChartColors(dataKeys.length, false);\n const softColors = useChartColors(dataKeys.length, true);\n const isAnimated = useChartAnimation(animated);\n const legendVisible = showLegend ?? dataKeys.length >= 2;\n // the rings are a value axis: compact in the page's language, the tooltip in full (Sprint 25.17's review)\n const values = useMemo(() => seriesValues(data ?? [], dataKeys.map((dk) => dk.key)), [data, dataKeys]);\n // the chart's numbers in the locale the server and the hydrating browser share (Sprint 25.20)\n const locale = useFormatLocale();\n const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);\n const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"radar\" className={className} aria-label={ariaLabel} formatValue={fullFormat}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadarChart data={data} cx=\"50%\" cy=\"50%\" outerRadius=\"75%\" accessibilityLayer>\n <PolarGrid stroke=\"var(--ds-border-subtle)\" />\n <PolarAngleAxis\n dataKey={axisKey}\n tick={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: \"var(--ds-text-muted)\" }}\n />\n <PolarRadiusAxis\n tick={{ fontSize: \"var(--ds-font-size-xs)\", fontFamily: \"var(--ds-font-sans)\", fill: \"var(--ds-text-muted)\" }}\n tickFormatter={tickFormat}\n axisLine={false}\n />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {legendVisible && <ChartLegend order={dataKeys.map((dk) => dk.key)} />}\n {dataKeys.map((dk, i) => (\n <Radar\n key={dk.key}\n name={dk.label ?? dk.key}\n dataKey={dk.key}\n stroke={solidColors[i]}\n fill={filled ? softColors[i] : \"transparent\"}\n strokeWidth={2}\n dot={showDots ? { r: 3, fill: solidColors[i] } : false}\n isAnimationActive={isAnimated}\n />\n ))}\n </RechartsRadarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n RadialBarChart as RechartsRadialBarChart,\n RadialBar,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, ChartLegend } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface RadialBarChartProps {\n data: { name: string; value: number; max?: number; [key: string]: unknown }[];\n /** \"auto\" (the default): square. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n showLegend?: boolean;\n showLabels?: boolean;\n startAngle?: number;\n endAngle?: number;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const RadialBarChart = markChart(forwardRef<HTMLDivElement, RadialBarChartProps>(function RadialBarChart({\n data,\n height = \"auto\",\n showTooltip = true,\n showLegend = true,\n showLabels = false,\n startAngle = 90,\n endAngle = -270,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n const chartData = data.map((d, i) => ({\n ...d,\n fill: colors[i % colors.length],\n }));\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"square\" }} chart=\"radial-bar\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadialBarChart\n data={chartData}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius=\"20%\"\n outerRadius=\"90%\"\n startAngle={startAngle}\n endAngle={endAngle}\n accessibilityLayer\n >\n <RadialBar\n dataKey=\"value\"\n background={{ fill: \"var(--ds-bg-muted)\" }}\n label={showLabels ? { position: \"insideStart\", fill: \"var(--ds-text-primary)\", fontSize: \"var(--ds-font-size-xs)\" } : false}\n isAnimationActive={isAnimated}\n />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n {showLegend && <ChartLegend order={data.map((d) => d.name)} by=\"value\" />}\n </RechartsRadialBarChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n FunnelChart as RechartsFunnelChart,\n Funnel,\n Tooltip,\n LabelList,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\n/** A funnel stage takes a taller row than a sideways bar (Sprint 25.9, A2). */\nconst STAGE_ROWS = 1.5;\n\nexport interface FunnelChartProps {\n data: { name: string; value: number; [key: string]: unknown }[];\n /** \"auto\" (the default): a row per stage. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n /** Kept for compatibility: a funnel has no legend, its labels name the stages (Recharts gives it no legend entries). */\n showLegend?: boolean;\n showLabels?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const FunnelChart = markChart(forwardRef<HTMLDivElement, FunnelChartProps>(function FunnelChart({\n data,\n height = \"auto\",\n showTooltip = true,\n showLabels = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.length, false);\n const isAnimated = useChartAnimation(animated);\n\n const chartData = data.map((d, i) => ({\n ...d,\n fill: colors[i % colors.length],\n }));\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"rows\", units: data.length * STAGE_ROWS, axis: \"16px\" }} chart=\"funnel\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsFunnelChart accessibilityLayer>\n <Funnel dataKey=\"value\" data={chartData} isAnimationActive={isAnimated}>\n {showLabels && (\n <LabelList\n dataKey=\"name\"\n position=\"right\"\n fill=\"var(--ds-text-primary)\"\n fontSize=\"var(--ds-font-size-sm)\"\n fontFamily=\"var(--ds-font-sans)\"\n />\n )}\n </Funnel>\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </RechartsFunnelChart>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","// showcase/src/lib/token-algorithms.ts\n// The one source for all token generation helpers. The platform imports it through\n// platform/src/lib/token-algorithms.ts, a re-export (Sprint 25.7 review, 26 September 2026: no more synced copy).\n\nexport type HoverEffect = 'scale' | 'lift' | 'scale-lift'\n\nfunction hasScaleEffect(effect: HoverEffect): boolean {\n return effect === 'scale' || effect === 'scale-lift'\n}\n\nfunction hasLiftEffect(effect: HoverEffect): boolean {\n return effect === 'lift' || effect === 'scale-lift'\n}\n\nexport interface GradientConfig {\n accentMode: 'solid' | 'gradient'\n endHue: number\n angle: number\n hue: number\n sat: number\n endSat?: number\n endShade?: number\n}\n\nexport interface InteractiveHoverConfig {\n enabled: boolean\n effect: HoverEffect\n speed: number\n ease: string\n scale: number\n lift: number\n pressDepth: number\n}\n\nexport interface AmbientHoverConfig {\n enabled: boolean\n effect: HoverEffect\n speed: number\n ease: string\n scale: number\n lift: number\n}\n\nexport interface MotionDecisions {\n speed: number\n ease: string\n intensity?: 'none' | 'subtle' | 'moderate' | 'expressive'\n interactive?: InteractiveHoverConfig\n ambient?: AmbientHoverConfig\n}\n\n// ---------------------------------------------------------------------------\n// On-fill text (Sprint 20.10)\n// ---------------------------------------------------------------------------\n//\n// The colour of text and icons on a solid fill is decided by contrast, not by\n// preset: white when white reaches WCAG AA (4.5:1) over the fill, otherwise\n// the theme's darkest neutral. One function, `onFillText`, decides for every\n// fill the theme emits — the page accent (`--ds-text-on-primary`), the\n// independent sidebar and header accents, the three status fills and the five\n// palette bold fills — and nothing else decides on-fill colour.\n//\n// The decision uses a real conversion (OKLCH → OKLab → linear sRGB → relative\n// luminance) of the fill as the browser draws it: a colour outside sRGB has\n// each channel clipped, which is what Chrome renders (measured, Sprint 25.7\n// Part D; see oklchToLinearSrgbClamped) — not the chroma reduction CSS Color 4\n// describes, which this used until then. The status palettes are literal\n// OKLCH values at arbitrary lightness, and saturated fills near the gamut\n// edge render lighter than their mapped colour. `estimateContrastRatio` below\n// keeps its L³ proxy for the palette pair code that has always used it.\n\nexport interface Oklch { L: number; C: number; H: number }\n\n/**\n * The --ds-primary-{shade} scale from roots.css: lightness and the chroma\n * multiplier applied to --ds-sat-primary. The one table every literal accent\n * colour (gradient start and end, independent sidebar and header accents) is\n * computed from, so a flip at a given shade is the same flip everywhere.\n * A test pins it against the CSS.\n */\nexport const PRIMARY_SCALE: Record<number, { L: number; c: number }> = {\n 300: { L: 0.77, c: 0.150 },\n 400: { L: 0.66, c: 0.180 },\n 500: { L: 0.55, c: 0.200 },\n 600: { L: 0.47, c: 0.185 },\n 700: { L: 0.40, c: 0.165 },\n 800: { L: 0.33, c: 0.135 },\n 900: { L: 0.25, c: 0.100 },\n}\n\n/** Nearest step of the scale; a missing or malformed shade reads as 500 rather than throwing (stored decisions are read raw). */\nfunction scaleShade(shade: number): number {\n if (!Number.isFinite(shade)) return 500\n const s = Math.max(300, Math.min(900, shade))\n return Math.round(s / 100) * 100\n}\n\n/** The literal OKLCH of --ds-primary-{shade} at a saturation and hue. */\nexport function accentColour(shade: number, sat: number, hue: number): Oklch {\n const { L, c } = PRIMARY_SCALE[scaleShade(shade)]\n return { L, C: c * sat, H: hue }\n}\n\n/** Formats an OKLCH colour the way the emitters always have (L to 3 places, C to 4). */\nexport function oklchCss(colour: Oklch): string {\n return `oklch(${colour.L.toFixed(3)} ${colour.C.toFixed(4)} ${colour.H})`\n}\n\n/** Parses an `oklch(L C H)` literal (optional `/ alpha`). Returns null for anything else, including var() references. */\nexport function parseOklch(value: string): Oklch | null {\n const m = value.trim().match(/^oklch\\(\\s*([\\d.]+)(%?)\\s+([\\d.]+)\\s+([\\d.]+)(?:deg)?\\s*(?:\\/\\s*[\\d.%]+\\s*)?\\)$/i)\n if (!m) return null\n const L = m[2] ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n return { L, C: parseFloat(m[3]), H: parseFloat(m[4]) }\n}\n\nfunction oklchToLinearSrgb({ L, C, H }: Oklch): [number, number, number] {\n const h = (H * Math.PI) / 180\n const a = C * Math.cos(h)\n const b = C * Math.sin(h)\n const l_ = L + 0.3963377774 * a + 0.2158037573 * b\n const m_ = L - 0.1055613458 * a - 0.0638541728 * b\n const s_ = L - 0.0894841775 * a - 1.2914855480 * b\n const l = l_ * l_ * l_\n const m = m_ * m_ * m_\n const s = s_ * s_ * s_\n return [\n +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s,\n ]\n}\n\n/**\n * WCAG relative luminance of an OKLCH colour as the browser draws it: each\n * channel clipped to sRGB (oklchToLinearSrgbClamped) and rounded to the\n * nearest of the 256 steps an 8-bit sRGB surface has, then weighted. Contrast\n * decisions use the range Chrome's rounding can land in (luminanceRange); this\n * is its nearest value.\n */\nexport function oklchToLuminance(colour: Oklch): number {\n return srgbLuminance(oklchToSrgb(colour).map((v) => Math.round(v * 255) / 255) as [number, number, number])\n}\n\n/**\n * Linear sRGB channels as the browser renders them: an out-of-gamut colour has\n * each channel clipped to 0–1. Measured in Chrome 153 (Sprint 25.7 Part D): 211\n * of 211 oklch() colours outside sRGB came back within 1/255 of per-channel\n * clipping, from an sRGB canvas and from a screenshot alike. Reducing chroma to\n * the gamut edge, which this function did until then (CSS Color 4's intent),\n * was up to 82/255 off in a channel, and the full CSS Color 4 gamut-mapping\n * algorithm up to 73/255. Clipping is usually lighter (a negative channel\n * rises to 0), so white text decided on the chroma-reduced colour could miss\n * AA as drawn: 4.41:1 on the palette bold at hue 187.5, which it scored 4.62.\n */\nfunction oklchToLinearSrgbClamped(colour: Oklch): [number, number, number] {\n return oklchToLinearSrgb(colour).map((v) => Math.min(1, Math.max(0, v))) as [number, number, number]\n}\n\nconst gammaEncode = (v: number) => (v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055)\nconst gammaDecode = (v: number) => (v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4))\n\n/** Gamma-encoded sRGB channels (0..1) — the space `opacity` compositing and `color-mix(in srgb)` blend in. */\nfunction oklchToSrgb(colour: Oklch): [number, number, number] {\n return oklchToLinearSrgbClamped(colour).map(gammaEncode) as [number, number, number]\n}\n\nfunction srgbLuminance([r, g, b]: [number, number, number]): number {\n return 0.2126 * gammaDecode(r) + 0.7152 * gammaDecode(g) + 0.0722 * gammaDecode(b)\n}\n\n/**\n * How near a half step (of 1/255) a channel can sit and still come out of\n * Chrome one step either way. Chrome's arithmetic is not this file's: of 2,435\n * colours measured (Sprint 25.7 Part D; 7,305 channels), 39 channels came back\n * one step from the nearest, and every one sat within 0.12 of a step of the\n * half-step boundary.\n * One step is up to 0.05 of contrast near the white crossover, which is where\n * the decisions live, so a decision counts both steps inside this window.\n */\nexport const ROUNDING_WINDOW = 0.25\n\n/** A colour's WCAG luminance as Chrome can draw it: [darkest, lightest] over the 8-bit steps each channel can round to. */\nexport type LuminanceRange = readonly [number, number]\n\n/** The luminance range of gamma-encoded sRGB channels (0–1): each channel's nearest step, or both steps beside it within the window. */\nfunction srgbLuminanceRange(encoded: readonly number[]): LuminanceRange {\n let lo = 0\n let hi = 0\n encoded.forEach((v, i) => {\n const x = Math.min(1, Math.max(0, v)) * 255\n const below = Math.floor(x)\n const [a, b] = Math.abs(x - below - 0.5) <= ROUNDING_WINDOW ? [below, Math.min(255, below + 1)] : [Math.round(x), Math.round(x)]\n const weight = [0.2126, 0.7152, 0.0722][i]\n lo += weight * gammaDecode(a / 255)\n hi += weight * gammaDecode(b / 255)\n })\n return [lo, hi]\n}\n\n/** The luminance range an OKLCH colour can take as Chrome draws it: clipped to sRGB, then rounded to 8 bits. */\nexport function luminanceRange(colour: Oklch): LuminanceRange {\n return srgbLuminanceRange(oklchToSrgb(colour))\n}\n\n/** The lowest contrast two colours can show, every way either can round (1 when their ranges meet). */\nexport function worstContrastOf([t0, t1]: LuminanceRange, [f0, f1]: LuminanceRange): number {\n if (t0 <= f1 && f0 <= t1) return 1\n return t0 > f1 ? contrastRatio(t0, f1) : contrastRatio(t1, f0)\n}\n\n/** WCAG contrast ratio between two relative luminances. */\nexport function contrastRatio(lumA: number, lumB: number): number {\n const lighter = Math.max(lumA, lumB)\n const darker = Math.min(lumA, lumB)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/**\n * Sprint 25.14 A20 (and Sprint 30's P1): colours as the browser has drawn them — 8-bit sRGB channels and an alpha, read\n * from a canvas or a screenshot — composited and compared as WCAG does. A translucent edge is judged over what it sits\n * on: each ground laid under it in gamma-encoded sRGB, the space the browser blends in.\n */\nexport type DrawnColour = readonly [r: number, g: number, b: number, alpha: number]\n\n/** `top` laid over an opaque `ground`, as the browser composites it. */\nexport function drawnOver(top: DrawnColour, ground: DrawnColour): DrawnColour {\n const a = top[3]\n return [0, 1, 2].map((i) => Math.round(top[i] * a + ground[i] * (1 - a))).concat(1) as unknown as DrawnColour\n}\n\n/** WCAG relative luminance of an opaque drawn colour. */\nexport function drawnLuminance([r, g, b]: DrawnColour): number {\n return srgbLuminance([r / 255, g / 255, b / 255])\n}\n\n/** WCAG contrast between two opaque drawn colours. */\nexport function drawnContrast(a: DrawnColour, b: DrawnColour): number {\n return contrastRatio(drawnLuminance(a), drawnLuminance(b))\n}\n\n/** The lowest contrast `edge` shows over each ground (opaque), composited where it is translucent, and the ground it is lowest on. */\nexport function edgeContrast(edge: DrawnColour, grounds: ReadonlyArray<readonly [name: string, ground: DrawnColour]>): { ratio: number; on: string } {\n let worst = { ratio: Infinity, on: \"\" }\n for (const [name, ground] of grounds) {\n const ratio = drawnContrast(drawnOver(edge, ground), ground)\n if (ratio < worst.ratio) worst = { ratio, on: name }\n }\n return worst\n}\n\nexport const WCAG_AA_TEXT = 4.5\n\n/** White text as the emitters write it. */\nexport const ON_FILL_WHITE = 'oklch(1 0 0)'\n/** Last-resort dark text: the theme's darkest neutral. Used only when no tint of the fill's own hue can pass (§ onFillDarkTint). */\nexport const ON_FILL_DARK = 'var(--ds-neutral-950)'\n/**\n * The last-resort candidate as a colour: --ds-neutral-950 is L 0.13 with a\n * chroma of 0.002 × --ds-sat-neutral, which is invisible to the luminance\n * calculation, so the hue does not matter here.\n */\nexport const DARK_TEXT_CANDIDATE: Oklch = { L: 0.13, C: 0.002, H: 0 }\n\n/** The dark tint keeps the fill's hue at this chroma (the palette's `-dark` variant uses 0.10 too); a duller fill keeps its own chroma. */\nexport const ON_FILL_TINT_CHROMA = 0.10\n/** Preferred contrast for the dark tint. Falls back to AA where no dark colour can reach it (fills just above the white crossover). */\nexport const ON_FILL_TINT_TARGET = 5\nconst TINT_L_MAX = 0.45\nconst TINT_L_MIN = 0.10\nconst TINT_L_STEP = 0.01\n\nconst WHITE_RANGE: LuminanceRange = [1, 1]\nconst DARK_RANGE = luminanceRange(DARK_TEXT_CANDIDATE)\n\n/** The worst contrast a text colour gets over one or more fills as Chrome draws them (a gradient passes every colour it paints: gradientFills). */\nfunction minContrast(text: LuminanceRange, fills: Oklch[]): number {\n let min = Infinity\n for (const f of fills) min = Math.min(min, worstContrastOf(text, luminanceRange(f)))\n return min\n}\n\n/**\n * White or dark text over one or more fills (a gradient passes every colour it\n * paints, gradientFills): whichever onFillTextValue emits, so a caller showing the choice (the\n * builder's \"text flips to dark\" note) agrees with the token.\n */\nexport function onFillText(fill: Oklch, ...moreFills: Oklch[]): 'white' | 'dark' {\n return onFillTextValue(fill, ...moreFills) === ON_FILL_WHITE ? 'white' : 'dark'\n}\n\n/**\n * The dark text colour for a fill: a deep shade of the fill's own hue rather\n * than a neutral, so an amber badge reads as amber-on-amber the way the\n * decorative palette pairs `-dark` text with `-subtle` backgrounds. The\n * lightest tint (L 0.45 → 0.10 in 0.01 steps, chroma capped at 0.10) whose\n * worst contrast across the fills reaches 5:1. Contrast comes before colour:\n * where the full-chroma tint cannot reach the target the chroma halves, then\n * quarters (a saturated green tint at L 0.10 is still luminous enough to\n * miss 5:1 over a light green); where no dark colour can reach 5:1 the\n * lightest reaching AA; null when not even AA is reachable (the caller then\n * falls back to --ds-neutral-950). For a gradient the hue is the start\n * colour's; the contrast is checked over every colour it paints (gradientFills).\n */\nexport function onFillDarkTint(fill: Oklch, ...moreFills: Oklch[]): Oklch | null {\n const fills = [fill, ...moreFills]\n const H = fill.H\n const chroma = Math.min(ON_FILL_TINT_CHROMA, fill.C)\n for (const target of [ON_FILL_TINT_TARGET, WCAG_AA_TEXT]) {\n for (const C of [chroma, chroma / 2, chroma / 4]) {\n for (let L = TINT_L_MAX; L >= TINT_L_MIN - 1e-9; L -= TINT_L_STEP) {\n const candidate = { L: +L.toFixed(2), C: +C.toFixed(4), H }\n if (minContrast(luminanceRange(candidate), fills) >= target) return candidate\n }\n }\n }\n return null\n}\n\n/**\n * The CSS value for text on a fill, the one on-fill decision: white where\n * white reaches AA over every fill as drawn; else the dark tint\n * (onFillDarkTint); else --ds-neutral-950 or white, whichever does better.\n * The tints go darker than --ds-neutral-950, so they also cover the sliver\n * around luminance 0.184 where white and the neutral both miss a single fill\n * (a fill at L 0.55 near hue 215). Only a gradient whose colours lie either\n * side of the crossover can leave every colour short of AA; the fill has to\n * change there.\n */\nexport function onFillTextValue(fill: Oklch, ...moreFills: Oklch[]): string {\n const fills = [fill, ...moreFills]\n const whiteMin = minContrast(WHITE_RANGE, fills)\n if (whiteMin >= WCAG_AA_TEXT) return ON_FILL_WHITE\n const tint = onFillDarkTint(fill, ...moreFills)\n if (tint) return oklchCss(tint)\n return minContrast(DARK_RANGE, fills) >= whiteMin ? ON_FILL_DARK : ON_FILL_WHITE\n}\n\n/** How many equal parts a gradient is sampled in, between its two ends (every 5%: a dip can sit at 95% of the way). */\nconst GRADIENT_SAMPLES = 20\n\n/**\n * The colours a gradient paints, for deciding the text over it: its two ends\n * (the start first, so a dark tint keeps the start's hue) and the points\n * between them. Chrome paints a linear-gradient of oklch() colours in Oklab\n * (CSS Color 4's default for colours that are not legacy sRGB): its pixels\n * follow Oklab interpolation to within 0.003 of luminance (measured, Sprint\n * 25.7, 26 September 2026). A point in between can be darker or lighter than\n * both ends, because two saturated ends that sRGB clips meet at a duller colour\n * that clips less: up to 5% darker than the darker end across the accent scale\n * (a violet to a red at primary-600), enough to take text below AA.\n */\nexport function gradientFills(start: Oklch, end: Oklch): [Oklch, Oklch, ...Oklch[]] {\n const lab = ({ L, C, H }: Oklch) => [L, C * Math.cos((H * Math.PI) / 180), C * Math.sin((H * Math.PI) / 180)]\n const [a, b] = [lab(start), lab(end)]\n const between: Oklch[] = []\n for (let i = 1; i < GRADIENT_SAMPLES; i++) {\n const [L, x, y] = a.map((v, k) => v + ((b[k] - v) * i) / GRADIENT_SAMPLES)\n between.push({ L, C: Math.hypot(x, y), H: ((Math.atan2(y, x) * 180) / Math.PI + 360) % 360 })\n }\n return [start, end, ...between]\n}\n\n/* ── Tinted surfaces (subtle colourful header) ──────────────────────────\n A tinted surface is the surface colour (--ds-bg-surface, so it matches the\n cards around it) washed with the accent — the gradient, or the solid accent —\n at one strength. One recipe in both accent modes, so the tint is a pure\n shade of the accent over the paper and its luminance is knowable: the muted\n ink over it is the lightest neutral step that clears AA against the worst\n wash stop. The picker measures against the default surface; a preset that\n overrides --ds-bg-surface (cream, translucent) shifts the real tint a little,\n the same limitation --ds-text-on-primary has under a --ds-gradient override. */\n\n/** Opacity of the accent wash over --ds-tint-base. Shared by the CSS (--ds-tint-strength) and the ink picker. */\nexport const TINT_STRENGTH = 0.15\n/** The default --ds-bg-surface per mode: white in light, --ds-neutral-800 in dark. @sync roots.css (tint-parity.test.ts checks). */\nexport const TINT_BASE: Record<'light' | 'dark', Oklch> = {\n light: { L: 1, C: 0, H: 0 },\n dark: { L: 0.27, C: 0.004, H: 0 },\n}\n/** The CSS for --ds-accent-wash when the accent is solid: a flat image so the overlay reads one token in both modes. */\nexport const SOLID_ACCENT_WASH = 'linear-gradient(var(--ds-accent-primary), var(--ds-accent-primary))'\n\n/** L of the neutral steps: the muted-ink candidates (200–700) and the deep steps that can serve as text on the neutral status fill (chroma ≤ 0.01 × sat, invisible to luminance). @sync roots.css --ds-neutral-* (tint-parity.test.ts checks). */\nexport const NEUTRAL_STEP_L: Record<number, number> = { 200: 0.90, 300: 0.84, 400: 0.71, 500: 0.55, 600: 0.45, 700: 0.37, 800: 0.27, 900: 0.20, 950: 0.13 }\n/** Candidate steps, lightest first: the first that clears AA wins, so hierarchy against --ds-text-secondary is kept where the tint allows. */\nconst MUTED_ON_TINT_STEPS: Record<'light' | 'dark', number[]> = { light: [400, 500, 600, 700], dark: [400, 300, 200] }\n\n/** The tinted surface for one wash colour in gamma sRGB: the base blended with the wash (clipped, as drawn) at TINT_STRENGTH, as the browser composites the overlay. */\nfunction tintSrgb(mode: 'light' | 'dark', wash: Oklch): [number, number, number] {\n const base = oklchToSrgb(TINT_BASE[mode])\n const top = oklchToSrgb(wash)\n return base.map((v, i) => v * (1 - TINT_STRENGTH) + top[i] * TINT_STRENGTH) as [number, number, number]\n}\n\n/** WCAG luminance of the tinted surface for one wash colour, at the nearest 8-bit step (the ink picker uses the range Chrome's rounding can land in). */\nexport function tintLuminance(mode: 'light' | 'dark', wash: Oklch): number {\n return srgbLuminance(tintSrgb(mode, wash).map((v) => Math.round(v * 255) / 255) as [number, number, number])\n}\n\n/**\n * The muted ink for text over a tinted surface: `var(--ds-neutral-NNN)`, the\n * lightest candidate step whose worst contrast across the wash colours (a\n * gradient passes both ends) reaches AA as Chrome draws both. The darkest\n * candidate when none does.\n */\nexport function mutedOnTint(mode: 'light' | 'dark', wash: Oklch, ...moreWashes: Oklch[]): string {\n const surfaces: Paint[] = [wash, ...moreWashes].map((w) => ({ rgb: tintSrgb(mode, w), alpha: 1 }))\n const steps = MUTED_ON_TINT_STEPS[mode]\n // the shared routine (Sprint 30's firstReadable), walking the neutral scale's steps\n const candidates = steps.map((step): ColourCandidate => ({ value: `var(--ds-neutral-${step})`, paint: { rgb: oklchToSrgb({ L: NEUTRAL_STEP_L[step], C: 0, H: 0 }), alpha: 1 } }))\n return firstReadable(candidates, surfaces, WCAG_AA_TEXT)?.value ?? `var(--ds-neutral-${steps[steps.length - 1]})`\n}\n\n/**\n * On-fill tokens for the four status fills that carry text (Badge, Button,\n * Stepper, Dock, the Gantt's bars). Takes the palette's literal values; a value\n * that is not an OKLCH literal keeps white, the roots.css default.\n */\nexport function onStatusFillTokens(sv: { success: string; warning: string; error: string; info: string }): Record<string, string> {\n const pick = (value: string) => {\n const c = parseOklch(value)\n return c ? onFillTextValue(c) : ON_FILL_WHITE\n }\n return {\n '--ds-text-on-success': pick(sv.success),\n '--ds-text-on-warning': pick(sv.warning),\n '--ds-text-on-error': pick(sv.error),\n '--ds-text-on-info': pick(sv.info),\n }\n}\n\n/**\n * The neutral status fill per mode: a mid step of the theme's neutral scale, for\n * an item with no status (\"not started\", a Gantt bar with no known status). Dark\n * mode takes the step one lighter, as every status fill does (500 → 400), so the\n * fill still shows at 3:1 on the dark surfaces (neutral-700 to -900).\n * @sync roots.css --ds-status-neutral (token-algorithms.test.ts checks).\n */\nexport const STATUS_NEUTRAL_STEP: Record<'light' | 'dark', number> = { light: 500, dark: 400 }\n\n/** The deep neutral steps that can carry text on the neutral fill, lightest first. */\nconst NEUTRAL_TEXT_STEPS = [700, 800, 900, 950]\n\n/**\n * The neutral status fill and the text on it, for one mode. The same in every\n * status palette, so roots.css declares the same pair as its defaults. The text\n * is decided as every on-fill colour is (onFillText, onFillDarkTint): white\n * where white reaches AA over the fill; else the lightest deep shade of the\n * fill's own hue reaching 5:1, then AA — for a neutral fill that is a step of\n * the neutral scale, which carries the theme's neutral hue and saturation as the\n * fill does; --ds-neutral-950 as the last resort.\n */\nexport function neutralStatusFillTokens(mode: 'light' | 'dark'): Record<string, string> {\n const step = STATUS_NEUTRAL_STEP[mode]\n const fill: Oklch = { L: NEUTRAL_STEP_L[step], C: 0, H: 0 }\n const text = (): string => {\n if (onFillText(fill) === 'white') return ON_FILL_WHITE\n for (const target of [ON_FILL_TINT_TARGET, WCAG_AA_TEXT]) {\n for (const s of NEUTRAL_TEXT_STEPS) {\n if (s > step && minContrast(luminanceRange({ L: NEUTRAL_STEP_L[s], C: 0, H: 0 }), [fill]) >= target) return `var(--ds-neutral-${s})`\n }\n }\n return ON_FILL_DARK\n }\n return {\n '--ds-status-neutral': `var(--ds-neutral-${step})`,\n '--ds-text-on-neutral': text(),\n }\n}\n\n/**\n * Computes accent tokens from shade + mode.\n * Chart tokens are now generated separately via computeChartTokens (they\n * depend on palette values that don't exist at accent-computation time).\n *\n * With a `gradient` config (which every emitter passes, solid or gradient,\n * because it carries the hue and saturation) the set also includes\n * `--ds-text-on-primary`, decided by `onFillText` over the accent — or over\n * every colour a gradient paints (gradientFills). Without one the token is\n * left to roots.css (white).\n */\nexport function getAccentTokens(\n shade: number,\n mode: 'light' | 'dark',\n gradient?: GradientConfig\n): Record<string, string> {\n const s = Math.max(300, Math.min(900, shade))\n const hover = mode === 'dark' ? Math.max(300, s - 100) : Math.min(950, s + 100)\n const active = mode === 'dark' ? Math.max(300, s - 200) : Math.min(950, s + 200)\n\n const tokens: Record<string, string> = {\n '--ds-accent-primary': `var(--ds-primary-${s})`,\n '--ds-accent-primary-hover': `var(--ds-primary-${hover})`,\n '--ds-accent-primary-active': `var(--ds-primary-${active})`,\n // The active look's soft halo (Sprint 30, D6: a field clicked into, an open trigger). The focus colour is derived\n // (readableTokens); --ds-border-focus is its alias in roots.css, and the old ring and input alias are gone (P5).\n '--ds-ring-active': 'var(--ds-accent-soft)',\n // Tinted surfaces: --ds-tint-base is var(--ds-bg-surface) in roots.css; only the strength is emitted (see mutedOnTint).\n '--ds-tint-strength': String(TINT_STRENGTH),\n }\n\n if (gradient?.accentMode === 'gradient') {\n const startHue = gradient.hue ?? gradient.endHue\n const start = accentColour(s, gradient.sat, startHue)\n const startColor = `oklch(${start.L} ${start.C.toFixed(4)} ${startHue})`\n\n const endShade = Math.max(300, Math.min(900, gradient.endShade ?? s))\n const endSat = gradient.endSat ?? gradient.sat\n const end = accentColour(endShade, endSat, gradient.endHue)\n const endColor = oklchCss(end)\n tokens['--ds-gradient'] = `linear-gradient(${gradient.angle}deg, ${startColor}, ${endColor})`\n // The two ends as their own tokens so SVG gradients (icon strokes) can follow the theme.\n tokens['--ds-gradient-start'] = startColor\n tokens['--ds-gradient-end'] = endColor\n tokens['--ds-text-on-primary'] = onFillTextValue(...gradientFills(start, end))\n // Reads the gradient token (not the literal) so a preset override of --ds-gradient washes the tint too.\n tokens['--ds-accent-wash'] = 'var(--ds-gradient)'\n tokens['--ds-text-muted-on-tint'] = mutedOnTint(mode, start, end)\n } else {\n tokens['--ds-gradient'] = 'none'\n tokens['--ds-gradient-start'] = 'var(--ds-accent-primary)'\n tokens['--ds-gradient-end'] = 'var(--ds-accent-primary)'\n tokens['--ds-accent-wash'] = SOLID_ACCENT_WASH\n if (gradient) {\n const solid = accentColour(s, gradient.sat, gradient.hue)\n tokens['--ds-text-on-primary'] = onFillTextValue(solid)\n tokens['--ds-text-muted-on-tint'] = mutedOnTint(mode, solid)\n }\n }\n\n return tokens\n}\n\nconst DEFAULT_INTERACTIVE: InteractiveHoverConfig = {\n enabled: true, effect: 'scale-lift', speed: 150, ease: 'ease-out', scale: 1.02, lift: 2, pressDepth: 1,\n}\n\nconst DEFAULT_AMBIENT: AmbientHoverConfig = {\n enabled: true, effect: 'lift', speed: 250, ease: 'cubic-bezier(0.33, 1, 0.68, 1)', scale: 1, lift: 1,\n}\n\nconst INTENSITY_PRESETS: Record<string, Record<string, string>> = {\n none: { '--ds-hover-scale': '1', '--ds-hover-lift': '0px', '--ds-press-depth': '0px', '--ds-ambient-hover-scale': '1', '--ds-ambient-hover-lift': '0px' },\n subtle: { '--ds-hover-scale': '1.02', '--ds-hover-lift': '2px', '--ds-press-depth': '1px', '--ds-ambient-hover-scale': '1', '--ds-ambient-hover-lift': '1px' },\n moderate: { '--ds-hover-scale': '1.035', '--ds-hover-lift': '3px', '--ds-press-depth': '1px', '--ds-ambient-hover-scale': '1.01', '--ds-ambient-hover-lift': '2px' },\n expressive: { '--ds-hover-scale': '1.05', '--ds-hover-lift': '6px', '--ds-press-depth': '2px', '--ds-ambient-hover-scale': '1.015', '--ds-ambient-hover-lift': '3px' },\n}\n\n/**\n * Computes hover motion tokens from structured config.\n * Handles both modern (interactive + ambient) and legacy (intensity) input shapes.\n */\nexport function computeHoverTokens(motion: MotionDecisions): Record<string, string> {\n const i = motion.interactive\n const a = motion.ambient\n\n if (i || a) {\n const interactive = i ?? DEFAULT_INTERACTIVE\n const ambient = a ?? DEFAULT_AMBIENT\n const hasScale = interactive.enabled && hasScaleEffect(interactive.effect)\n const hasILift = interactive.enabled && hasLiftEffect(interactive.effect)\n const hasAScale = ambient.enabled && hasScaleEffect(ambient.effect)\n const hasALift = ambient.enabled && hasLiftEffect(ambient.effect)\n return {\n '--ds-hover-scale': hasScale ? String(interactive.scale) : '1',\n '--ds-hover-lift': hasILift ? `${interactive.lift}px` : '0px',\n '--ds-press-depth': interactive.enabled ? `${interactive.pressDepth}px` : '0px',\n '--ds-interactive-hover-speed': `${interactive.speed}ms`,\n '--ds-interactive-hover-ease': interactive.ease,\n '--ds-ambient-hover-scale': hasAScale ? String(ambient.scale) : '1',\n '--ds-ambient-hover-lift': hasALift ? `${ambient.lift}px` : '0px',\n '--ds-ambient-hover-speed': `${ambient.speed}ms`,\n '--ds-ambient-hover-ease': ambient.ease,\n }\n }\n\n const base = INTENSITY_PRESETS[motion.intensity ?? 'subtle'] ?? INTENSITY_PRESETS['subtle']\n return {\n ...base,\n '--ds-interactive-hover-speed': `${motion.speed}ms`,\n '--ds-interactive-hover-ease': motion.ease,\n '--ds-ambient-hover-speed': `${Math.round(motion.speed * 1.5)}ms`,\n '--ds-ambient-hover-ease': 'cubic-bezier(0.33, 1, 0.68, 1)',\n }\n}\n\n/**\n * Computes the accent colour of an independent-mode sidebar (or header) from\n * the target palette, as a literal because it comes from the *other* palette.\n * Since Sprint 20.10 it sits on the same --ds-primary-{shade} scale as the\n * page accent (it used to be a lighter curve, 0.597 at 500 against 0.55), so\n * the on-accent text decision flips at the same shade everywhere.\n * `onAccent` is the text colour over the accent, emitted as\n * --ds-sidebar-text-on-accent / --ds-header-text-on-accent.\n * Used by runtime DOM writers and static CSS generator.\n */\nexport function computeSidebarAccent(\n shade: number,\n satPrimary: number,\n huePrimary: number\n): { accent: string; accentSubtle: string; onAccent: string } {\n const colour = accentColour(shade, satPrimary, huePrimary)\n const accent = oklchCss(colour)\n const accentSubtle = `color-mix(in srgb, ${accent} 10%, transparent)`\n return { accent, accentSubtle, onAccent: onFillTextValue(colour) }\n}\n\n// Status hue positions (fixed, not configurable)\nconst STATUS_HUES = { success: 142, warning: 86, error: 25, info: 255 }\nconst STATUS_HUE_VALUES = Object.values(STATUS_HUES)\n\nconst GOLDEN_ANGLE = 137.508\n\n/**\n * Normalise a hue to [0, 360).\n */\nfunction normaliseHue(h: number): number {\n return ((h % 360) + 360) % 360\n}\n\n/**\n * Angular distance on the hue wheel (0–180).\n */\nfunction hueDistance(a: number, b: number): number {\n const diff = Math.abs(normaliseHue(a) - normaliseHue(b))\n return diff > 180 ? 360 - diff : diff\n}\n\n/**\n * Distributes 5 palette hues around the OKLCH hue wheel using golden-angle\n * spacing. Avoids the primary hue neighbourhood and status hue positions.\n *\n * @param primaryHue The user's primary accent hue (0–360)\n * @param exclusionRadius Minimum angular distance from primary and status hues (default 20°)\n * @returns Array of 5 hue values, each in [0, 360)\n */\nexport function computePaletteHues(\n primaryHue: number,\n exclusionRadius = 20\n): number[] {\n const hues: number[] = []\n const excluded = [normaliseHue(primaryHue), ...STATUS_HUE_VALUES]\n\n function isColliding(h: number): boolean {\n return excluded.some(ex => hueDistance(h, ex) < exclusionRadius) ||\n hues.some(existing => hueDistance(h, existing) < exclusionRadius)\n }\n\n // Start opposite the primary hue for maximum initial separation\n const cursor = normaliseHue(primaryHue + 180)\n\n for (let i = 0; i < 5; i++) {\n let candidate = normaliseHue(cursor + i * GOLDEN_ANGLE)\n\n // Nudge colliding candidates by +5° increments, up to a full rotation\n let attempts = 0\n while (isColliding(candidate) && attempts < 72) {\n candidate = normaliseHue(candidate + 5)\n attempts++\n }\n\n hues.push(candidate)\n }\n\n return hues\n}\n\n// Palette generation lightness/chroma targets\nconst PALETTE_BOLD_L = 0.55\nconst PALETTE_BOLD_C = 0.12\nconst PALETTE_SUBTLE_L = 0.92\nconst PALETTE_SUBTLE_C = 0.03\nconst PALETTE_DARK_L = 0.35\nconst PALETTE_DARK_C = 0.10\n\n/**\n * How far a palette bold may darken to keep white text (the owner's call, 26\n * September 2026). Teals and cyans near the sRGB edge (hues 170–216.5 at the\n * constants above) clip lighter than white allows at PALETTE_BOLD_L, and one\n * step of PALETTE_BOLD_STEP brings each to AA as drawn, so a row of Badges and\n * Tags keeps one text colour. A bold that no step up to this brings to AA keeps\n * its lightness and takes a tint of its hue.\n */\nexport const PALETTE_BOLD_MAX_DARKEN = 0.02\nconst PALETTE_BOLD_STEP = 0.01\n\n/**\n * A bold fill for white text: darkened by the smallest step (PALETTE_BOLD_STEP) that brings white to AA as drawn,\n * never by more than maxDarken; a fill no darkening within the cap brings there is returned as it was, and its text\n * takes a tint (onFillTextValue). getPaletteTokens passes PALETTE_BOLD_MAX_DARKEN; the cap is a parameter so a fill\n * that needs more than it can be tested (no palette hue does at today's constants).\n */\nexport function boldForWhiteText(fill: Oklch, maxDarken: number = PALETTE_BOLD_MAX_DARKEN): Oklch {\n let L = fill.L\n while (onFillText({ ...fill, L }) === 'dark' && fill.L - L < maxDarken - 1e-9) L = +(L - PALETTE_BOLD_STEP).toFixed(2)\n return onFillText({ ...fill, L }) === 'dark' ? fill : { ...fill, L }\n}\n\n/**\n * The lightness a chart series needs in dark mode to show at 3:1 against the surfaces a chart sits on (WCAG 1.4.11):\n * every hue at C 0.12 clears 3:1 on the elevated surface (neutral-700) and 4.5:1 on the card (neutral-800). It is\n * primary-400's lightness, as the light-mode series (the palette bold, 0.55, a step darker for the teals) is\n * primary-500's (Sprint 25.7).\n */\nexport const CHART_SERIES_DARK_L = 0.66\n\n/**\n * Generates the 5 palette tokens (bold/subtle/dark/bg/text) for a single hue.\n * Validates subtle/dark contrast and clamps chroma if needed.\n *\n * @param hue The palette hue value (0–360)\n * @param index Palette index (1–5) for token naming\n * @param mode 'light' | 'dark' — determines bg/text alias direction\n * @returns Record of CSS custom properties for this palette hue\n */\n/**\n * The soft pair of a hue (the supporting colours' step, Sprint 25.18's one rule for coloured text on a coloured ground,\n * the owner's D50): a pale fill and a deep text at fixed lightnesses, the gap widened until the pair reaches AA (4.5:1),\n * which these lightnesses already clear for every hue. `chroma` caps the two chromas: the supporting colours pass none\n * (their own constants); the accent passes its own chroma, so a grey accent gives a grey pair. Light mode draws the\n * pale one as the fill and the deep one as the text; dark mode swaps them.\n */\nexport function softPair(hue: number, chroma = Infinity): { subtle: string; dark: string } {\n const h = normaliseHue(hue)\n let subtleL = PALETTE_SUBTLE_L\n let darkL = PALETTE_DARK_L\n let ratio = estimateContrastRatio(subtleL, darkL)\n while (ratio < 4.5 && subtleL < 0.98 && darkL > 0.20) {\n subtleL = Math.min(0.98, subtleL + 0.02)\n darkL = Math.max(0.20, darkL - 0.02)\n ratio = estimateContrastRatio(subtleL, darkL)\n }\n const c = (constant: number) => Math.max(0, Math.min(constant, chroma)).toFixed(4)\n return {\n subtle: `oklch(${subtleL.toFixed(2)} ${c(PALETTE_SUBTLE_C)} ${h})`,\n dark: `oklch(${darkL.toFixed(2)} ${c(PALETTE_DARK_C)} ${h})`,\n }\n}\n\n/** The soft pair's lightnesses and chromas, for the stylesheet's own reading of the step (roots.css derives the accent's pair from them). */\nexport const SOFT_PAIR = { subtleL: PALETTE_SUBTLE_L, subtleC: PALETTE_SUBTLE_C, darkL: PALETTE_DARK_L, darkC: PALETTE_DARK_C } as const\n\n/**\n * The accent's soft pair (Sprint 25.18 A15, the owner's D51): the supporting colours' step applied to the accent, its\n * chroma capped by the accent's own (the primary scale's chroma at the accent's shade, times the saturation), so the\n * accent's tint and text are one more supporting colour. `--ds-accent-bg` is the fill, `--ds-accent-text` the text on it\n * (readable on the page and a card too); a Calendar event in the accent draws with them.\n */\nexport function getAccentPairTokens(shade: number, sat: number, hue: number, mode: 'light' | 'dark'): Record<string, string> {\n const { subtle, dark } = softPair(hue, accentColour(shade, sat, hue).C)\n return {\n '--ds-accent-bg': mode === 'light' ? subtle : dark,\n '--ds-accent-text': mode === 'light' ? dark : subtle,\n }\n}\n\nexport function getPaletteTokens(\n hue: number,\n index: number,\n mode: 'light' | 'dark'\n): Record<string, string> {\n const h = normaliseHue(hue)\n\n // Bold: white text as drawn, darkened within PALETTE_BOLD_MAX_DARKEN where the fill clips too light for it; past the\n // cap it keeps its lightness and its text takes a tint (below)\n const boldFill = boldForWhiteText({ L: PALETTE_BOLD_L, C: PALETTE_BOLD_C, H: h })\n const boldL = boldFill.L\n\n // Subtle/dark: the soft pair, at AA (softPair)\n const { subtle, dark } = softPair(h)\n const bold = `oklch(${boldL.toFixed(2)} ${PALETTE_BOLD_C.toFixed(4)} ${h})`\n\n const prefix = `--ds-palette-${index}`\n\n return {\n [`${prefix}-bold`]: bold,\n [`${prefix}-subtle`]: subtle,\n [`${prefix}-dark`]: dark,\n [`${prefix}-bg`]: mode === 'light' ? `var(${prefix}-subtle)` : `var(${prefix}-dark)`,\n [`${prefix}-text`]: mode === 'light' ? `var(${prefix}-dark)` : `var(${prefix}-subtle)`,\n // The chart series colour: the bold in light mode; lifted in dark, where the bold sinks into a dark card\n // (2.9:1 for reds and magentas on neutral-800). Badges and Tags keep the bold, for their white text.\n [`${prefix}-chart`]: mode === 'light' ? `var(${prefix}-bold)` : `oklch(${CHART_SERIES_DARK_L.toFixed(2)} ${PALETTE_BOLD_C.toFixed(4)} ${h})`,\n // Text on the bold fill (Badge / Tag colour variants), decided by contrast as\n // drawn: white, the teals and cyans that clip too light for it one step\n // darker (above); a deep tint of the hue only where no step within\n // PALETTE_BOLD_MAX_DARKEN brings white to AA.\n [`${prefix}-on-bold`]: onFillTextValue(boldFill),\n }\n}\n\n/**\n * The primary step chart-1 draws in: the accent's own when it shows at 3:1 on the mode's surfaces — 500 or darker on\n * a light card (PRIMARY_SCALE L 0.55 and below, the palette bold's lightness), 400 or lighter on a dark one (L 0.66\n * and above, CHART_SERIES_DARK_L) — else the nearest step that does.\n */\nexport function chartAccentShade(accentShade: number, mode: 'light' | 'dark'): number {\n const s = scaleShade(accentShade)\n return mode === 'dark' ? Math.min(s, 400) : Math.max(s, 500)\n}\n\n/**\n * Generates chart tokens that reference accent and palette values via var(). All values are CSS variable references,\n * not computed colours — the palette tokens must already exist in the same scope. chart-1 is the accent unless the\n * accent is too light (light mode) or too dark (dark mode) for a series, and then the nearest primary step that shows\n * (chartAccentShade); chart-2–6 are the palette's chart colours. Without an accent shade, chart-1 is the accent.\n *\n * @returns Record of 14 CSS custom properties (12 chart tokens + 2 backwards-compat aliases)\n */\nexport function computeChartTokens(accentShade?: number, mode: 'light' | 'dark' = 'light'): Record<string, string> {\n const series = accentShade == null ? null : chartAccentShade(accentShade, mode)\n const accent = series == null || series === scaleShade(accentShade!) ? 'var(--ds-accent-primary)' : `var(--ds-primary-${series})`\n const tokens: Record<string, string> = {\n '--ds-chart-1': accent,\n '--ds-chart-1-soft': `color-mix(in oklch, ${accent} 30%, transparent)`,\n }\n\n for (let i = 1; i <= 5; i++) {\n tokens[`--ds-chart-${i + 1}`] = `var(--ds-palette-${i}-chart)`\n tokens[`--ds-chart-${i + 1}-soft`] = `color-mix(in oklch, var(--ds-palette-${i}-chart) 30%, transparent)`\n }\n\n // Backwards-compat aliases\n tokens['--ds-chart-fill'] = `var(--ds-chart-1)`\n tokens['--ds-chart-fill-soft'] = `var(--ds-chart-1-soft)`\n\n return tokens\n}\n\n/**\n * Approximate WCAG contrast ratio between two OKLCH lightness values.\n * Uses L³ as a luminance proxy (OKLCH lightness is perceptual, L³ ≈ relative luminance).\n * Returns estimated ratio (1.0 to 21.0). Kept for the palette subtle/dark\n * pair, which only needs a ranking; on-fill text decisions use\n * `oklchToLuminance` + `contrastRatio` (Sprint 20.10), which account for hue,\n * chroma and gamut.\n */\nexport function estimateContrastRatio(L1: number, L2: number): number {\n const lum1 = Math.pow(Math.max(0, Math.min(1, L1)), 3)\n const lum2 = Math.pow(Math.max(0, Math.min(1, L2)), 3)\n const lighter = Math.max(lum1, lum2)\n const darker = Math.min(lum1, lum2)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/**\n * Approximate WCAG contrast ratio between an oklch colour and white.\n * Delegates to estimateContrastRatio with L2 = 1.0 (white).\n */\nexport function estimateContrastVsWhite(oklchL: number): number {\n return estimateContrastRatio(oklchL, 1.0)\n}\n\n// ---------------------------------------------------------------------------\n// Navigation active styles (Sprint 20.8)\n// ---------------------------------------------------------------------------\n//\n// The *shape* of an active navigation item is a theme decision, not a per-page\n// one. Three decisions (sidebar, in-page horizontal, in-page vertical) resolve\n// to 24 CSS custom properties that SidebarNav, Tabs and TreeView read. Every\n// value is a var() of an existing mode-aware token or a plain length, so the\n// set has one body — but because var() inside a custom property is substituted\n// where it is *declared*, emitters must declare the set in every scope that\n// redeclares one of its inputs (:root, [data-mode], [data-ds-overlay]).\n//\n// The defaults reproduce today's rendering exactly (sprint §0.1). Do not\n// \"improve\" a default value here — that is a product change with its own\n// changelog entry.\n\nexport type SidebarActiveStyle = 'rail' | 'tint' | 'pill'\nexport type InPageHorizontalStyle = 'underline' | 'tint' | 'pill'\nexport type InPageVerticalStyle = 'rail' | 'tint' | 'pill'\n\nexport interface NavStyleInput {\n sidebarActiveStyle?: SidebarActiveStyle\n /** Only used to derive the default and the coercion: minimal and compact sidebars have no edge to stroke, so their default is tint and an explicit rail resolves to tint. */\n sidebarType?: 'traditional' | 'compact' | 'minimal'\n inPageHorizontal?: InPageHorizontalStyle\n inPageVertical?: InPageVerticalStyle\n}\n\nexport interface ResolvedNavStyles {\n sidebarActiveStyle: SidebarActiveStyle\n inPageHorizontal: InPageHorizontalStyle\n inPageVertical: InPageVerticalStyle\n}\n\n/**\n * The only place the missing-field defaults and the no-edge coercion (minimal\n * and compact sidebars) live. Every reader (deserialisers, Worker readers, CSS emitters, the rules\n * file) calls this — nobody writes `?? 'rail'` anywhere else.\n *\n * The coercion is render-time only: stored state keeps the user's choice so\n * switching a minimal or compact sidebar back to traditional restores the rail.\n */\nexport function resolveNavStyles(input: NavStyleInput): ResolvedNavStyles {\n const noEdge = input.sidebarType === 'minimal' || input.sidebarType === 'compact'\n let sidebarActiveStyle: SidebarActiveStyle = input.sidebarActiveStyle ?? (noEdge ? 'tint' : 'rail')\n if (noEdge && sidebarActiveStyle === 'rail') sidebarActiveStyle = 'tint'\n return {\n sidebarActiveStyle,\n inPageHorizontal: input.inPageHorizontal ?? 'underline',\n inPageVertical: input.inPageVertical ?? 'rail',\n }\n}\n\nconst ON_PRIMARY = 'var(--ds-text-on-primary)'\nconst SIDEBAR_ON_ACCENT = 'var(--ds-sidebar-text-on-accent)'\nconst ACCENT = 'var(--ds-accent-primary)'\n/** The accent as text (Sprint 30, P8): the theme's derived ink, readable on the page and on the accent's own tint; fills keep ACCENT. */\nconst ACCENT_INK = 'var(--ds-accent-ink)'\n/** The sidebar's current item as text and its marks (P8): the sidebar family's own ink. */\nconst SIDEBAR_INK = 'var(--ds-sidebar-accent-ink)'\nconst ACCENT_SUBTLE = 'var(--ds-accent-subtle)'\nconst PILL_BADGE_BG = 'color-mix(in oklab, var(--ds-bg-canvas) 20%, transparent)'\n\n/**\n * The 25 tokens of sprint §4 for the resolved styles (24, plus the sidebar\n * pill's gradient image — September 2026).\n */\nexport function getNavStyleTokens(input: NavStyleInput): Record<string, string> {\n const { sidebarActiveStyle, inPageHorizontal, inPageVertical } = resolveNavStyles(input)\n const tokens: Record<string, string> = {}\n\n // ── In-page horizontal (Tabs) ─────────────────────────────────────────\n switch (inPageHorizontal) {\n case 'underline':\n tokens['--ds-nav-h-active-bg'] = 'transparent'\n tokens['--ds-nav-h-active-text'] = 'var(--ds-text-primary)'\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-muted)'\n tokens['--ds-nav-h-indicator'] = 'calc(var(--ds-border-width) * 3)'\n tokens['--ds-nav-h-item-radius'] = '0px'\n tokens['--ds-nav-h-hover-bg'] = 'transparent'\n tokens['--ds-nav-h-track-border'] = 'var(--ds-border-width)'\n tokens['--ds-nav-h-track-gap'] = '0px'\n tokens['--ds-nav-h-badge-bg'] = ACCENT\n break\n case 'tint':\n tokens['--ds-nav-h-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-nav-h-active-text'] = ACCENT_INK\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-h-indicator'] = '0px'\n tokens['--ds-nav-h-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-h-hover-bg'] = 'var(--ds-tab-hover-bg)'\n tokens['--ds-nav-h-track-border'] = '0px'\n tokens['--ds-nav-h-track-gap'] = 'var(--ds-space-1)'\n tokens['--ds-nav-h-badge-bg'] = ACCENT\n break\n case 'pill':\n tokens['--ds-nav-h-active-bg'] = ACCENT\n tokens['--ds-nav-h-active-text'] = ON_PRIMARY\n tokens['--ds-nav-h-inactive-text'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-h-indicator'] = '0px'\n tokens['--ds-nav-h-item-radius'] = 'var(--ds-radius-md)'\n tokens['--ds-nav-h-hover-bg'] = 'var(--ds-tab-hover-bg)'\n tokens['--ds-nav-h-track-border'] = '0px'\n tokens['--ds-nav-h-track-gap'] = 'var(--ds-space-1)'\n tokens['--ds-nav-h-badge-bg'] = PILL_BADGE_BG\n break\n }\n\n // ── In-page vertical (Tabs rail) ──────────────────────────────────────\n switch (inPageVertical) {\n case 'rail':\n tokens['--ds-nav-v-active-bg'] = 'var(--ds-tab-active-bg)'\n tokens['--ds-nav-v-active-text'] = ACCENT_INK\n tokens['--ds-nav-v-active-rail'] = 'var(--ds-border-width-thick)'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = 'var(--ds-space-1)'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-v-badge-bg'] = ACCENT\n break\n case 'tint':\n tokens['--ds-nav-v-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-nav-v-active-text'] = ACCENT_INK\n tokens['--ds-nav-v-active-rail'] = '0px'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-md)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = '0px'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'var(--ds-text-secondary)'\n tokens['--ds-nav-v-badge-bg'] = ACCENT\n break\n case 'pill':\n tokens['--ds-nav-v-active-bg'] = ACCENT\n tokens['--ds-nav-v-active-text'] = ON_PRIMARY\n tokens['--ds-nav-v-active-rail'] = '0px'\n tokens['--ds-nav-v-item-radius'] = 'var(--ds-radius-sm)'\n tokens['--ds-nav-v-track-border'] = '0px'\n tokens['--ds-nav-v-track-padding'] = '0px'\n // Secondary lines on the selected row (StackedList subtitle/description/meta): readable on the accent bar under pill.\n tokens['--ds-nav-v-active-muted'] = 'color-mix(in srgb, var(--ds-text-on-primary) 80%, transparent)'\n tokens['--ds-nav-v-badge-bg'] = PILL_BADGE_BG\n break\n }\n\n // ── Tree ──────────────────────────────────────────────────────────────\n // `-muted` is the chevron on the selected row: muted grey today, on-primary\n // under pill so it stays visible on the full-width accent bar.\n switch (inPageVertical) {\n case 'rail':\n tokens['--ds-tree-active-bg'] = 'var(--ds-tab-active-bg)'\n tokens['--ds-tree-active-text'] = ACCENT_INK\n tokens['--ds-tree-active-muted'] = 'var(--ds-text-muted)'\n tokens['--ds-tree-active-rail'] = 'var(--ds-border-width-thick)'\n break\n case 'tint':\n tokens['--ds-tree-active-bg'] = ACCENT_SUBTLE\n tokens['--ds-tree-active-text'] = ACCENT_INK\n tokens['--ds-tree-active-muted'] = 'var(--ds-text-muted)'\n tokens['--ds-tree-active-rail'] = '0px'\n break\n case 'pill':\n tokens['--ds-tree-active-bg'] = ACCENT\n tokens['--ds-tree-active-text'] = ON_PRIMARY\n tokens['--ds-tree-active-muted'] = ON_PRIMARY\n tokens['--ds-tree-active-rail'] = '0px'\n break\n }\n\n // ── Sidebar ───────────────────────────────────────────────────────────\n // Decision 21: the active root label takes the sidebar accent for rail and\n // tint, matching Tabs, TreeView and NavItem (pre-20.8 it stayed neutral with\n // only the icon in accent). A deliberate default change, recorded in the\n // changelog.\n switch (sidebarActiveStyle) {\n case 'rail':\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent-subtle)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-rail'] = 'var(--ds-border-width-thick)'\n tokens['--ds-sidebar-active-image'] = 'none'\n break\n case 'tint':\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent-subtle)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_INK\n tokens['--ds-sidebar-active-rail'] = '0px'\n tokens['--ds-sidebar-active-image'] = 'none'\n break\n case 'pill':\n // The sidebar accent may come from the other palette (independent mode),\n // so its on-accent text is the scoped token, which roots.css defaults to\n // --ds-text-on-primary for match mode.\n tokens['--ds-sidebar-active-bg'] = 'var(--ds-sidebar-accent)'\n tokens['--ds-sidebar-active-text'] = SIDEBAR_ON_ACCENT\n tokens['--ds-sidebar-active-accent'] = SIDEBAR_ON_ACCENT\n tokens['--ds-sidebar-active-rail'] = '0px'\n // The pill takes the accent gradient like Button does: --ds-sidebar-gradient\n // is the page gradient in match mode and the target palette's gradient in\n // an independent mode (none when the accent is solid).\n tokens['--ds-sidebar-active-image'] = 'var(--ds-sidebar-gradient)'\n break\n }\n\n return tokens\n}\n\n/**\n * Sprint 25.14 A20: the switch's off look — no fill, and the strong edge colour for its outline and its knob, as Fluent\n * 2's off switch is. Only the theme writers emit these (generateTokensCss and ThemeContext, beside the nav style set, so\n * each scope resolves them against its own edge), never roots.css: an app that upgrades the library without\n * regenerating its stylesheet keeps the switch its stylesheet draws (the Toggle falls back to the filled one without it).\n * Sprint 25.19 K2: the edge is `--ds-control-edge-strong`, the theme's 3:1 edge, since a field's resting edge\n * (`--ds-input-border`) is the soft border again; the generator writes the strong edge in every mode's block, so a\n * stylesheet made by 0.27.0 resolves it with an earlier library's roots.css too.\n *\n * The knob is the lightest shade of the edge that still reaches 3:1 on every ground (the owner, 30 September: the black\n * knob of a black-edged theme was \"very bold, unnecessarily so\"): the edge mixed toward the surface, keeping\n * `--ds-switch-knob-share` of it. A preset whose edge is far past 3:1 sets the share per mode (neo-brutalist light keeps\n * under half its black); everywhere else it is the edge itself. The knob's place is the switch's state, so it needs\n * the 3:1 an outline does. Declared with the set, the mix reads each scope's own edge and surface.\n */\nexport const SWITCH_TOKENS: Record<string, string> = {\n '--ds-switch-off-fill': 'transparent',\n '--ds-switch-off-edge': 'var(--ds-control-edge-strong)',\n '--ds-switch-off-knob': 'color-mix(in oklab, var(--ds-control-edge-strong) var(--ds-switch-knob-share, 100%), var(--ds-bg-surface))',\n}\n\n/**\n * The checked colour (a checked box, a selected radio's dot, a switch's track when on) and its mark: the accent, unless\n * the preset sets its own for the mode. roots.css declares them once, at the root (@sync, check-tokens.test.ts checks).\n * A writer redeclares them in every block that redeclares the accent for another scope (the other mode's block, a dark\n * portal, a project's theme wrapper), before that scope's preset overrides, so they follow the scope's accent, not the\n * page's (the review of 30 September: since A20 a dark sidebar's switch on a light page took the light check colour).\n * Never under NAV_STYLE_SCOPE_SELECTOR: a same-mode wrapper or an overlay would lose the page preset's own check colour,\n * which some presets set for 3:1. --ds-check-gradient is left to inherit: a scope may take the page's `none`, a look\n * without the gradient, never a weaker fill.\n */\nexport const CHECK_TOKENS: Record<string, string> = {\n '--ds-check-bg': 'var(--ds-accent-primary)',\n '--ds-check-fg': 'var(--ds-text-on-primary)',\n '--ds-check-border': 'var(--ds-accent-primary)',\n}\n\n/**\n * Selector under which every emitter declares the nav style set. One rule\n * reaching the root, every nested mode wrapper and every overlay portal, so\n * the var() aliases resolve against each scope's own inputs.\n */\nexport const NAV_STYLE_SCOPE_SELECTOR = ':root, [data-mode], [data-ds-overlay]'\n\n// ---------------------------------------------------------------------------\n// Readable colours (Sprint 30, T1)\n// ---------------------------------------------------------------------------\n//\n// The colours a theme derives so they read on what they're drawn on: the focus outline (3:1, WCAG 1.4.11), the quiet\n// greys, the accent as text and the status words (4.5:1, 1.4.3). Each is the theme's own colour wherever that reaches\n// its minimum against every ground it sits on. Otherwise it is the nearest colour that does: the same colour a little\n// darker on a light ground, a little lighter on a dark one, keeping its hue, chroma and see-through-ness, so the look\n// changes no more than the minimum asks (the owner, 2 October 2026: the look comes first).\n//\n// The grounds are read from the theme as it is written: a preset's or a saved theme's values (the presets write them\n// with calc() and var(), which parseOklch can't read), see-through surfaces laid over the page, and the glows a canvas\n// gradient paints. Colours are laid over one another in gamma-encoded sRGB, as the browser composites them, and\n// measured with the range Chrome's rounding can land in (luminanceRange, worstContrastOf). Glass's backdrop blur and\n// saturation are not modelled; T6's Chrome pass measures the drawn page.\n\n/** A colour as the browser composites it: gamma-encoded sRGB channels (0–1, clipped to the gamut) and an alpha. */\nexport interface Paint { rgb: readonly [number, number, number]; alpha: number }\n\n/** The theme variables the roots.css scales read, as one block of tokens sees them. */\nexport interface ScaleVars {\n huePrimary: number\n satPrimary: number\n hueNeutral: number\n satNeutral: number\n hueSuccess: number\n hueWarning: number\n hueDestructive: number\n}\n\ntype ScaleName = 'primary' | 'neutral' | 'destructive' | 'success' | 'warning' | 'info'\n\n/**\n * The roots.css colour scales: [lightness, chroma] per step, the chroma multiplied by the scale's saturation where it\n * has one, at the scale's hue (info's is fixed). @sync roots.css (sprint30-readable-colours.test.ts checks every step).\n */\nexport const CSS_SCALES: Record<ScaleName, { hue: keyof ScaleVars | number; sat: keyof ScaleVars | null; steps: Record<number, readonly [number, number]> }> = {\n primary: {\n hue: 'huePrimary', sat: 'satPrimary',\n steps: { 50: [0.97, 0.025], 100: [0.93, 0.050], 200: [0.87, 0.100], 300: [0.77, 0.150], 400: [0.66, 0.180], 500: [0.55, 0.200], 600: [0.47, 0.185], 700: [0.40, 0.165], 800: [0.33, 0.135], 900: [0.25, 0.100], 950: [0.17, 0.060] },\n },\n neutral: {\n hue: 'hueNeutral', sat: 'satNeutral',\n steps: { 50: [0.97, 0.007], 100: [0.94, 0.009], 200: [0.90, 0.010], 300: [0.84, 0.010], 400: [0.71, 0.009], 500: [0.55, 0.007], 600: [0.45, 0.006], 700: [0.37, 0.005], 800: [0.27, 0.004], 900: [0.20, 0.003], 950: [0.13, 0.002] },\n },\n destructive: { hue: 'hueDestructive', sat: null, steps: { 50: [0.97, 0.015], 100: [0.93, 0.040], 400: [0.66, 0.200], 500: [0.55, 0.220], 600: [0.47, 0.200], 950: [0.15, 0.050] } },\n success: { hue: 'hueSuccess', sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.045], 400: [0.66, 0.170], 500: [0.52, 0.160], 600: [0.45, 0.145], 950: [0.15, 0.040] } },\n warning: { hue: 'hueWarning', sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.060], 400: [0.78, 0.155], 500: [0.75, 0.160], 600: [0.65, 0.145], 950: [0.20, 0.040] } },\n info: { hue: 230, sat: null, steps: { 50: [0.97, 0.020], 100: [0.93, 0.045], 400: [0.66, 0.170], 500: [0.52, 0.160], 950: [0.15, 0.040] } },\n}\n\n/** The CSS variables a colour expression may read, and the scale variable each is. */\nconst SCALE_VAR_NAMES: Record<string, keyof ScaleVars> = {\n '--ds-hue-primary': 'huePrimary',\n '--ds-sat-primary': 'satPrimary',\n '--ds-hue-neutral': 'hueNeutral',\n '--ds-sat-neutral': 'satNeutral',\n '--ds-hue-success': 'hueSuccess',\n '--ds-hue-warning': 'hueWarning',\n '--ds-hue-destructive': 'hueDestructive',\n}\n\n/** The index of the parenthesis that closes the one at `open`, or -1. */\nfunction closingParen(src: string, open: number): number {\n let depth = 0\n for (let i = open; i < src.length; i++) {\n if (src[i] === '(') depth++\n else if (src[i] === ')' && --depth === 0) return i\n }\n return -1\n}\n\n/** Splits at `sep` outside parentheses (a whitespace `sep` splits at runs of whitespace). */\nfunction splitTopLevel(src: string, sep: ',' | '/' | ' '): string[] {\n const parts: string[] = []\n let depth = 0\n let start = 0\n for (let i = 0; i < src.length; i++) {\n const ch = src[i]\n if (ch === '(') depth++\n else if (ch === ')') depth--\n else if (depth === 0 && (sep === ' ' ? /\\s/.test(ch) : ch === sep)) {\n parts.push(src.slice(start, i))\n start = i + 1\n }\n }\n parts.push(src.slice(start))\n return parts.map((p) => p.trim()).filter((p) => p !== '')\n}\n\n/**\n * A number from a CSS expression: a plain number or percentage (50% is 0.5), a var() of one of the scale variables,\n * or a calc() of those with + − × ÷. NaN for anything else (an unknown variable, a unit).\n */\nexport function evalCssNumber(expr: string, vars: ScaleVars): number {\n const src = expr.trim()\n let i = 0\n const ws = () => { while (i < src.length && /\\s/.test(src[i])) i++ }\n const sum = (): number => {\n let v = product()\n for (;;) {\n ws()\n const op = src[i]\n if (op !== '+' && op !== '-') return v\n i++\n const r = product()\n v = op === '+' ? v + r : v - r\n }\n }\n const product = (): number => {\n let v = factor()\n for (;;) {\n ws()\n const op = src[i]\n if (op !== '*' && op !== '/') return v\n i++\n const r = factor()\n v = op === '*' ? v * r : v / r\n }\n }\n const factor = (): number => {\n ws()\n if (src.startsWith('calc(', i) || src[i] === '(') {\n const open = src[i] === '(' ? i : i + 4\n const close = closingParen(src, open)\n if (close < 0) return NaN\n const inner = evalCssNumber(src.slice(open + 1, close), vars)\n i = close + 1\n return inner\n }\n if (src.startsWith('var(', i)) {\n const close = closingParen(src, i + 3)\n if (close < 0) return NaN\n const name = splitTopLevel(src.slice(i + 4, close), ',')[0]\n i = close + 1\n const key = SCALE_VAR_NAMES[name]\n return key ? vars[key] : NaN\n }\n if (src[i] === '-') { i++; return -factor() }\n const m = /^(\\d*\\.?\\d+(?:e[+-]?\\d+)?)(%|deg)?/i.exec(src.slice(i))\n if (!m) return NaN\n i += m[0].length\n return m[2] === '%' ? parseFloat(m[1]) / 100 : parseFloat(m[1])\n }\n const v = sum()\n ws()\n return i === src.length ? v : NaN\n}\n\nconst WHITE_PAINT: Paint = { rgb: [1, 1, 1], alpha: 1 }\n\nfunction paintOfOklch(colour: Oklch, alpha = 1): Paint {\n return { rgb: oklchToSrgb(colour), alpha }\n}\n\n/** A scale step's colour (--ds-neutral-400 and the rest), or null when the name is not one. */\nfunction scaleColour(name: string, vars: ScaleVars): { scale: ScaleName; step: number; colour: Oklch } | null {\n const m = /^--ds-(primary|neutral|destructive|success|warning|info)-(\\d+)$/.exec(name)\n if (!m) return null\n const scale = m[1] as ScaleName\n const def = CSS_SCALES[scale]\n const step = Number(m[2])\n const entry = def.steps[step]\n if (!entry) return null\n const sat = def.sat ? vars[def.sat] : 1\n const hue = typeof def.hue === 'number' ? def.hue : vars[def.hue]\n return { scale, step, colour: { L: entry[0], C: entry[1] * sat, H: hue } }\n}\n\n/** The parts of an oklch() value: each component's text, and its numbers where they evaluate. */\ninterface OklchParts { L: number; C: number; H: number; alpha: number; cText: string; hText: string }\n\nfunction oklchParts(value: string, vars: ScaleVars): OklchParts | null {\n const v = value.trim()\n if (!/^oklch\\(/i.test(v) || closingParen(v, 5) !== v.length - 1) return null\n const inner = v.slice(6, -1)\n if (/^\\s*from\\s/i.test(inner)) return null\n const [colourPart, alphaPart] = splitTopLevel(inner, '/')\n const comps = splitTopLevel(colourPart ?? '', ' ')\n if (comps.length !== 3) return null\n const L = evalCssNumber(comps[0], vars)\n const C = evalCssNumber(comps[1], vars)\n const H = evalCssNumber(comps[2], vars)\n const alpha = alphaPart === undefined ? 1 : evalCssNumber(alphaPart, vars)\n if (![L, C, H, alpha].every(Number.isFinite)) return null\n return { L, C, H, alpha: Math.max(0, Math.min(1, alpha)), cText: comps[1], hText: comps[2] }\n}\n\n/** `color-mix(in srgb, A p%, B q%)` as CSS Color 5 mixes it: premultiplied, the percentages normalised, a sum under 100% lowering the alpha. */\nfunction mixedPaint(value: string, tokens: Record<string, string>, vars: ScaleVars, depth: number): Paint | null {\n const v = value.trim()\n if (closingParen(v, 9) !== v.length - 1) return null\n const args = splitTopLevel(v.slice(10, -1), ',')\n if (args.length !== 3 || !/^in\\s+srgb$/i.test(args[0])) return null\n const side = (arg: string) => {\n const parts = splitTopLevel(arg, ' ')\n const pct = parts.length > 1 && /%$/.test(parts[parts.length - 1]) ? parseFloat(parts.pop()!) / 100 : undefined\n return { paint: resolvePaint(parts.join(' '), tokens, vars, depth + 1), pct }\n }\n const a = side(args[1])\n const b = side(args[2])\n if (!a.paint || !b.paint) return null\n let p1 = a.pct ?? (b.pct !== undefined ? 1 - b.pct : 0.5)\n let p2 = b.pct ?? 1 - p1\n const total = p1 + p2\n if (total <= 0) return null\n const multiplier = Math.min(1, total)\n p1 /= total\n p2 /= total\n const alpha = a.paint.alpha * p1 + b.paint.alpha * p2\n if (alpha <= 0) return { rgb: [0, 0, 0], alpha: 0 }\n const rgb = [0, 1, 2].map((i) => (a.paint!.rgb[i] * a.paint!.alpha * p1 + b.paint!.rgb[i] * b.paint!.alpha * p2) / alpha) as [number, number, number]\n return { rgb, alpha: alpha * multiplier }\n}\n\n/** A #rgb, #rrggbb or #rrggbbaa colour. */\nfunction hexPaint(value: string): Paint | null {\n const m = /^#([0-9a-f]{3,8})$/i.exec(value.trim())\n if (!m || ![3, 4, 6, 8].includes(m[1].length)) return null\n const hex = m[1].length <= 4 ? m[1].split('').map((c) => c + c).join('') : m[1]\n const n = (k: number) => parseInt(hex.slice(k * 2, k * 2 + 2), 16) / 255\n return { rgb: [n(0), n(1), n(2)], alpha: hex.length === 8 ? n(3) : 1 }\n}\n\n/** An rgb()/rgba() colour with 0–255 channels. */\nfunction rgbPaint(value: string): Paint | null {\n const m = /^rgba?\\(([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const parts = m[1].split(/[\\s,/]+/).filter(Boolean)\n if (parts.length < 3) return null\n const ch = parts.slice(0, 3).map((p) => (p.endsWith('%') ? parseFloat(p) / 100 : parseFloat(p) / 255))\n const alpha = parts[3] === undefined ? 1 : parts[3].endsWith('%') ? parseFloat(parts[3]) / 100 : parseFloat(parts[3])\n if (![...ch, alpha].every(Number.isFinite)) return null\n return { rgb: ch.map((c) => Math.max(0, Math.min(1, c))) as [number, number, number], alpha }\n}\n\n/**\n * A token or a CSS colour value as the browser would paint it, followed through the block's own declarations\n * (`tokens`) and the roots.css scales. Null where it can't be known (an image, an unknown function or variable).\n */\nexport function resolvePaint(value: string, tokens: Record<string, string>, vars: ScaleVars, depth = 0): Paint | null {\n if (depth > 24) return null\n const v = value.trim()\n if (v === 'transparent') return { rgb: [0, 0, 0], alpha: 0 }\n if (v.startsWith('var(')) {\n if (closingParen(v, 3) !== v.length - 1) return null\n const [name, ...fallback] = splitTopLevel(v.slice(4, -1), ',')\n const own = tokens[name]\n if (own !== undefined) return resolvePaint(own, tokens, vars, depth + 1)\n const scaled = scaleColour(name, vars)\n if (scaled) return paintOfOklch(scaled.colour)\n return fallback.length ? resolvePaint(fallback.join(','), tokens, vars, depth + 1) : null\n }\n if (/^oklch\\(/i.test(v)) {\n const parts = oklchParts(v, vars)\n return parts ? paintOfOklch({ L: parts.L, C: parts.C, H: parts.H }, parts.alpha) : null\n }\n if (/^color-mix\\(/i.test(v)) return mixedPaint(v, tokens, vars, depth)\n if (v.startsWith('#')) return hexPaint(v)\n if (/^rgba?\\(/i.test(v)) return rgbPaint(v)\n if (/^color\\(\\s*srgb\\s/i.test(v)) return srgbFunctionPaint(v)\n if (/^oklab\\(/i.test(v)) return oklabPaint(v)\n return null\n}\n\n/** `color(srgb r g b / a)`, as Chrome serialises a computed colour mixed in sRGB. */\nfunction srgbFunctionPaint(value: string): Paint | null {\n const m = /^color\\(\\s*srgb\\s+([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const [rgbPart, alphaPart] = m[1].split('/')\n const ch = rgbPart.trim().split(/\\s+/).map((p) => (p.endsWith('%') ? parseFloat(p) / 100 : parseFloat(p)))\n const alpha = alphaPart === undefined ? 1 : alphaPart.trim().endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart)\n if (ch.length !== 3 || ![...ch, alpha].every(Number.isFinite)) return null\n return { rgb: ch.map((c) => Math.max(0, Math.min(1, c))) as [number, number, number], alpha }\n}\n\n/** `oklab(L a b / alpha)`, as Chrome serialises some computed colours. */\nfunction oklabPaint(value: string): Paint | null {\n const m = /^oklab\\(([^)]*)\\)$/i.exec(value.trim())\n if (!m) return null\n const [labPart, alphaPart] = m[1].split('/')\n const [L, a, b] = labPart.trim().split(/\\s+/).map((p, i) => (p.endsWith('%') ? (parseFloat(p) / 100) * (i === 0 ? 1 : 0.4) : parseFloat(p)))\n const alpha = alphaPart === undefined ? 1 : alphaPart.trim().endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart)\n if (![L, a, b, alpha].every(Number.isFinite)) return null\n return paintOfOklch({ L, C: Math.hypot(a, b), H: ((Math.atan2(b, a) * 180) / Math.PI + 360) % 360 }, alpha)\n}\n\n/** `top` laid over `ground` (source-over in gamma-encoded sRGB, as the browser composites). */\nexport function paintOver(top: Paint, ground: Paint): Paint {\n const alpha = top.alpha + ground.alpha * (1 - top.alpha)\n if (alpha <= 0) return { rgb: [0, 0, 0], alpha: 0 }\n const rgb = [0, 1, 2].map((i) => (top.rgb[i] * top.alpha + ground.rgb[i] * ground.alpha * (1 - top.alpha)) / alpha) as [number, number, number]\n return { rgb, alpha }\n}\n\n/** The lowest contrast `text` shows over an opaque `ground` (see-through text laid over it first), every way either can round. */\nexport function paintContrast(text: Paint, ground: Paint): number {\n const drawnGround = ground.alpha >= 1 ? ground : paintOver(ground, WHITE_PAINT)\n return worstContrastOf(srgbLuminanceRange(paintOver(text, drawnGround).rgb), srgbLuminanceRange(drawnGround.rgb))\n}\n\n/** The lowest contrast `text` shows over any of `grounds` (Infinity for none). */\nexport function worstPaintContrast(text: Paint, grounds: readonly Paint[]): number {\n let min = Infinity\n for (const g of grounds) min = Math.min(min, paintContrast(text, g))\n return min\n}\n\n/**\n * The colours a canvas gradient shows (presets.ts's `canvasGradientLight`/`Dark`, a saved theme's own): its last\n * layer's colours are the base, each laid over the canvas colour if see-through; every layer above is laid over each\n * base colour at the strongest it shows. A radial glow fades from its first colour to transparent, so where its centre\n * sits outside the page only part of it shows (an `ellipse 80% 50% at 20% -10%` peaks at 71% at the top edge, its\n * nearest point); a line pattern or a flat wash shows at full strength somewhere.\n */\nexport function gradientPaints(gradient: string, tokens: Record<string, string>, vars: ScaleVars, under: Paint): Paint[] {\n const layers = splitLayers(gradient)\n if (!layers.length) return []\n const parsed = layers.map((layer) => gradientLayer(layer, tokens, vars))\n const bases = uniquePaints(parsed[parsed.length - 1].stops.map((s) => (s.paint.alpha >= 1 ? s.paint : paintOver(s.paint, under))))\n if (!bases.length) bases.push(under)\n const out = [...bases]\n for (const layer of parsed.slice(0, -1)) {\n const lead = layer.stops.find((s) => s.paint.alpha > 0)\n if (!lead) continue\n const strength = layer.radial ? radialStrength(layer.radial, layer.stops) : 1\n const glow: Paint = { rgb: lead.paint.rgb, alpha: lead.paint.alpha * strength }\n if (glow.alpha <= 0) continue\n for (const base of bases) out.push(paintOver(glow, base))\n }\n return out\n}\n\n/** The paints, each once. */\nfunction uniquePaints(paints: Paint[]): Paint[] {\n const seen = new Set<string>()\n return paints.filter((p) => {\n const key = `${p.rgb.map((c) => c.toFixed(5)).join(',')}/${p.alpha.toFixed(5)}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\n/** A gradient value's layers: each top-level `…-gradient(…)` function. */\nfunction splitLayers(gradient: string): string[] {\n const layers: string[] = []\n const re = /(?:repeating-)?(?:linear|radial|conic)-gradient\\(/gi\n let m: RegExpExecArray | null\n while ((m = re.exec(gradient))) {\n const open = m.index + m[0].length - 1\n const close = closingParen(gradient, open)\n if (close < 0) break\n layers.push(gradient.slice(m.index, close + 1))\n re.lastIndex = close + 1\n }\n return layers\n}\n\ninterface GradientStop { paint: Paint; pos?: number }\ninterface RadialShape { rx: number; ry: number; cx: number; cy: number }\n\n/** One gradient layer's colour stops (with their first position, as a fraction) and, for an ellipse, its shape. */\nfunction gradientLayer(layer: string, tokens: Record<string, string>, vars: ScaleVars): { stops: GradientStop[]; radial?: RadialShape } {\n const open = layer.indexOf('(')\n const args = splitTopLevel(layer.slice(open + 1, -1), ',')\n const stops: GradientStop[] = []\n let radial: RadialShape | undefined\n args.forEach((arg, k) => {\n const parts = splitTopLevel(arg, ' ')\n const paint = parts.length ? resolvePaint(parts[0], tokens, vars) : null\n if (paint) {\n const pos = parts[1] !== undefined ? evalCssNumber(parts[1], vars) : undefined\n stops.push({ paint, pos: Number.isFinite(pos) ? pos : undefined })\n return\n }\n if (k === 0 && /^radial/i.test(layer)) {\n const shape = /ellipse\\s+(-?[\\d.]+)%\\s+(-?[\\d.]+)%\\s+at\\s+(-?[\\d.]+)%\\s+(-?[\\d.]+)%/i.exec(arg)\n if (shape) radial = { rx: +shape[1], ry: +shape[2], cx: +shape[3], cy: +shape[4] }\n }\n })\n return { stops, radial }\n}\n\n/** How strongly a radial glow's first colour shows at its nearest point on the page (1 when its centre is on the page). */\nfunction radialStrength(shape: RadialShape, stops: GradientStop[]): number {\n const px = Math.max(0, Math.min(100, shape.cx))\n const py = Math.max(0, Math.min(100, shape.cy))\n const d = Math.hypot((px - shape.cx) / shape.rx, (py - shape.cy) / shape.ry)\n const leadIndex = stops.findIndex((s) => s.paint.alpha > 0)\n const start = stops[leadIndex]?.pos ?? 0\n const end = stops.slice(leadIndex + 1).find((s) => s.paint.alpha === 0)?.pos ?? 1\n if (d <= start) return 1\n if (d >= end) return 0\n return (end - d) / (end - start)\n}\n\n/** A candidate colour: the CSS a writer emits, and how it paints. */\nexport interface ColourCandidate { value: string; paint: Paint }\n\n/**\n * The shared routine (Sprint 30): the first candidate, in the order given, that reaches `minimum` against every ground\n * and that `accept` takes. mutedOnTint walks the neutral scale's steps with it; the readable tokens walk the theme's\n * own colour in small steps (walkCandidates).\n */\nexport function firstReadable(candidates: Iterable<ColourCandidate>, grounds: readonly Paint[], minimum: number, accept: (c: ColourCandidate) => boolean = () => true): ColourCandidate | null {\n for (const c of candidates) {\n if (worstPaintContrast(c.paint, grounds) >= minimum && accept(c)) return c\n }\n return null\n}\n\n/** A colour as written, ready to be walked: its lightness and alpha as numbers, its chroma and hue as the CSS that writes them. */\ninterface WalkableColour {\n L: number\n alpha: number\n H: number\n /** The chroma at a lightness: a scale's chroma follows the scale's curve between its steps. */\n chroma: (L: number) => number\n chromaText: (L: number) => string\n hueText: string\n}\n\n/** The chroma coefficient of a scale at a lightness, read off the line between its two nearest steps. */\nfunction scaleChromaAt(scale: ScaleName, L: number): number {\n const points = Object.values(CSS_SCALES[scale].steps).map(([l, c]) => [l, c] as const).sort((a, b) => a[0] - b[0])\n if (L <= points[0][0]) return points[0][1]\n if (L >= points[points.length - 1][0]) return points[points.length - 1][1]\n for (let k = 1; k < points.length; k++) {\n const [l1, c1] = points[k]\n const [l0, c0] = points[k - 1]\n if (L <= l1) return c0 + ((c1 - c0) * (L - l0)) / (l1 - l0)\n }\n return points[points.length - 1][1]\n}\n\nconst fixed = (n: number, places: number) => String(+n.toFixed(places))\n\n/** The colour a token's value finally writes, followed through var(), in a form the walk can step. Null for a mix or an image. */\nfunction walkableColour(value: string, tokens: Record<string, string>, vars: ScaleVars, depth = 0): WalkableColour | null {\n if (depth > 24) return null\n const v = value.trim()\n if (v.startsWith('var(')) {\n if (closingParen(v, 3) !== v.length - 1) return null\n const [name, ...fallback] = splitTopLevel(v.slice(4, -1), ',')\n const own = tokens[name]\n if (own !== undefined) return walkableColour(own, tokens, vars, depth + 1)\n const scaled = scaleColour(name, vars)\n if (scaled) {\n const def = CSS_SCALES[scaled.scale]\n const satVar = def.sat ? Object.keys(SCALE_VAR_NAMES).find((k) => SCALE_VAR_NAMES[k] === def.sat) : undefined\n const hueVar = typeof def.hue === 'number' ? undefined : Object.keys(SCALE_VAR_NAMES).find((k) => SCALE_VAR_NAMES[k] === def.hue)\n const sat = def.sat ? vars[def.sat] : 1\n return {\n L: scaled.colour.L,\n alpha: 1,\n H: scaled.colour.H,\n chroma: (L) => scaleChromaAt(scaled.scale, L) * sat,\n chromaText: (L) => (satVar ? `calc(${fixed(scaleChromaAt(scaled.scale, L), 4)} * var(${satVar}))` : fixed(scaleChromaAt(scaled.scale, L), 4)),\n hueText: hueVar ? `var(${hueVar})` : String(def.hue),\n }\n }\n return fallback.length ? walkableColour(fallback.join(','), tokens, vars, depth + 1) : null\n }\n const parts = oklchParts(v, vars)\n if (!parts) return null\n return { L: parts.L, alpha: parts.alpha, H: parts.H, chroma: () => parts.C, chromaText: () => parts.cText, hueText: parts.hText }\n}\n\n/** The CSS for a walked colour. */\nfunction walkedCss(c: WalkableColour, L: number, alpha: number): string {\n return `oklch(${fixed(L, 3)} ${c.chromaText(L)} ${c.hueText}${alpha < 1 ? ` / ${fixed(alpha, 2)}` : ''})`\n}\n\n/**\n * The colours a walk tries after the theme's own: a see-through colour first grows more opaque, 5% at a time; then the\n * lightness steps by 0.01 toward contrast (darker for `dir` −1, on a light ground; lighter for +1).\n */\nfunction* walkCandidates(c: WalkableColour, dir: 1 | -1): Generator<ColourCandidate> {\n let alpha = c.alpha\n while (alpha < 1 - 1e-9) {\n alpha = Math.min(1, +(alpha + 0.05).toFixed(2))\n yield { value: walkedCss(c, c.L, alpha), paint: paintOfOklch({ L: c.L, C: c.chroma(c.L), H: c.H }, alpha) }\n }\n for (let L = +(c.L + dir * 0.01).toFixed(3); L >= 0 && L <= 1; L = +(L + dir * 0.01).toFixed(3)) {\n yield { value: walkedCss(c, L, 1), paint: paintOfOklch({ L, C: c.chroma(L), H: c.H }, 1) }\n }\n}\n\n/**\n * The readable colour for one token: `own` (as written) where it reaches `minimum` against every ground and `accept`\n * takes it; else the nearest step of its walk that does; else `fallback`. Returns the CSS to emit and its paint.\n */\nfunction readableColour(own: string, grounds: readonly Paint[], minimum: number, dir: 1 | -1, tokens: Record<string, string>, vars: ScaleVars, fallback: string, accept: (c: ColourCandidate) => boolean = () => true): ColourCandidate {\n const ownPaint = resolvePaint(own, tokens, vars)\n const first = ownPaint ? firstReadable([{ value: own, paint: ownPaint }], grounds, minimum, accept) : null\n if (first) return first\n const walkable = walkableColour(own, tokens, vars)\n const walked = walkable ? firstReadable(walkCandidates(walkable, dir), grounds, minimum, accept) : null\n if (walked) return walked\n return { value: fallback, paint: resolvePaint(fallback, tokens, vars) ?? ownPaint ?? WHITE_PAINT }\n}\n\n/**\n * Tokens roots.css declares that the shared semantic defaults leave out: the derivations read them where a block\n * doesn't declare its own. @sync roots.css.\n */\nconst ROOTS_COLOUR_DEFAULTS: Record<string, string> = {\n '--ds-accent-subtle': 'color-mix(in srgb, var(--ds-accent-primary) 10%, transparent)',\n '--ds-accent-muted': 'color-mix(in srgb, var(--ds-accent-primary) 20%, transparent)',\n '--ds-sidebar-accent-subtle': 'color-mix(in srgb, var(--ds-sidebar-accent) 10%, transparent)',\n '--ds-header-accent-subtle': 'color-mix(in srgb, var(--ds-header-accent) 10%, transparent)',\n '--ds-tint-strength': String(TINT_STRENGTH),\n}\n\n/** The see-through layer `name` resolves to laid over each ground (the grounds unchanged where it can't be read). */\nfunction layered(name: string, grounds: readonly Paint[], tokens: Record<string, string>, vars: ScaleVars): Paint[] {\n const top = resolvePaint(`var(${name})`, tokens, vars)\n return top ? grounds.map((g) => paintOver(top, g)) : []\n}\n\nexport interface ReadableInput {\n /** The block's mode: its walks go darker on a light page, lighter on a dark one. */\n mode: 'light' | 'dark'\n /** Every declaration the block sees, in cascade order: the mode's semantic defaults, the writer's tokens, the preset's or saved theme's overrides, the status palette. */\n tokens: Record<string, string>\n vars: ScaleVars\n /** The canvas gradient painted under the page, if the theme has one for this mode. */\n canvasGradient?: string\n /** Whether to derive the sidebar family too (a mode's block; an independent sidebar derives its own with readableSidebarTokens). */\n sidebar?: boolean\n}\n\nexport interface ReadableResult {\n /** The derived tokens, to declare after the block's overrides. */\n tokens: Record<string, string>\n /** Each derived token's own colour before the derivation (the Focus page's \"before\"). */\n inputs: Record<string, string>\n}\n\n/**\n * The scale variables a theme state shows in a mode, as the preview writers' ROOT_MAP sets them on <html>: the dark\n * palette's hues and saturations in dark mode, the light ones otherwise; the status hues are shared.\n */\nexport function scaleVarsOf(s: {\n huePrimary: number; satPrimary: number; hueNeutral: number; satNeutral: number\n darkHuePrimary: number; darkSatPrimary: number; darkHueNeutral: number; darkSatNeutral: number\n hueSuccess: number; hueWarning: number; hueDestructive: number\n}, mode: 'light' | 'dark'): ScaleVars {\n const dark = mode === 'dark'\n return {\n huePrimary: dark ? s.darkHuePrimary : s.huePrimary,\n satPrimary: dark ? s.darkSatPrimary : s.satPrimary,\n hueNeutral: dark ? s.darkHueNeutral : s.hueNeutral,\n satNeutral: dark ? s.darkSatNeutral : s.satNeutral,\n hueSuccess: s.hueSuccess,\n hueWarning: s.hueWarning,\n hueDestructive: s.hueDestructive,\n }\n}\n\n/** The colours the page's canvas shows: the canvas colour (over white where see-through) and, with a gradient, every colour it paints. */\nexport function canvasPaints(tokens: Record<string, string>, vars: ScaleVars, canvasGradient?: string): Paint[] {\n const base = resolvePaint('var(--ds-bg-canvas)', tokens, vars)\n const canvasColour = base ? (base.alpha >= 1 ? base : paintOver(base, WHITE_PAINT)) : WHITE_PAINT\n return [canvasColour, ...(canvasGradient ? gradientPaints(canvasGradient, tokens, vars, canvasColour) : [])]\n}\n\n/** The page's grounds for a block: the canvas (and its gradient's colours), and the surface and the raised surface over each. */\nfunction pageGrounds(input: ReadableInput): { canvas: Paint[]; page: Paint[] } {\n const { tokens, vars } = input\n const canvas = canvasPaints(tokens, vars, input.canvasGradient)\n return { canvas, page: [...canvas, ...layered('--ds-bg-surface', canvas, tokens, vars), ...layered('--ds-bg-surface-elevated', canvas, tokens, vars)] }\n}\n\n/** The colours a fill of the accent paints: the accent, or every colour its gradient paints (gradientFills). */\nfunction accentFillPaints(tokens: Record<string, string>, vars: ScaleVars): Paint[] {\n const accent = resolvePaint('var(--ds-accent-primary)', tokens, vars)\n const gradient = (tokens['--ds-gradient'] ?? 'none').trim()\n if (gradient !== 'none' && gradient !== '') {\n const start = walkableColour(tokens['--ds-gradient-start'] ?? '', tokens, vars)\n const end = walkableColour(tokens['--ds-gradient-end'] ?? '', tokens, vars)\n if (start && end) {\n return gradientFills({ L: start.L, C: start.chroma(start.L), H: start.H }, { L: end.L, C: end.chroma(end.L), H: end.H }).map((c) => paintOfOklch(c))\n }\n }\n return accent ? [accent] : []\n}\n\n/** The text on the accent fill, quieter: the quietest of it at 60–90% that reaches 4.5:1 over every colour the fill paints. */\nfunction quietOnAccent(tokens: Record<string, string>, vars: ScaleVars): string {\n const fills = accentFillPaints(tokens, vars)\n const text = resolvePaint('var(--ds-text-on-primary)', tokens, vars)\n if (!text || !fills.length) return 'var(--ds-text-on-primary)'\n const candidates = [60, 70, 80, 90].map((pct): ColourCandidate => ({ value: `color-mix(in srgb, var(--ds-text-on-primary) ${pct}%, transparent)`, paint: { rgb: text.rgb, alpha: text.alpha * pct / 100 } }))\n return firstReadable(candidates, fills, WCAG_AA_TEXT)?.value ?? 'var(--ds-text-on-primary)'\n}\n\n/** The status words and the colour each starts from: the status colour, or warning's own text colour. */\nconst STATUS_WORDS: Array<[status: 'success' | 'warning' | 'error' | 'info', own: string]> = [\n ['success', '--ds-status-success'],\n ['warning', '--ds-status-warning-text'],\n ['error', '--ds-status-error'],\n ['info', '--ds-status-info'],\n]\n\n/** The status's words: its own colour where it reads on its soft background and on the page, else the soft pair's text at its hue (D4). */\nfunction statusWords(status: string, own: string, page: readonly Paint[], mode: 'light' | 'dark', tokens: Record<string, string>, vars: ScaleVars): ColourCandidate {\n const ownValue = tokens[own] ?? `var(${own})`\n const grounds = [...page, ...layered(`--ds-status-${status}-bg`, page, tokens, vars)]\n const ownPaint = resolvePaint(ownValue, tokens, vars)\n const walkable = walkableColour(ownValue, tokens, vars)\n const candidates: ColourCandidate[] = []\n if (ownPaint) candidates.push({ value: ownValue, paint: ownPaint })\n if (walkable) {\n const pair = softPair(walkable.H)\n const text = mode === 'light' ? pair.dark : pair.subtle\n const paint = resolvePaint(text, tokens, vars)\n if (paint) candidates.push({ value: text, paint })\n }\n return firstReadable(candidates, grounds, WCAG_AA_TEXT) ?? { value: 'var(--ds-text-primary)', paint: resolvePaint('var(--ds-text-primary)', tokens, vars) ?? WHITE_PAINT }\n}\n\n/**\n * Every token a block's readable colours set (readableTokens with the sidebar's family): what a writer declares after\n * its overrides, and what a check comparing a block with roots.css's own values leaves out.\n */\nexport const READABLE_TOKEN_NAMES: ReadonlySet<string> = new Set([\n '--ds-focus', '--ds-accent-ink', '--ds-text-muted', '--ds-text-secondary',\n '--ds-status-success-text', '--ds-status-warning-text', '--ds-status-error-text', '--ds-status-info-text',\n '--ds-text-on-primary-muted',\n '--ds-sidebar-text-muted', '--ds-sidebar-text-secondary', '--ds-sidebar-focus', '--ds-sidebar-accent-ink',\n])\n\n/** How much louder the secondary grey stays than the muted one, as a ratio of their contrasts (the hierarchy, P7). */\nexport const QUIET_HIERARCHY = 1.2\n\n/**\n * The tokens a mode's block derives so its colours read (Sprint 30: P1, P7, P8, P10, and the bold band's quiet text):\n * `--ds-focus` at 3:1, the greys, `--ds-accent-ink` and the status words at 4.5:1. With `sidebar`, the sidebar's family\n * too (readableSidebarTokens). Writers declare the result after the block's overrides.\n */\nexport function readableTokens(input: ReadableInput): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n input = { ...input, tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const { canvas, page } = pageGrounds(input)\n // What the colours sit on besides the page: its muted fill (a hovered row, a hint's key, a neutral trend) and the\n // accent's two tints (a selected row and a date range's days at 10%, the range's ends and a hovered accent action at 20%)\n const mutedFill = layered('--ds-bg-muted', page, tokens, vars)\n const accentTints = [...layered('--ds-accent-subtle', page, tokens, vars), ...layered('--ds-accent-muted', page, tokens, vars)]\n const out: Record<string, string> = {}\n const inputs: Record<string, string> = {}\n\n // The focus colour: on the page, its muted fill, the accent's tints, the subtle header's tint and the bold band's\n // strip (the surface, at least 60% opaque, over every colour the band paints)\n const accent = resolvePaint('var(--ds-accent-primary)', tokens, vars)\n const strength = evalCssNumber(tokens['--ds-tint-strength'] ?? String(TINT_STRENGTH), vars)\n const headerTint = accent && Number.isFinite(strength) ? layeredPaint({ rgb: accent.rgb, alpha: accent.alpha * strength }, layered('--ds-bg-surface', canvas, tokens, vars)) : []\n const surface = resolvePaint('var(--ds-bg-surface)', tokens, vars)\n const strip = surface ? accentFillPaints(tokens, vars).map((fill) => paintOver({ rgb: surface.rgb, alpha: Math.max(surface.alpha, 0.6) }, fill)) : []\n const focus = readableColour('var(--ds-accent-primary)', [...page, ...mutedFill, ...accentTints, ...headerTint, ...strip], 3, dir, tokens, vars, 'var(--ds-text-primary)')\n out['--ds-focus'] = focus.value\n inputs['--ds-focus'] = 'var(--ds-accent-primary)'\n\n // The accent as text, a mark or a state's edge: on the page, its muted fill and the accent's own tints\n out['--ds-accent-ink'] = readableColour('var(--ds-accent-primary)', [...page, ...mutedFill, ...accentTints], WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-primary)').value\n inputs['--ds-accent-ink'] = 'var(--ds-accent-primary)'\n\n // The greys, on the page and its muted fill: the muted one first, then the secondary one, kept louder than it\n const greyGrounds = [...page, ...mutedFill]\n const mutedOwn = tokens['--ds-text-muted'] ?? 'var(--ds-neutral-400)'\n const muted = readableColour(mutedOwn, greyGrounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-secondary)')\n const mutedContrast = worstPaintContrast(muted.paint, greyGrounds)\n const secondaryOwn = tokens['--ds-text-secondary'] ?? 'var(--ds-neutral-600)'\n const secondary = readableColour(secondaryOwn, greyGrounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-text-primary)', (c) => worstPaintContrast(c.paint, greyGrounds) >= mutedContrast * QUIET_HIERARCHY)\n out['--ds-text-muted'] = muted.value\n out['--ds-text-secondary'] = secondary.value\n inputs['--ds-text-muted'] = mutedOwn\n inputs['--ds-text-secondary'] = secondaryOwn\n\n // The status words (D4): on their soft backgrounds and on the page\n for (const [status, own] of STATUS_WORDS) {\n out[`--ds-status-${status}-text`] = statusWords(status, own, page, mode, tokens, vars).value\n inputs[`--ds-status-${status}-text`] = tokens[own] ?? `var(${own})`\n }\n\n // The bold band's quieter text\n out['--ds-text-on-primary-muted'] = quietOnAccent(tokens, vars)\n inputs['--ds-text-on-primary-muted'] = 'color-mix(in srgb, var(--ds-text-on-primary) 70%, transparent)'\n\n if (input.sidebar) {\n const sidebar = readableSidebarTokens({ mode, tokens: { ...tokens, ...out }, vars, canvas })\n Object.assign(out, sidebar.tokens)\n Object.assign(inputs, sidebar.inputs)\n }\n return { tokens: out, inputs }\n}\n\nfunction layeredPaint(top: Paint, grounds: readonly Paint[]): Paint[] {\n return grounds.map((g) => paintOver(top, g))\n}\n\n/**\n * The sidebar family's readable tokens, against the sidebar's own background (laid over the page's canvas where it is\n * see-through) and an item's hover: its quiet text, its focus colour and its current item's accent (P2, P7, P8). A\n * value that reads as it is (an alias of the page's derived token, mostly) is kept as written.\n */\nexport function readableSidebarTokens(input: { mode: 'light' | 'dark'; tokens: Record<string, string>; vars: ScaleVars; canvas?: Paint[] }): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const canvas = input.canvas ?? canvasPaints(tokens, vars)\n const bg = layered('--ds-sidebar-bg', canvas, tokens, vars)\n const grounds = bg.length ? [...bg, ...layered('--ds-sidebar-item-hover', bg, tokens, vars)] : canvas\n const out: Record<string, string> = {}\n const inputs: Record<string, string> = {}\n const own = (name: string, otherwise: string) => tokens[name] ?? otherwise\n\n const mutedOwn = own('--ds-sidebar-text-muted', 'var(--ds-text-muted)')\n const muted = readableColour(mutedOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)')\n const mutedContrast = worstPaintContrast(muted.paint, grounds)\n const secondaryOwn = own('--ds-sidebar-text-secondary', 'var(--ds-text-secondary)')\n const secondary = readableColour(secondaryOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)', (c) => worstPaintContrast(c.paint, grounds) >= mutedContrast * QUIET_HIERARCHY)\n out['--ds-sidebar-text-muted'] = muted.value\n out['--ds-sidebar-text-secondary'] = secondary.value\n inputs['--ds-sidebar-text-muted'] = mutedOwn\n inputs['--ds-sidebar-text-secondary'] = secondaryOwn\n\n // The focus colour: the page's where it reads on the sidebar, else the sidebar accent walked\n const pageFocus = resolvePaint('var(--ds-focus)', tokens, vars)\n out['--ds-sidebar-focus'] = pageFocus && worstPaintContrast(pageFocus, grounds) >= 3\n ? 'var(--ds-focus)'\n : readableColour('var(--ds-sidebar-accent)', grounds, 3, dir, tokens, vars, 'var(--ds-sidebar-text)').value\n inputs['--ds-sidebar-focus'] = 'var(--ds-sidebar-accent)'\n\n // The current item's accent, on the sidebar and on its own tint\n const tint = layered('--ds-sidebar-accent-subtle', grounds, tokens, vars)\n out['--ds-sidebar-accent-ink'] = readableColour('var(--ds-sidebar-accent)', [...grounds, ...tint], WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-sidebar-text)').value\n inputs['--ds-sidebar-accent-ink'] = 'var(--ds-sidebar-accent)'\n return { tokens: out, inputs }\n}\n\n/**\n * The builder preview's independent header (applyHeaderOverrides; a generated app wraps its header in data-mode\n * instead, so the mode blocks cover it): the header family's focus colour, quiet text and accent ink against its own\n * background. BuilderShell's header wrapper maps the page's tokens onto them.\n */\nexport function readableHeaderTokens(input: { mode: 'light' | 'dark'; tokens: Record<string, string>; vars: ScaleVars }): ReadableResult {\n const { mode, vars } = input\n const tokens = { ...ROOTS_COLOUR_DEFAULTS, ...input.tokens }\n const dir: 1 | -1 = mode === 'light' ? -1 : 1\n const bg = resolvePaint('var(--ds-header-bg)', tokens, vars)\n const base = bg ? (bg.alpha >= 1 ? bg : paintOver(bg, WHITE_PAINT)) : WHITE_PAINT\n const grounds = [base, ...layered('--ds-header-hover', [base], tokens, vars)]\n const mutedOwn = tokens['--ds-header-text-muted'] ?? 'var(--ds-text-muted)'\n return {\n tokens: {\n '--ds-header-focus': readableColour('var(--ds-header-accent)', grounds, 3, dir, tokens, vars, 'var(--ds-header-text)').value,\n '--ds-header-text-muted': readableColour(mutedOwn, grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-header-text)').value,\n '--ds-header-accent-ink': readableColour('var(--ds-header-accent)', grounds, WCAG_AA_TEXT, dir, tokens, vars, 'var(--ds-header-text)').value,\n },\n inputs: { '--ds-header-focus': 'var(--ds-header-accent)', '--ds-header-text-muted': mutedOwn, '--ds-header-accent-ink': 'var(--ds-header-accent)' },\n }\n}\n","import { onFillTextValue, parseOklch } from \"../../lib/token-algorithms\";\nimport { forwardRef, useLayoutEffect, useRef, useState } from \"react\";\nimport {\n Treemap,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent, useRadius } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface TreemapNode {\n name: string;\n value?: number;\n children?: TreemapNode[];\n [key: string]: unknown;\n}\n\nexport interface TreemapChartProps {\n data: TreemapNode[];\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\ninterface TreemapContentProps {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n name?: string;\n depth?: number;\n colors: string[];\n radius: number;\n index?: number;\n /** The label's line height and font size in px, read from the page (null until read). */\n metrics: LabelMetrics | null;\n}\n\ninterface LabelMetrics { lineHeight: number; fontSize: number }\n\n/** A label's inset from its cell's edges. */\nconst LABEL_INSET = 4;\n\n/**\n * How many lines of a label a cell holds (Sprint 25.17 A25, R28-55): as many as its height takes inside the inset; none\n * when it can't hold one line, or is narrower than about three characters, since a sliver of a word reads as nothing.\n */\nexport function treemapLabelLines(width: number, height: number, metrics: LabelMetrics): number {\n if (width - 2 * LABEL_INSET < metrics.fontSize * 3) return 0;\n return Math.max(0, Math.floor((height - 2 * LABEL_INSET) / metrics.lineHeight));\n}\n\n/** Colours as the browser computes them, once each: a token's var() and calc() resolved (\"oklch(0.66 calc(0.18 * 1) 280)\"). */\nconst computedColors = new Map<string, string>();\nfunction computedColor(css: string): string {\n if (typeof document === \"undefined\") return css;\n let value = computedColors.get(css);\n if (value === undefined) {\n const probe = document.createElement(\"span\");\n probe.style.color = css;\n document.body.appendChild(probe);\n value = getComputedStyle(probe).color;\n probe.remove();\n computedColors.set(css, value);\n }\n return value;\n}\n\n/**\n * The label's colour over its cell: the library's one on-fill decision (onFillTextValue: white where it reaches AA, else\n * a deep tint of the fill), for the theme's oklch fills, read as the browser computes them (Sprint 25.17's review: read\n * as hex, every label was white, under 4.5:1 on the lighter cells of every dark preset; a fill with a calc() in it didn't\n * parse); any other colour by its brightness.\n */\nfunction labelColorOn(fill: string): string {\n const parsed = parseOklch(fill) ?? parseOklch(computedColor(fill));\n return parsed ? onFillTextValue(parsed) : contrastColor(computedColor(fill));\n}\n\n/** Dark or white text by a colour's brightness: a hex colour, or rgb() as the browser writes one. */\nfunction contrastColor(color: string): string {\n const rgb = /^rgba?\\(\\s*(\\d+)[\\s,]+(\\d+)[\\s,]+(\\d+)/.exec(color);\n const c = color.replace(\"#\", \"\");\n const [r, g, b] = rgb ? [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])] : c.length >= 6 ? [parseInt(c.substring(0, 2), 16), parseInt(c.substring(2, 4), 16), parseInt(c.substring(4, 6), 16)] : [0, 0, 0];\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n return luminance > 0.55 ? \"#1f2937\" : \"#ffffff\";\n}\n\nfunction TreemapContent({ x = 0, y = 0, width = 0, height: h = 0, name, depth, colors, radius, index = 0, metrics }: TreemapContentProps) {\n const fill = colors[index % colors.length];\n // the label wraps onto the lines the cell holds, then ends in \"…\", and never leaves the cell (the owner: \"wrap and\n // truncate like our other items\"); SVG text doesn't wrap, so it is HTML in the cell, clamped as the library's other\n // labels are. A word too long for the cell is hyphenated where the page's language allows, else broken. The tooltip\n // keeps the full name.\n const lines = metrics && name ? treemapLabelLines(width, h, metrics) : 0;\n const labelColor = labelColorOn(fill);\n\n return (\n <g>\n <rect\n x={x}\n y={y}\n width={width}\n height={h}\n fill={fill}\n stroke=\"var(--ds-bg-surface)\"\n strokeWidth={2}\n rx={depth === 1 ? radius : 0}\n style={{ opacity: depth === 1 ? 1 : 0.85 }}\n />\n {lines > 0 && (\n <foreignObject x={x} y={y} width={width} height={h} style={{ pointerEvents: \"none\" }}>\n <div className=\"flex h-full w-full items-center justify-center overflow-hidden text-center\" style={{ padding: LABEL_INSET }}>\n <span\n data-treemap-label=\"\"\n className={LABEL_TEXT}\n style={{ color: labelColor, display: \"-webkit-box\", WebkitBoxOrient: \"vertical\", WebkitLineClamp: lines, overflow: \"hidden\", overflowWrap: \"anywhere\", hyphens: \"auto\" }}\n >\n {name}\n </span>\n </div>\n </foreignObject>\n )}\n </g>\n );\n}\n\nfunction addFillToNodes(nodes: TreemapNode[], colors: string[], counter = { i: 0 }): TreemapNode[] {\n return nodes.map((node) => {\n if (node.children) {\n return { ...node, children: addFillToNodes(node.children, colors, counter) };\n }\n const fill = colors[counter.i % colors.length];\n counter.i++;\n return { ...node, fill };\n });\n}\n\n/** The label's type: the theme's small size, its sans font, tight lines. */\nconst LABEL_TEXT = \"text-xs leading-tight font-[family-name:var(--ds-font-sans)]\";\n\n/** The label's line height and font size as the page draws them, read from a hidden sample after each render (a theme change re-renders the chart). */\nfunction useLabelMetrics(): [React.RefObject<HTMLSpanElement | null>, LabelMetrics | null] {\n const probe = useRef<HTMLSpanElement | null>(null);\n const [metrics, setMetrics] = useState<LabelMetrics | null>(null);\n // after every render: a theme's type can change with no prop of the chart's changing; the equality check below ends\n // the chain once the reading holds\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(() => {\n const el = probe.current;\n if (!el) return;\n const cs = getComputedStyle(el);\n const fontSize = parseFloat(cs.fontSize);\n const lineHeight = parseFloat(cs.lineHeight) || el.getBoundingClientRect().height;\n if (!(fontSize > 0) || !(lineHeight > 0)) return;\n if (!metrics || metrics.fontSize !== fontSize || metrics.lineHeight !== lineHeight) setMetrics({ fontSize, lineHeight });\n });\n return [probe, metrics];\n}\n\nexport const TreemapChart = markChart(forwardRef<HTMLDivElement, TreemapChartProps>(function TreemapChart({\n data,\n height = \"auto\",\n showTooltip = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(6, false);\n const isAnimated = useChartAnimation(animated);\n const radius = useRadius();\n const [probe, metrics] = useLabelMetrics();\n\n const chartData = addFillToNodes(data, colors);\n\n if (!data?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"ratio\" }} chart=\"treemap\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <Treemap\n data={chartData}\n dataKey=\"value\"\n nameKey=\"name\"\n aspectRatio={4 / 3}\n stroke=\"var(--ds-bg-surface)\"\n isAnimationActive={isAnimated}\n content={<TreemapContent colors={colors} radius={radius} metrics={metrics} />}\n >\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </Treemap>\n </ResponsiveContainer>\n <span ref={probe} aria-hidden className={LABEL_TEXT} style={{ position: \"absolute\", visibility: \"hidden\", pointerEvents: \"none\" }}>M</span>\n </ChartWrapper>\n );\n}));\n","import { forwardRef } from \"react\";\nimport {\n Sankey as RechartsSankey,\n Tooltip,\n ResponsiveContainer,\n} from \"recharts\";\nimport { useChartColors, useResolvedToken } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { ChartWrapper, markChart } from \"./ChartWrapper\";\n\nexport interface SankeyChartProps {\n data: {\n nodes: { name: string }[];\n links: { source: number; target: number; value: number }[];\n };\n /** \"auto\" (the default): two wide to one high. A preset or a number overrides it; a ChartContainer's own height wins. */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n showTooltip?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const SankeyChart = markChart(forwardRef<HTMLDivElement, SankeyChartProps>(function SankeyChart({\n data,\n height = \"auto\",\n showTooltip = true,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const colors = useChartColors(data.nodes.length, false);\n const linkStroke = useResolvedToken(\"--ds-border-subtle\");\n\n const nodesWithColor = data.nodes.map((node, i) => ({\n ...node,\n fill: colors[i % colors.length],\n }));\n\n const sankeyData = {\n nodes: nodesWithColor,\n links: data.links,\n };\n\n if (!data?.nodes?.length) return null;\n\n return (\n <ChartWrapper ref={ref} height={height} size={{ model: \"ratio\" }} chart=\"sankey\" className={className} aria-label={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsSankey\n data={sankeyData}\n nodeWidth={10}\n nodePadding={24}\n margin={{ top: 8, right: 8, bottom: 8, left: 8 }}\n link={{ stroke: linkStroke, strokeOpacity: 0.4 }}\n >\n {showTooltip && <Tooltip content={<ChartTooltipContent />} />}\n </RechartsSankey>\n </ResponsiveContainer>\n </ChartWrapper>\n );\n}));\n","import { forwardRef, useId } from \"react\";\nimport {\n LineChart,\n Line,\n AreaChart,\n Area,\n BarChart,\n Bar,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { useResolvedToken, useChartAnimation } from \"../../lib/chart-utils\";\nimport { ChartTooltipContent } from \"./ChartPrimitives\";\nimport { useInsideChartContainer } from \"./ChartWrapper\";\n\nexport interface SparklineProps {\n data: number[];\n variant?: \"line\" | \"area\" | \"bar\";\n color?: 1 | 2 | 3 | 4 | 5 | 6;\n height?: number;\n width?: number | \"100%\";\n showTooltip?: boolean;\n curved?: boolean;\n animated?: boolean;\n \"aria-label\"?: string;\n className?: string;\n}\n\nexport const Sparkline = forwardRef<HTMLDivElement, SparklineProps>(function Sparkline({\n data,\n variant = \"line\",\n color = 1,\n height = 40,\n width = \"100%\",\n showTooltip = false,\n curved = true,\n animated,\n \"aria-label\": ariaLabel,\n className,\n}, ref) {\n const instanceId = useId();\n const isAnimated = useChartAnimation(animated);\n const insideContainer = useInsideChartContainer();\n\n const tokenName = `--ds-chart-${color}` as const;\n const softTokenName = `--ds-chart-${color}-soft` as const;\n const chartColor = useResolvedToken(tokenName);\n const softColor = useResolvedToken(softTokenName);\n const chartData = data.map((value, i) => ({ value, index: i }));\n\n const containerStyle = insideContainer\n ? { width: \"100%\", height: \"100%\" }\n : { width: typeof width === \"number\" ? `${width}px` : width, height: `${height}px` };\n\n if (!data?.length) return null;\n\n if (variant === \"bar\") {\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={chartData} margin={{ top: 0, right: 0, bottom: 0, left: 0 }}>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Bar\n dataKey=\"value\"\n fill={chartColor}\n radius={[2, 2, 0, 0]}\n isAnimationActive={isAnimated}\n />\n </BarChart>\n </ResponsiveContainer>\n </div>\n );\n }\n\n if (variant === \"area\") {\n const gradientId = `sparkline-gradient-${instanceId}-${color}`;\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={chartData} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={softColor} stopOpacity={1} />\n <stop offset=\"95%\" stopColor={softColor} stopOpacity={0.1} />\n </linearGradient>\n </defs>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide domain={[\"dataMin - 1\", \"dataMax + 1\"]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Area\n type={curved ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke={chartColor}\n strokeWidth={1.5}\n fill={`url(#${gradientId})`}\n dot={false}\n activeDot={showTooltip ? { r: 3, fill: chartColor } : false}\n isAnimationActive={isAnimated}\n />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n );\n }\n\n return (\n <div ref={ref} style={containerStyle} className={className} {...(ariaLabel ? { role: \"img\", \"aria-label\": ariaLabel } : {})}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={chartData} margin={{ top: 2, right: 2, bottom: 2, left: 2 }}>\n <XAxis dataKey=\"index\" hide />\n <YAxis hide domain={[\"dataMin - 1\", \"dataMax + 1\"]} />\n {showTooltip && <Tooltip content={<ChartTooltipContent />} cursor={false} />}\n <Line\n type={curved ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke={chartColor}\n strokeWidth={1.5}\n dot={false}\n activeDot={showTooltip ? { r: 3, fill: chartColor } : false}\n isAnimationActive={isAnimated}\n />\n </LineChart>\n </ResponsiveContainer>\n </div>\n );\n});\n","import { useId, useMemo, type ReactNode } from \"react\";\nimport { cn, GLASS_SURFACE } from \"../lib/utils\";\nimport { TITLE_TEXT } from \"../lib/title-text\";\nimport { Skeleton } from \"./Skeleton\";\nimport { CHART_HEIGHTS, ChartContainerContext, fixedChartHeight, isLibraryChart, type ChartContainerValue } from \"./charts/ChartWrapper\";\n\n/**\n * CardTitle's classes (Card.tsx) without its line clamp: a chart's title states its insight, its message\n * (data_visualisation#3), so it is never cut. Kept equal to CardTitle's by a test.\n */\nexport const CHART_TITLE_CLASSES = TITLE_TEXT;\n\nexport interface ChartContainerProps {\n /**\n * \"auto\" (the default): the chart sizes itself from its type and its data (Sprint 25.9, A2) — a row per item for\n * sideways bars and funnels, two wide to one high for charts over dates or numbers, square for round charts — and in\n * a row its frame matches the tallest block while the chart grows only to its bound.\n * A preset (sm, md, lg) or a number of px sets this chart's height instead, and beats the chart's own.\n */\n height?: \"auto\" | \"sm\" | \"md\" | \"lg\" | number;\n /** The insight, as a heading (h3) in the card-title style, never cut. The chart's graphic is named by it. */\n title?: string;\n loading?: boolean;\n emptyState?: ReactNode;\n /** \"default\" is a card surface. \"ghost\" drops surface, border, shadow and padding for charts embedded in another container. */\n variant?: \"default\" | \"ghost\";\n children: ReactNode;\n className?: string;\n}\n\nexport function ChartContainer({\n height = \"auto\",\n title,\n loading = false,\n emptyState,\n variant = \"default\",\n children,\n className,\n}: ChartContainerProps) {\n const titleId = useId();\n const fixed = fixedChartHeight(height);\n // A library chart sizes itself (its mark). Anything else — a hand-built chart, an EmptyState, a Sparkline, several\n // children — keeps an area of the preset's height, else md, and fills it.\n const sizesItself = !loading && !!children && isLibraryChart(children);\n const area = fixed ?? CHART_HEIGHTS.md;\n const context = useMemo<ChartContainerValue>(\n () => ({ height: fixed, titleId: title ? titleId : undefined, fillArea: !sizesItself }),\n [fixed, title, titleId, sizesItself],\n );\n\n let body: ReactNode = null;\n if (loading) {\n body = (\n <div className=\"absolute inset-0 flex flex-col justify-end gap-ds-2 px-ds-2\">\n <div className=\"flex items-end h-full gap-ds-1\">\n {[65, 40, 80, 55, 72, 45, 60].map((h, i) => (\n <Skeleton key={i} variant=\"custom\" className=\"flex-1\" height={`${h}%`} />\n ))}\n </div>\n <Skeleton variant=\"text\" lines={1} className=\"w-full\" />\n </div>\n );\n } else if (children) {\n body = (\n <ChartContainerContext.Provider value={context}>\n {sizesItself ? children : (\n // the area is absolute, so a child that fills 100% has a definite height to fill\n <div className=\"absolute inset-0\">\n <div className=\"h-full w-full\">{children}</div>\n </div>\n )}\n </ChartContainerContext.Provider>\n );\n } else if (emptyState) {\n body = <div className=\"flex flex-1 items-center justify-center\">{emptyState}</div>;\n }\n\n return (\n <div\n data-card=\"\"\n data-gs=\"chart\"\n className={cn(\n \"flex flex-col\",\n variant === \"ghost\"\n ? \"bg-transparent\"\n : cn(\n // CardHeader's inset, so titles inside frames line up in a row (A1)\n \"rounded-[var(--ds-radius-md)] px-ds-5 py-ds-4\",\n \"bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\",\n GLASS_SURFACE,\n ),\n className,\n )}\n >\n {title && (\n <h3 id={titleId} className={cn(CHART_TITLE_CLASSES, \"mb-ds-4\")}>\n {title}\n </h3>\n )}\n <div\n data-chart-body=\"\"\n className=\"relative flex min-w-0 flex-col\"\n style={{ flex: \"1 1 0%\", minHeight: sizesItself ? undefined : area }}\n >\n {body}\n </div>\n </div>\n );\n}\n"]}
|