@chartgpu/chartgpu 0.2.5
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/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/ChartGPU.d.ts +146 -0
- package/dist/ChartGPU.d.ts.map +1 -0
- package/dist/components/createAnnotationConfigDialog.d.ts +24 -0
- package/dist/components/createAnnotationConfigDialog.d.ts.map +1 -0
- package/dist/components/createDataZoomSlider.d.ts +14 -0
- package/dist/components/createDataZoomSlider.d.ts.map +1 -0
- package/dist/components/createLegend.d.ts +9 -0
- package/dist/components/createLegend.d.ts.map +1 -0
- package/dist/components/createTextOverlay.d.ts +17 -0
- package/dist/components/createTextOverlay.d.ts.map +1 -0
- package/dist/components/createTooltip.d.ts +12 -0
- package/dist/components/createTooltip.d.ts.map +1 -0
- package/dist/components/formatTooltip.d.ts +19 -0
- package/dist/components/formatTooltip.d.ts.map +1 -0
- package/dist/config/OptionResolver.d.ts +137 -0
- package/dist/config/OptionResolver.d.ts.map +1 -0
- package/dist/config/defaults.d.ts +56 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/types.d.ts +553 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/core/GPUContext.d.ts +242 -0
- package/dist/core/GPUContext.d.ts.map +1 -0
- package/dist/core/RenderScheduler.d.ts +174 -0
- package/dist/core/RenderScheduler.d.ts.map +1 -0
- package/dist/core/createAnimationController.d.ts +15 -0
- package/dist/core/createAnimationController.d.ts.map +1 -0
- package/dist/core/createRenderCoordinator.d.ts +78 -0
- package/dist/core/createRenderCoordinator.d.ts.map +1 -0
- package/dist/core/renderCoordinator/animation/animationHelpers.d.ts +183 -0
- package/dist/core/renderCoordinator/animation/animationHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/annotations/processAnnotations.d.ts +88 -0
- package/dist/core/renderCoordinator/annotations/processAnnotations.d.ts.map +1 -0
- package/dist/core/renderCoordinator/axis/axisLabelHelpers.d.ts +91 -0
- package/dist/core/renderCoordinator/axis/axisLabelHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/axis/computeAxisTicks.d.ts +53 -0
- package/dist/core/renderCoordinator/axis/computeAxisTicks.d.ts.map +1 -0
- package/dist/core/renderCoordinator/data/computeVisibleSlice.d.ts +66 -0
- package/dist/core/renderCoordinator/data/computeVisibleSlice.d.ts.map +1 -0
- package/dist/core/renderCoordinator/gpu/textureManager.d.ts +69 -0
- package/dist/core/renderCoordinator/gpu/textureManager.d.ts.map +1 -0
- package/dist/core/renderCoordinator/interaction/interactionHelpers.d.ts +160 -0
- package/dist/core/renderCoordinator/interaction/interactionHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderAnnotationLabels.d.ts +36 -0
- package/dist/core/renderCoordinator/render/renderAnnotationLabels.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderAxisLabels.d.ts +40 -0
- package/dist/core/renderCoordinator/render/renderAxisLabels.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderOverlays.d.ts +70 -0
- package/dist/core/renderCoordinator/render/renderOverlays.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderSeries.d.ts +146 -0
- package/dist/core/renderCoordinator/render/renderSeries.d.ts.map +1 -0
- package/dist/core/renderCoordinator/renderers/rendererPool.d.ts +112 -0
- package/dist/core/renderCoordinator/renderers/rendererPool.d.ts.map +1 -0
- package/dist/core/renderCoordinator/types.d.ts +19 -0
- package/dist/core/renderCoordinator/types.d.ts.map +1 -0
- package/dist/core/renderCoordinator/ui/tooltipLegendHelpers.d.ts +104 -0
- package/dist/core/renderCoordinator/ui/tooltipLegendHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/axisUtils.d.ts +122 -0
- package/dist/core/renderCoordinator/utils/axisUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/boundsComputation.d.ts +69 -0
- package/dist/core/renderCoordinator/utils/boundsComputation.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/canvasUtils.d.ts +52 -0
- package/dist/core/renderCoordinator/utils/canvasUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/dataPointUtils.d.ts +71 -0
- package/dist/core/renderCoordinator/utils/dataPointUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/index.d.ts +12 -0
- package/dist/core/renderCoordinator/utils/index.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/timeAxisUtils.d.ts +149 -0
- package/dist/core/renderCoordinator/utils/timeAxisUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/zoom/zoomHelpers.d.ts +129 -0
- package/dist/core/renderCoordinator/zoom/zoomHelpers.d.ts.map +1 -0
- package/dist/data/cartesianData.d.ts +72 -0
- package/dist/data/cartesianData.d.ts.map +1 -0
- package/dist/data/createDataStore.d.ts +27 -0
- package/dist/data/createDataStore.d.ts.map +1 -0
- package/dist/data/createStreamBuffer.d.ts +20 -0
- package/dist/data/createStreamBuffer.d.ts.map +1 -0
- package/dist/data/lttbSample.d.ts +5 -0
- package/dist/data/lttbSample.d.ts.map +1 -0
- package/dist/data/ohlcSample.d.ts +21 -0
- package/dist/data/ohlcSample.d.ts.map +1 -0
- package/dist/data/packDataPoints.d.ts +65 -0
- package/dist/data/packDataPoints.d.ts.map +1 -0
- package/dist/data/sampleSeries.d.ts +20 -0
- package/dist/data/sampleSeries.d.ts.map +1 -0
- package/dist/esm/ChartGPUWorkerController-B50J-8sx.js +772 -0
- package/dist/esm/ChartGPUWorkerController-B50J-8sx.js.map +1 -0
- package/dist/esm/OptionResolver-R_gJDRSD.js +7150 -0
- package/dist/esm/OptionResolver-R_gJDRSD.js.map +1 -0
- package/dist/esm/assets/worker-entry-Wg897auv.js +779 -0
- package/dist/esm/assets/worker-entry-Wg897auv.js.map +1 -0
- package/dist/esm/createChartInWorker-C4fEeJL8.js +1224 -0
- package/dist/esm/createChartInWorker-C4fEeJL8.js.map +1 -0
- package/dist/esm/index.js +795 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.cjs +1270 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10504 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction/createAnnotationAuthoring.d.ts +115 -0
- package/dist/interaction/createAnnotationAuthoring.d.ts.map +1 -0
- package/dist/interaction/createAnnotationDragHandler.d.ts +28 -0
- package/dist/interaction/createAnnotationDragHandler.d.ts.map +1 -0
- package/dist/interaction/createAnnotationHitTester.d.ts +32 -0
- package/dist/interaction/createAnnotationHitTester.d.ts.map +1 -0
- package/dist/interaction/createChartSync.d.ts +27 -0
- package/dist/interaction/createChartSync.d.ts.map +1 -0
- package/dist/interaction/createEventManager.d.ts +24 -0
- package/dist/interaction/createEventManager.d.ts.map +1 -0
- package/dist/interaction/createHoverState.d.ts +20 -0
- package/dist/interaction/createHoverState.d.ts.map +1 -0
- package/dist/interaction/createInsideZoom.d.ts +14 -0
- package/dist/interaction/createInsideZoom.d.ts.map +1 -0
- package/dist/interaction/createZoomState.d.ts +63 -0
- package/dist/interaction/createZoomState.d.ts.map +1 -0
- package/dist/interaction/findCandlestick.d.ts +41 -0
- package/dist/interaction/findCandlestick.d.ts.map +1 -0
- package/dist/interaction/findNearestPoint.d.ts +61 -0
- package/dist/interaction/findNearestPoint.d.ts.map +1 -0
- package/dist/interaction/findPieSlice.d.ts +36 -0
- package/dist/interaction/findPieSlice.d.ts.map +1 -0
- package/dist/interaction/findPointsAtX.d.ts +37 -0
- package/dist/interaction/findPointsAtX.d.ts.map +1 -0
- package/dist/renderers/createAnnotationMarkerRenderer.d.ts +58 -0
- package/dist/renderers/createAnnotationMarkerRenderer.d.ts.map +1 -0
- package/dist/renderers/createAreaRenderer.d.ts +19 -0
- package/dist/renderers/createAreaRenderer.d.ts.map +1 -0
- package/dist/renderers/createAxisRenderer.d.ts +19 -0
- package/dist/renderers/createAxisRenderer.d.ts.map +1 -0
- package/dist/renderers/createBarRenderer.d.ts +20 -0
- package/dist/renderers/createBarRenderer.d.ts.map +1 -0
- package/dist/renderers/createCandlestickRenderer.d.ts +19 -0
- package/dist/renderers/createCandlestickRenderer.d.ts.map +1 -0
- package/dist/renderers/createCrosshairRenderer.d.ts +43 -0
- package/dist/renderers/createCrosshairRenderer.d.ts.map +1 -0
- package/dist/renderers/createGridRenderer.d.ts +45 -0
- package/dist/renderers/createGridRenderer.d.ts.map +1 -0
- package/dist/renderers/createHighlightRenderer.d.ts +41 -0
- package/dist/renderers/createHighlightRenderer.d.ts.map +1 -0
- package/dist/renderers/createLineRenderer.d.ts +18 -0
- package/dist/renderers/createLineRenderer.d.ts.map +1 -0
- package/dist/renderers/createPieRenderer.d.ts +18 -0
- package/dist/renderers/createPieRenderer.d.ts.map +1 -0
- package/dist/renderers/createReferenceLineRenderer.d.ts +81 -0
- package/dist/renderers/createReferenceLineRenderer.d.ts.map +1 -0
- package/dist/renderers/createScatterDensityRenderer.d.ts +14 -0
- package/dist/renderers/createScatterDensityRenderer.d.ts.map +1 -0
- package/dist/renderers/createScatterRenderer.d.ts +20 -0
- package/dist/renderers/createScatterRenderer.d.ts.map +1 -0
- package/dist/renderers/rendererUtils.d.ts +100 -0
- package/dist/renderers/rendererUtils.d.ts.map +1 -0
- package/dist/themes/darkTheme.d.ts +11 -0
- package/dist/themes/darkTheme.d.ts.map +1 -0
- package/dist/themes/index.d.ts +8 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/lightTheme.d.ts +11 -0
- package/dist/themes/lightTheme.d.ts.map +1 -0
- package/dist/themes/types.d.ts +14 -0
- package/dist/themes/types.d.ts.map +1 -0
- package/dist/types/ChartGPU.d.ts +99 -0
- package/dist/types/ChartGPU.d.ts.map +1 -0
- package/dist/types/components/createDataZoomSlider.d.ts +14 -0
- package/dist/types/components/createDataZoomSlider.d.ts.map +1 -0
- package/dist/types/components/createLegend.d.ts +9 -0
- package/dist/types/components/createLegend.d.ts.map +1 -0
- package/dist/types/components/createTextOverlay.d.ts +17 -0
- package/dist/types/components/createTextOverlay.d.ts.map +1 -0
- package/dist/types/components/createTooltip.d.ts +12 -0
- package/dist/types/components/createTooltip.d.ts.map +1 -0
- package/dist/types/components/formatTooltip.d.ts +19 -0
- package/dist/types/components/formatTooltip.d.ts.map +1 -0
- package/dist/types/config/OptionResolver.d.ts +134 -0
- package/dist/types/config/OptionResolver.d.ts.map +1 -0
- package/dist/types/config/defaults.d.ts +55 -0
- package/dist/types/config/defaults.d.ts.map +1 -0
- package/dist/types/config/types.d.ts +485 -0
- package/dist/types/config/types.d.ts.map +1 -0
- package/dist/types/core/GPUContext.d.ts +242 -0
- package/dist/types/core/GPUContext.d.ts.map +1 -0
- package/dist/types/core/RenderScheduler.d.ts +174 -0
- package/dist/types/core/RenderScheduler.d.ts.map +1 -0
- package/dist/types/core/createAnimationController.d.ts +15 -0
- package/dist/types/core/createAnimationController.d.ts.map +1 -0
- package/dist/types/core/createRenderCoordinator.d.ts +129 -0
- package/dist/types/core/createRenderCoordinator.d.ts.map +1 -0
- package/dist/types/data/createDataStore.d.ts +33 -0
- package/dist/types/data/createDataStore.d.ts.map +1 -0
- package/dist/types/data/createStreamBuffer.d.ts +20 -0
- package/dist/types/data/createStreamBuffer.d.ts.map +1 -0
- package/dist/types/data/lttbSample.d.ts +5 -0
- package/dist/types/data/lttbSample.d.ts.map +1 -0
- package/dist/types/data/ohlcSample.d.ts +21 -0
- package/dist/types/data/ohlcSample.d.ts.map +1 -0
- package/dist/types/data/packDataPoints.d.ts +79 -0
- package/dist/types/data/packDataPoints.d.ts.map +1 -0
- package/dist/types/data/sampleSeries.d.ts +3 -0
- package/dist/types/data/sampleSeries.d.ts.map +1 -0
- package/dist/types/index.d.ts +35 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interaction/createChartSync.d.ts +12 -0
- package/dist/types/interaction/createChartSync.d.ts.map +1 -0
- package/dist/types/interaction/createEventManager.d.ts +24 -0
- package/dist/types/interaction/createEventManager.d.ts.map +1 -0
- package/dist/types/interaction/createHoverState.d.ts +20 -0
- package/dist/types/interaction/createHoverState.d.ts.map +1 -0
- package/dist/types/interaction/createInsideZoom.d.ts +14 -0
- package/dist/types/interaction/createInsideZoom.d.ts.map +1 -0
- package/dist/types/interaction/createZoomState.d.ts +63 -0
- package/dist/types/interaction/createZoomState.d.ts.map +1 -0
- package/dist/types/interaction/findCandlestick.d.ts +41 -0
- package/dist/types/interaction/findCandlestick.d.ts.map +1 -0
- package/dist/types/interaction/findNearestPoint.d.ts +61 -0
- package/dist/types/interaction/findNearestPoint.d.ts.map +1 -0
- package/dist/types/interaction/findPieSlice.d.ts +36 -0
- package/dist/types/interaction/findPieSlice.d.ts.map +1 -0
- package/dist/types/interaction/findPointsAtX.d.ts +37 -0
- package/dist/types/interaction/findPointsAtX.d.ts.map +1 -0
- package/dist/types/renderers/createAreaRenderer.d.ts +18 -0
- package/dist/types/renderers/createAreaRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createAxisRenderer.d.ts +19 -0
- package/dist/types/renderers/createAxisRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createBarRenderer.d.ts +20 -0
- package/dist/types/renderers/createBarRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createCandlestickRenderer.d.ts +19 -0
- package/dist/types/renderers/createCandlestickRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createCrosshairRenderer.d.ts +43 -0
- package/dist/types/renderers/createCrosshairRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createGridRenderer.d.ts +45 -0
- package/dist/types/renderers/createGridRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createHighlightRenderer.d.ts +41 -0
- package/dist/types/renderers/createHighlightRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createLineRenderer.d.ts +18 -0
- package/dist/types/renderers/createLineRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createPieRenderer.d.ts +18 -0
- package/dist/types/renderers/createPieRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createScatterDensityRenderer.d.ts +14 -0
- package/dist/types/renderers/createScatterDensityRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createScatterRenderer.d.ts +19 -0
- package/dist/types/renderers/createScatterRenderer.d.ts.map +1 -0
- package/dist/types/renderers/rendererUtils.d.ts +100 -0
- package/dist/types/renderers/rendererUtils.d.ts.map +1 -0
- package/dist/types/themes/darkTheme.d.ts +11 -0
- package/dist/types/themes/darkTheme.d.ts.map +1 -0
- package/dist/types/themes/index.d.ts +8 -0
- package/dist/types/themes/index.d.ts.map +1 -0
- package/dist/types/themes/lightTheme.d.ts +11 -0
- package/dist/types/themes/lightTheme.d.ts.map +1 -0
- package/dist/types/themes/types.d.ts +14 -0
- package/dist/types/themes/types.d.ts.map +1 -0
- package/dist/types/utils/axisLabelStyling.d.ts +27 -0
- package/dist/types/utils/axisLabelStyling.d.ts.map +1 -0
- package/dist/types/utils/checkWebGPU.d.ts +39 -0
- package/dist/types/utils/checkWebGPU.d.ts.map +1 -0
- package/dist/types/utils/colors.d.ts +14 -0
- package/dist/types/utils/colors.d.ts.map +1 -0
- package/dist/types/utils/easing.d.ts +9 -0
- package/dist/types/utils/easing.d.ts.map +1 -0
- package/dist/types/utils/scales.d.ts +79 -0
- package/dist/types/utils/scales.d.ts.map +1 -0
- package/dist/utils/axisLabelStyling.d.ts +20 -0
- package/dist/utils/axisLabelStyling.d.ts.map +1 -0
- package/dist/utils/checkWebGPU.d.ts +39 -0
- package/dist/utils/checkWebGPU.d.ts.map +1 -0
- package/dist/utils/colors.d.ts +14 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/easing.d.ts +9 -0
- package/dist/utils/easing.d.ts.map +1 -0
- package/dist/utils/scales.d.ts +79 -0
- package/dist/utils/scales.d.ts.map +1 -0
- package/package.json +64 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1270 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function Ea(e){return typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement}function Da(e){const t=e.clientWidth||e.width||0,n=e.clientHeight||e.height||0;if(!Number.isFinite(t)||!Number.isFinite(n))throw new Error(`GPUContext: Invalid canvas dimensions detected: width=${e.clientWidth||e.width}, height=${e.clientHeight||e.height}. Canvas must have finite dimensions. Ensure canvas is properly sized before initialization.`);return{width:t,height:n}}function eo(e,t){const n=(t==null?void 0:t.devicePixelRatio)??(typeof window<"u"?window.devicePixelRatio:1),i=Number.isFinite(n)&&n>0?n:1,r=(t==null?void 0:t.alphaMode)??"opaque",o=(t==null?void 0:t.powerPreference)??"high-performance";return{adapter:null,device:null,initialized:!1,canvas:e||null,canvasContext:null,preferredFormat:null,devicePixelRatio:i,alphaMode:r,powerPreference:o}}async function to(e){var i,r;if(e.initialized)throw new Error("GPUContext is already initialized. Call destroyGPUContext() before reinitializing.");const t=Number.isFinite(e.devicePixelRatio)&&e.devicePixelRatio>0?e.devicePixelRatio:1;if(!navigator.gpu)throw new Error("WebGPU is not available in this browser. Please use a browser that supports WebGPU (Chrome 113+, Edge 113+, or Safari 18+). Ensure WebGPU is enabled in browser flags if needed.");let n=null;try{const o=await navigator.gpu.requestAdapter({powerPreference:e.powerPreference});if(!o)throw new Error("Failed to request WebGPU adapter. No compatible adapter found. This may occur if no GPU is available or WebGPU is disabled.");if(n=await o.requestDevice(),!n)throw new Error("Failed to request WebGPU device from adapter.");n.addEventListener("uncapturederror",c=>{console.error("WebGPU uncaptured error:",c.error)});let s=null,a=null;if(e.canvas){const c=e.canvas.getContext("webgpu");if(!c){try{n.destroy()}catch(S){console.warn("Error destroying device during canvas setup failure:",S)}throw new Error("Failed to get WebGPU context from canvas.")}const{width:u,height:p}=Da(e.canvas),h=t,l=Math.floor(u*h),m=Math.floor(p*h),C=n.limits.maxTextureDimension2D,F=Math.max(1,Math.min(l,C)),R=Math.max(1,Math.min(m,C));e.canvas.width=F,e.canvas.height=R,a=((r=(i=navigator.gpu).getPreferredCanvasFormat)==null?void 0:r.call(i))||"bgra8unorm",c.configure({device:n,format:a,alphaMode:e.alphaMode}),s=c}return{adapter:o,device:n,initialized:!0,canvas:e.canvas,canvasContext:s,preferredFormat:a,devicePixelRatio:t,alphaMode:e.alphaMode,powerPreference:e.powerPreference}}catch(o){if(n)try{n.destroy()}catch(s){console.warn("Error destroying device during initialization failure:",s)}throw o instanceof Error?o:new Error(`Failed to initialize GPUContext: ${String(o)}`)}}function no(e){if(!e.canvas)throw new Error("Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.canvasContext)throw new Error("GPUContext is not initialized. Call initializeGPUContext() first.");return e.canvasContext.getCurrentTexture()}function qs(e,t,n,i,r){if(t<0||t>1||n<0||n>1||i<0||i>1||r<0||r>1)throw new Error("Color components must be in the range [0.0, 1.0]");if(!e.canvas)throw new Error("Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.device||!e.canvasContext)throw new Error("GPUContext is not initialized. Call initializeGPUContext() first.");const o=no(e),s=e.device.createCommandEncoder();s.beginRenderPass({colorAttachments:[{view:o.createView(),clearValue:{r:t,g:n,b:i,a:r},loadOp:"clear",storeOp:"store"}]}).end(),e.device.queue.submit([s.finish()])}function Zs(e){if(e.device)try{e.device.destroy()}catch(t){console.warn("Error destroying GPU device:",t)}return{adapter:null,device:null,initialized:!1,canvas:e.canvas,canvasContext:null,preferredFormat:null,devicePixelRatio:e.devicePixelRatio,alphaMode:e.alphaMode,powerPreference:e.powerPreference}}async function Ba(e,t){const n=eo(e,t);return to(n)}class nr{get adapter(){return this._state.adapter}get device(){return this._state.device}get initialized(){return this._state.initialized}get canvas(){return this._state.canvas}get canvasContext(){return this._state.canvasContext}get preferredFormat(){return this._state.preferredFormat}get devicePixelRatio(){return this._state.devicePixelRatio}get alphaMode(){return this._state.alphaMode}get powerPreference(){return this._state.powerPreference}constructor(t,n){this._state=eo(t,n)}async initialize(){this._state=await to(this._state)}static async create(t,n){const i=new nr(t,n);return await i.initialize(),i}getCanvasTexture(){return no(this._state)}clearScreen(t,n,i,r){qs(this._state,t,n,i,r)}destroy(){this._state=Zs(this._state)}}function Po(e){return Array.isArray(e)}function hr(e){if(!e)throw new TypeError("packDataPoints: points parameter is required");if(!Array.isArray(e))throw new TypeError("packDataPoints: points must be an array");if(e.length===0)return new Float32Array(0);const t=268435456;if(e.length>t)throw new RangeError(`packDataPoints: points array too large (${e.length} points). Maximum supported: ${t.toLocaleString()} points (2GB buffer limit)`);const n=new ArrayBuffer(e.length*2*4),i=new Float32Array(n);for(let r=0;r<e.length;r++){const o=e[r];if(o==null)throw new TypeError(`packDataPoints: Invalid point at index ${r}. Expected DataPoint (tuple or object), got ${o}`);const s=Po(o)?o[0]:o.x,a=Po(o)?o[1]:o.y;if(typeof s!="number"||typeof a!="number")throw new TypeError(`packDataPoints: Invalid coordinate values at index ${r}. Expected numbers, got x=${typeof s}, y=${typeof a}`);i[r*2+0]=s,i[r*2+1]=a}return i}const Yi=4;function $r(e){return e+3&-4}function La(e){if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))}function Ao(e,t){const n=Math.max(Yi,$r(t)),i=Math.max(Yi,La(n));return Math.max(e,i)}function js(e,t){let n=e>>>0;for(let i=0;i<t.length;i++)n^=t[i],n=Math.imul(n,16777619)>>>0;return n>>>0}function Ro(e){const t=new Uint32Array(e.buffer,e.byteOffset,e.byteLength/4);return js(2166136261,t)}function ka(e){const t=new Map;let n=!1;const i=C=>Array.isArray(C),r=(C,F)=>{if(!C||C.length===0)return new Float32Array(0);const R=new ArrayBuffer(C.length*2*4),S=new Float32Array(R);for(let y=0;y<C.length;y++){const b=C[y],w=i(b)?b[0]:b.x,d=i(b)?b[1]:b.y;S[y*2+0]=w-F,S[y*2+1]=d}return S},o=()=>{if(n)throw new Error("DataStore is disposed.")},s=C=>{o();const F=t.get(C);if(!F)throw new Error(`Series ${C} has no data. Call setSeries(${C}, data) first.`);return F};return{setSeries:(C,F,R)=>{o();const S=(R==null?void 0:R.xOffset)??0,y=S===0?hr(F):r(F,S),b=F.length,w=Ro(y),d=$r(y.byteLength),g=Math.max(Yi,d),v=t.get(C);if(v&&v.pointCount===b&&v.hash32===w)return;let I=(v==null?void 0:v.buffer)??null,T=(v==null?void 0:v.capacityBytes)??0;if(!I||g>T){const E=e.limits.maxBufferSize;if(g>E)throw new Error(`DataStore.setSeries(${C}): required buffer size ${g} exceeds device.limits.maxBufferSize (${E}).`);if(I)try{I.destroy()}catch{}const f=Ao(T,g);f>E?T=g:T=f,I=e.createBuffer({size:T,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})}y.byteLength>0&&e.queue.writeBuffer(I,0,y.buffer),t.set(C,{buffer:I,capacityBytes:T,pointCount:b,hash32:w,xOffset:S,data:F.length===0?[]:F.slice()})},appendSeries:(C,F)=>{if(o(),!F||F.length===0)return;const R=s(C),S=R.pointCount,y=S+F.length,b=R.xOffset===0?hr(F):r(F,R.xOffset),w=b.byteLength,d=$r(y*2*4),g=Math.max(Yi,d);let v=R.buffer,M=R.capacityBytes;const I=R.data;I.push(...F);const T=e.limits.maxBufferSize;if(g>M){if(g>T)throw new Error(`DataStore.appendSeries(${C}): required buffer size ${g} exceeds device.limits.maxBufferSize (${T}).`);try{v.destroy()}catch{}const x=Ao(M,g);M=x>T?g:x,v=e.createBuffer({size:M,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});const N=R.xOffset===0?hr(I):r(I,R.xOffset);N.byteLength>0&&e.queue.writeBuffer(v,0,N.buffer),t.set(C,{buffer:v,capacityBytes:M,pointCount:y,hash32:Ro(N),xOffset:R.xOffset,data:I});return}if(w>0){const x=S*2*4;e.queue.writeBuffer(v,x,b.buffer)}const E=new Uint32Array(b.buffer,b.byteOffset,b.byteLength/4),f=js(R.hash32,E);t.set(C,{buffer:v,capacityBytes:M,pointCount:y,hash32:f,xOffset:R.xOffset,data:I})},removeSeries:C=>{o();const F=t.get(C);if(F){try{F.buffer.destroy()}catch{}t.delete(C)}},getSeriesBuffer:C=>s(C).buffer,getSeriesPointCount:C=>s(C).pointCount,getSeriesData:C=>s(C).data,dispose:()=>{if(!n){n=!0;for(const C of t.values())try{C.buffer.destroy()}catch{}t.clear()}}}}function fn(e){return Array.isArray(e)}function Ua(e,t){const n=e.length>>>1,i=n-1;if(t<=0||n===0)return new Int32Array(0);if(t===1)return new Int32Array([0]);if(t===2)return n>=2?new Int32Array([0,i]):new Int32Array([0]);if(n<=t){const p=new Int32Array(n);for(let h=0;h<n;h++)p[h]=h;return p}const r=new Int32Array(t);r[0]=0,r[t-1]=i;const o=(n-2)/(t-2);let s=0,a=1;const c=e[i*2+0],u=e[i*2+1];for(let p=0;p<t-2;p++){let h=Math.floor(o*p)+1,l=Math.min(Math.floor(o*(p+1))+1,i);h>=l&&(h=Math.min(h,i-1),l=Math.min(h+1,i));const m=Math.floor(o*(p+1))+1,C=Math.min(Math.floor(o*(p+2))+1,i);let F=c,R=u;if(m<C){let d=0,g=0,v=0;for(let M=m;M<C;M++)d+=e[M*2+0],g+=e[M*2+1],v++;v>0&&(F=d/v,R=g/v)}const S=e[s*2+0],y=e[s*2+1];let b=-1,w=h;for(let d=h;d<l;d++){const g=e[d*2+0],v=e[d*2+1],M=(S-F)*(v-y)-(S-g)*(R-y),I=M<0?-M:M;I>b&&(b=I,w=d)}r[a++]=w,s=w}return r}function _a(e,t){const n=e.length,i=n-1;if(t<=0||n===0)return new Int32Array(0);if(t===1)return new Int32Array([0]);if(t===2)return n>=2?new Int32Array([0,i]):new Int32Array([0]);if(n<=t){const h=new Int32Array(n);for(let l=0;l<n;l++)h[l]=l;return h}const r=new Int32Array(t);r[0]=0,r[t-1]=i;const o=(n-2)/(t-2);let s=0,a=1;const c=e[i],u=fn(c)?c[0]:c.x,p=fn(c)?c[1]:c.y;for(let h=0;h<t-2;h++){let l=Math.floor(o*h)+1,m=Math.min(Math.floor(o*(h+1))+1,i);l>=m&&(l=Math.min(l,i-1),m=Math.min(l+1,i));const C=Math.floor(o*(h+1))+1,F=Math.min(Math.floor(o*(h+2))+1,i);let R=u,S=p;if(C<F){let v=0,M=0,I=0;for(let T=C;T<F;T++){const E=e[T],f=fn(E)?E[0]:E.x,x=fn(E)?E[1]:E.y;v+=f,M+=x,I++}I>0&&(R=v/I,S=M/I)}const y=e[s],b=fn(y)?y[0]:y.x,w=fn(y)?y[1]:y.y;let d=-1,g=l;for(let v=l;v<m;v++){const M=e[v],I=fn(M)?M[0]:M.x,T=fn(M)?M[1]:M.y,E=(b-R)*(T-w)-(b-I)*(S-w),f=E<0?-E:E;f>d&&(d=f,g=v)}r[a++]=g,s=g}return r}function hi(e,t){const n=Math.floor(t);if(e instanceof Float32Array){const s=e.length>>>1;if(n<=0||s===0)return new Float32Array(0);if(s<=n)return e;const a=Ua(e,n),c=new Float32Array(a.length*2);for(let u=0;u<a.length;u++){const p=a[u];c[u*2+0]=e[p*2+0],c[u*2+1]=e[p*2+1]}return c}const i=e.length;if(n<=0||i===0)return[];if(i<=n)return e;const r=_a(e,n),o=new Array(r.length);for(let s=0;s<r.length;s++)o[s]=e[r[s]];return o}function ir(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&"x"in e&&"y"in e&&typeof e.x=="object"&&typeof e.y=="object"&&"length"in e.x&&"length"in e.y}function rr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function io(e){return Array.isArray(e)}function Xe(e){if(ir(e))return Math.min(e.x.length,e.y.length);if(rr(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return Math.floor(e.length/2)}return e.length}function Ee(e,t){if(ir(e))return e.x[t];if(rr(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return e[t*2]}const n=e[t];return io(n)?n[0]:n.x}function We(e,t){if(ir(e))return e.y[t];if(rr(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return e[t*2+1]}const n=e[t];return io(n)?n[1]:n.y}function mt(e,t){var i;if(ir(e))return(i=e.size)==null?void 0:i[t];if(rr(e))return;const n=e[t];return io(n)?n[2]:n.size}function sn(e){let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;const o=Xe(e);for(let s=0;s<o;s++){const a=Ee(e,s),c=We(e,s);!Number.isFinite(a)||!Number.isFinite(c)||(a<t&&(t=a),a>n&&(n=a),c<i&&(i=c),c>r&&(r=c))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?null:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})}function Ks(e){const t=Math.floor(e);return Number.isFinite(t)?t:0}function Ga(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&"x"in e&&"y"in e&&typeof e.x=="object"&&typeof e.y=="object"&&"length"in e.x&&"length"in e.y}function za(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function Eo(e){const t=Xe(e),n=new Float32Array(t*2);for(let i=0;i<t;i++)n[i*2]=Ee(e,i),n[i*2+1]=We(e,i);return n}function yr(e,t,n){const i=Xe(e),r=Ks(t);if(r<=0||i===0)return[];if(r===1){const c=Ee(e,0),u=We(e,0),p=mt(e,0);return p!==void 0?[[c,u,p]]:[[c,u]]}if(r===2)if(i>=2){const c=Ee(e,0),u=We(e,0),p=mt(e,0),h=Ee(e,i-1),l=We(e,i-1),m=mt(e,i-1);return[p!==void 0?[c,u,p]:[c,u],m!==void 0?[h,l,m]:[h,l]]}else{const c=Ee(e,0),u=We(e,0),p=mt(e,0);return p!==void 0?[[c,u,p]]:[[c,u]]}const o=i-1,s=new Array(r);{const c=Ee(e,0),u=We(e,0),p=mt(e,0);s[0]=p!==void 0?[c,u,p]:[c,u];const h=Ee(e,o),l=We(e,o),m=mt(e,o);s[r-1]=m!==void 0?[h,l,m]:[h,l]}const a=(i-2)/(r-2);for(let c=0;c<r-2;c++){let u=Math.floor(a*c)+1,p=Math.min(Math.floor(a*(c+1))+1,o);u>=p&&(u=Math.min(u,o-1),p=Math.min(u+1,o));let h=null;if(n==="average"){let l=0,m=0,C=0,F=0,R=0;for(let S=u;S<p;S++){const y=Ee(e,S),b=We(e,S);if(!Number.isFinite(y)||!Number.isFinite(b))continue;l+=y,m+=b,F++;const w=mt(e,S);typeof w=="number"&&Number.isFinite(w)&&(C+=w,R++)}if(F>0){const S=l/F,y=m/F;R>0?h=[S,y,C/R]:h=[S,y]}}else{let l=n==="max"?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,m=u;for(let S=u;S<p;S++){const y=We(e,S);Number.isFinite(y)&&(n==="max"?y>l&&(l=y,m=S):y<l&&(l=y,m=S))}const C=Ee(e,m),F=We(e,m),R=mt(e,m);h=R!==void 0?[C,F,R]:[C,F]}if(h===null){const l=Ee(e,u),m=We(e,u),C=mt(e,u);h=C!==void 0?[l,m,C]:[l,m]}s[c+1]=h}return s}function _n(e,t,n){const i=Ks(n),r=Xe(e);if(t==="none"||!(i>0)||r<=i)return e;switch(t){case"lttb":{if(e instanceof Float32Array)return hi(e,i);if(za(e)){const o=Eo(e);return hi(o,i)}if(Ga(e)){const o=Eo(e);return hi(o,i)}return hi(e,i)}case"average":return yr(e,i,"average");case"max":return yr(e,i,"max");case"min":return yr(e,i,"min");default:return e}}function Va(e){return Array.isArray(e)}function Wr(e,t){const n=Math.floor(t),i=e.length;if(n<2||i<=n)return e;const r=new Array(n);if(r[0]=e[0],r[n-1]=e[i-1],n===2)return r;const o=Va(e[0]),s=(i-2)/(n-2);if(o){const a=e;for(let c=0;c<n-2;c++){let u=Math.floor(s*c)+1,p=Math.min(Math.floor(s*(c+1))+1,i-1);u>=p&&(u=Math.min(u,i-2),p=Math.min(u+1,i-1));const h=a[u],l=a[p-1],m=h[0],C=h[1],F=l[2];let R=-1/0,S=1/0;for(let y=u;y<p;y++){const b=a[y],w=b[3],d=b[4];d>R&&(R=d),w<S&&(S=w)}r[c+1]=[m,C,F,S,R]}}else{const a=e;for(let c=0;c<n-2;c++){let u=Math.floor(s*c)+1,p=Math.min(Math.floor(s*(c+1))+1,i-1);u>=p&&(u=Math.min(u,i-2),p=Math.min(u+1,i-1));const h=a[u],l=a[p-1],m=h.timestamp,C=h.open,F=l.close;let R=-1/0,S=1/0;for(let y=u;y<p;y++){const b=a[y],w=b.high,d=b.low;w>R&&(R=w),d<S&&(S=d)}r[c+1]={timestamp:m,open:C,close:F,low:S,high:R}}}return r}function Oa(e){return e?e.clientWidth:0}function $a(e){return e?e.clientHeight:0}function pn(e,t,n){return Math.min(n,Math.max(t,e|0))}function Hi(e){return Array.isArray(e)}const yi=new WeakMap,gi=new WeakMap;function ro(e){const t=typeof e=="object"&&e!==null?e:null;if(t){const r=yi.get(t);if(r!==void 0)return r}let n=Number.NEGATIVE_INFINITY;const i=Xe(e);for(let r=0;r<i;r++){const o=Ee(e,r);if(!Number.isFinite(o)||o<n)return t&&yi.set(t,!1),!1;n=o}return t&&yi.set(t,!0),!0}function Wa(e){const t=gi.get(e);if(t!==void 0)return t;let n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=e[i],o=Hi(r)?r[0]:r.timestamp;if(!Number.isFinite(o)||o<n)return gi.set(e,!1),!1;n=o}return gi.set(e,!0),!0}function Js(e,t){let n=0,i=Xe(e);for(;n<i;){const r=n+i>>>1;Ee(e,r)<t?n=r+1:i=r}return n}function Qs(e,t){let n=0,i=Xe(e);for(;n<i;){const r=n+i>>>1;Ee(e,r)<=t?n=r+1:i=r}return n}function Xa(e,t){let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;e[r][0]<t?n=r+1:i=r}return n}function Ya(e,t){let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;e[r][0]<=t?n=r+1:i=r}return n}function Ha(e,t){let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;e[r].timestamp<t?n=r+1:i=r}return n}function qa(e,t){let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;e[r].timestamp<=t?n=r+1:i=r}return n}function Do(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&"x"in e&&"y"in e&&typeof e.x=="object"&&typeof e.y=="object"&&"length"in e.x&&"length"in e.y}function Bo(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function Za(e,t,n){const i=Xe(e),r=Math.max(0,Math.min(t,i)),o=Math.max(r,Math.min(n,i));if(r===0&&o===i)return e;if(o<=r){if(Do(e))return{x:[],y:[],...e.size?{size:[]}:{}};if(Bo(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData");const s=e.constructor;return new s(0)}return[]}if(Do(e)){const s=Array.isArray(e.x)?e.x.slice(r,o):"subarray"in e.x?e.x.subarray(r,o):Array.from(e.x).slice(r,o),a=Array.isArray(e.y)?e.y.slice(r,o):"subarray"in e.y?e.y.subarray(r,o):Array.from(e.y).slice(r,o),c={x:s,y:a};if(e.size){const u=Array.isArray(e.size)?e.size.slice(r,o):"subarray"in e.size?e.size.subarray(r,o):Array.from(e.size).slice(r,o);c.size=u}return c}if(Bo(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData");return e.subarray(r*2,o*2)}return e.slice(r,o)}function xi(e,t,n){const i=Xe(e);if(i===0||!Number.isFinite(t)||!Number.isFinite(n))return e;if(ro(e)){const s=Js(e,t),a=Qs(e,n);return s<=0&&a>=i?e:Za(e,s,a)}const o=[];for(let s=0;s<i;s++){const a=Ee(e,s);if(Number.isFinite(a)&&a>=t&&a<=n){const c=We(e,s);o.push([a,c])}}return o}function ja(e,t,n){const i=Xe(e);if(i===0)return{start:0,end:0};if(!Number.isFinite(t)||!Number.isFinite(n))return{start:0,end:i};if(!ro(e))return{start:0,end:i};const o=Js(e,t),s=Qs(e,n),a=pn(o,0,i),c=pn(s,0,i);return c<=a?{start:a,end:a}:{start:a,end:c}}function bi(e,t,n){const i=e.length;if(i===0||!Number.isFinite(t)||!Number.isFinite(n))return e;const r=Wa(e),o=i>0&&Hi(e[0]);if(r){const a=o?Xa(e,t):Ha(e,t),c=o?Ya(e,n):qa(e,n);return a<=0&&c>=i?e:c<=a?[]:e.slice(a,c)}const s=[];for(let a=0;a<i;a++){const c=e[a],u=Hi(c)?c[0]:c.timestamp;Number.isFinite(u)&&u>=t&&u<=n&&s.push(c)}return s}const Lo=e=>Math.min(1,Math.max(0,e)),ko=e=>Math.min(255,Math.max(0,e)),Mn=e=>{const t=Number.parseInt(e,16);return Number.isFinite(t)?t:0},Fn=e=>{const t=Number.parseInt(e,16);return Number.isFinite(t)?t:0},Ka=e=>{const t=e.trim();if(!t.startsWith("#"))return null;const n=t.slice(1);if(n.length===3){const i=Mn(n[0]),r=Mn(n[1]),o=Mn(n[2]);return[i*17/255,r*17/255,o*17/255,1]}if(n.length===4){const i=Mn(n[0]),r=Mn(n[1]),o=Mn(n[2]),s=Mn(n[3]);return[i*17/255,r*17/255,o*17/255,s*17/255]}if(n.length===6){const i=Fn(n.slice(0,2)),r=Fn(n.slice(2,4)),o=Fn(n.slice(4,6));return[i/255,r/255,o/255,1]}if(n.length===8){const i=Fn(n.slice(0,2)),r=Fn(n.slice(2,4)),o=Fn(n.slice(4,6)),s=Fn(n.slice(6,8));return[i/255,r/255,o/255,s/255]}return null},En=e=>{const t=e.trim();if(t.length===0)return null;if(t.endsWith("%")){const i=Number.parseFloat(t.slice(0,-1));return Number.isFinite(i)?ko(i/100*255):null}const n=Number.parseFloat(t);return Number.isFinite(n)?ko(n):null},Ja=e=>{const t=e.trim();if(t.length===0)return null;if(t.endsWith("%")){const i=Number.parseFloat(t.slice(0,-1));return Number.isFinite(i)?Lo(i/100):null}const n=Number.parseFloat(t);return Number.isFinite(n)?Lo(n):null},Qa=e=>{const t=e.trim(),n=/^(rgba?|RGBA?)\(\s*([^\)]*)\s*\)$/.exec(t);if(!n)return null;const i=n[1].toLowerCase(),o=n[2].split(",").map(s=>s.trim());if(i==="rgb"){if(o.length!==3)return null;const s=En(o[0]),a=En(o[1]),c=En(o[2]);return s==null||a==null||c==null?null:[s/255,a/255,c/255,1]}if(i==="rgba"){if(o.length!==4)return null;const s=En(o[0]),a=En(o[1]),c=En(o[2]),u=Ja(o[3]);return s==null||a==null||c==null||u==null?null:[s/255,a/255,c/255,u]}return null},pt=e=>{if(typeof e!="string")return null;const t=e.trim();if(t.length===0)return null;const n=Ka(t);if(n)return n;const i=Qa(t);return i||null},ec=(e,t={r:0,g:0,b:0,a:1})=>{const n=pt(e);if(!n)return t;const[i,r,o,s]=n;return{r:i,g:r,b:o,a:s}},vi=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,Xr=e=>{throw new Error(`RenderCoordinator: unreachable value: ${String(e)}`)},ea=e=>Array.isArray(e),tc=e=>ea(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Mt=e=>Math.min(1,Math.max(0,e)),nc=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=pn(Math.floor(r),0,Math.max(0,t)),u=pn(Math.floor(s),0,Math.max(0,n)),p=pn(Math.ceil(o),0,Math.max(0,t)),h=pn(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},Qn=(e,t)=>(e+1)/2*t,ei=(e,t)=>(1-e)/2*t,qi=24*60*60*1e3,ic=30*qi,rc=365*qi,oc=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],gr=(e,t)=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;const n=e.trim();if(n.length===0)return null;if(n.endsWith("%")){const r=Number.parseFloat(n.slice(0,-1));return Number.isFinite(r)?r/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},sc=e=>Array.isArray(e),ac=(e,t)=>{if(e==null)return{inner:0,outer:t*.7};if(sc(e)){const r=gr(e[0],t),o=gr(e[1],t),s=Math.max(0,Number.isFinite(r)?r:0),a=Math.max(s,Number.isFinite(o)?o:t*.7);return{inner:s,outer:Math.min(t,a)}}const n=gr(e,t),i=Math.max(0,Number.isFinite(n)?n:t*.7);return{inner:0,outer:Math.min(t,i)}},_t=e=>String(Math.trunc(e)).padStart(2,"0"),cc=(e,t)=>{if(!Number.isFinite(e))return null;(!Number.isFinite(t)||t<0)&&(t=0);const n=new Date(e);if(!Number.isFinite(n.getTime()))return null;const i=n.getFullYear(),r=n.getMonth()+1,o=n.getDate(),s=n.getHours(),a=n.getMinutes();return t<qi?`${_t(s)}:${_t(a)}`:t<=7*qi?`${_t(r)}/${_t(o)} ${_t(s)}:${_t(a)}`:t<3*ic?`${_t(r)}/${_t(o)}`:t<=rc?`${oc[n.getMonth()]??_t(r)} ${_t(o)}`:`${i}/${_t(r)}`},lc=8;function uc(e,t=lc){const n=Math.abs(e);if(!Number.isFinite(n)||n===0)return 0;for(let i=0;i<=t;i++){const r=n*10**i,o=Math.round(r),s=Math.abs(r-o),a=1e-9*Math.max(1,Math.abs(r));if(s<=a)return i}return Math.max(0,Math.min(t,1-Math.floor(Math.log10(n))+1))}function Uo(e){const t=uc(e);return new Intl.NumberFormat(void 0,{maximumFractionDigits:t})}function _o(e,t){if(!Number.isFinite(t))return null;const n=Math.abs(t)<1e-12?0:t,i=e.format(n);return i==="NaN"?null:i}function fc(e){return Math.max(e+1,Math.round(e*1.15))}const Go=6,xr=4,dc=5;function br(e,t){return(e+1)/2*t}function vr(e,t){return(1-e)/2*t}function wi(e,t,n){e.style.fontFamily=n.fontFamily,e.style.fontWeight=t?"500":"400",e.style.userSelect="none",e.style.pointerEvents="none"}function mc(e,t,n){var V,_,re;const{gpuContext:i,currentOptions:r,xScale:o,yScale:s,xTickValues:a,plotClipRect:c,visibleXRangeMs:u}=n;if(!r.series.some(Y=>Y.type!=="pie")||!e||!t)return;const h=i.canvas;if(!h)return;const l=Oa(h),m=$a(h);if(l<=0||m<=0)return;const C=h.offsetLeft||0,F=h.offsetTop||0,R=br(c.left,l),S=br(c.right,l),y=vr(c.top,m),b=vr(c.bottom,m);e.clear();const w=r.xAxis.tickLength??Go,d=b+w+xr+r.theme.fontSize*.5,g=r.xAxis.type==="time",v=(()=>{if(g)return null;const Y=vi(r.xAxis.min)??o.invert(c.left),W=vi(r.xAxis.max)??o.invert(c.right),Z=a.length,oe=Z===1?0:(W-Y)/(Z-1);return Uo(oe)})();for(let Y=0;Y<a.length;Y++){const W=a[Y],Z=o.scale(W),oe=br(Z,l),ee=a.length===1?"middle":Y===0?"start":Y===a.length-1?"end":"middle",q=g?cc(W,u):_o(v,W);if(q==null)continue;const de=e.addLabel(q,C+oe,F+d,{fontSize:r.theme.fontSize,color:r.theme.textColor,anchor:ee});wi(de,!1,r.theme)}const M=dc,I=r.yAxis.tickLength??Go,T=vi(r.yAxis.min)??s.invert(c.bottom),E=vi(r.yAxis.max)??s.invert(c.top),f=(E-T)/(M-1),x=Uo(f),N=R-I-xr,A=[];for(let Y=0;Y<M;Y++){const W=Y/(M-1),Z=T+W*(E-T),oe=s.scale(Z),ee=vr(oe,m),q=_o(x,Z);if(q==null)continue;const de=e.addLabel(q,C+N,F+ee,{fontSize:r.theme.fontSize,color:r.theme.textColor,anchor:"end"});wi(de,!1,r.theme),A.push(de)}const P=fc(r.theme.fontSize),L=((V=r.xAxis.name)==null?void 0:V.trim())??"";if(L.length>0){const Y=(R+S)/2,W=d+r.theme.fontSize*.5,ee=((_=r.dataZoom)==null?void 0:_.some(G=>(G==null?void 0:G.type)==="slider"))??!1?m-32:m,q=(W+ee)/2,de=e.addLabel(L,C+Y,F+q,{fontSize:P,color:r.theme.textColor,anchor:"middle"});wi(de,!0,r.theme)}const B=((re=r.yAxis.name)==null?void 0:re.trim())??"";if(B.length>0){const Y=A.length===0?0:A.reduce((q,de)=>Math.max(q,de.getBoundingClientRect().width),0),W=(y+b)/2,oe=N-Y-xr-P*.5,ee=e.addLabel(B,C+oe,F+W,{fontSize:P,color:r.theme.textColor,anchor:"middle",rotation:-90});wi(ee,!0,r.theme)}}function zo(e){return"offsetLeft"in e}function wr(e,t){return(e+1)/2*t}function Cr(e,t){return(1-e)/2*t}function pc(e,t){const n=pt(e)??[0,0,0,1],i=Mt(n[3]*Mt(t)),r=Math.round(Mt(n[0])*255),o=Math.round(Mt(n[1])*255),s=Math.round(Mt(n[2])*255);return`rgba(${r}, ${o}, ${s}, ${i})`}function hc(e,t){if(!Number.isFinite(e))return"";if(t==null)return String(e);const n=Math.min(20,Math.max(0,Math.floor(t)));return e.toFixed(n)}const Vo=/\{(x|y|value|name)\}/g;function Oo(e,t,n){return Vo.lastIndex=0,e.replace(Vo,(i,r)=>{if(r==="name")return t.name??"";const o=t[r];return o==null?"":hc(o,n)})}function yc(e){switch(e){case"center":return"middle";case"end":return"end";case"start":default:return"start"}}function gc(e,t,n){var S,y,b;const{currentOptions:i,xScale:r,yScale:o,canvasCssWidthForAnnotations:s,canvasCssHeightForAnnotations:a,plotLeftCss:c,plotTopCss:u,plotWidthCss:p,plotHeightCss:h,canvas:l}=n;if(!i.series.some(w=>w.type!=="pie")||!e||!t)return;if(!l||s<=0||a<=0||p<=0||h<=0){e.clear();return}const C=zo(l)?l.offsetLeft:0,F=zo(l)?l.offsetTop:0;e.clear();const R=i.annotations??[];if(R.length!==0)for(let w=0;w<R.length;w++){const d=R[w],g=d.label;if(!(g!=null||d.type==="text"))continue;let M=null,I=null,T={name:d.id??""};switch(d.type){case"lineX":{const ee=r.scale(d.x);M=wr(ee,s),I=u,T={...T,x:d.x,value:d.x};break}case"lineY":{const ee=o.scale(d.y),q=Cr(ee,a);M=c,I=q-8,T={...T,y:d.y,value:d.y};break}case"point":{const ee=r.scale(d.x),q=o.scale(d.y),de=wr(ee,s),G=Cr(q,a);M=de,I=G,T={...T,x:d.x,y:d.y,value:d.y};break}case"text":{if(d.position.space==="data"){const ee=r.scale(d.position.x),q=o.scale(d.position.y),de=wr(ee,s),G=Cr(q,a);M=de,I=G,T={...T,x:d.position.x,y:d.position.y,value:d.position.y}}else{const ee=c+d.position.x*p,q=u+d.position.y*h;M=ee,I=q,T={...T,x:d.position.x,y:d.position.y,value:d.position.y}}break}default:Xr(d)}if(M==null||I==null||!Number.isFinite(M)||!Number.isFinite(I))continue;const E=((S=g==null?void 0:g.offset)==null?void 0:S[0])??0,f=((y=g==null?void 0:g.offset)==null?void 0:y[1])??0,x=M+E,N=I+f,A=(g==null?void 0:g.text)??(g!=null&&g.template?Oo(g.template,T,g.decimals):g?(()=>{const ee=d.type==="lineX"?"x={x}":d.type==="lineY"?"y={y}":d.type==="point"?"({x}, {y})":d.type==="text"?d.text:"";return ee.includes("{")?Oo(ee,T,g.decimals):ee})():d.type==="text"?d.text:""),P=typeof A=="string"?A.trim():"";if(P.length===0)continue;const L=yc(g==null?void 0:g.anchor),B=((b=d.style)==null?void 0:b.color)??i.theme.textColor,V=i.theme.fontSize,_=g==null?void 0:g.background,re=(_==null?void 0:_.color)!=null?pc(_.color,_.opacity??1):void 0,Y=(()=>{const ee=_==null?void 0:_.padding;return typeof ee=="number"&&Number.isFinite(ee)?[ee,ee,ee,ee]:Array.isArray(ee)&&ee.length===4&&ee.every(q=>typeof q=="number"&&Number.isFinite(q))?[ee[0],ee[1],ee[2],ee[3]]:_?[2,4,2,4]:void 0})(),W=typeof(_==null?void 0:_.borderRadius)=="number"&&Number.isFinite(_.borderRadius)?_.borderRadius:void 0,Z={x:C+x,y:F+N,...re?{background:{backgroundColor:re,...Y?{padding:Y}:{},...W!=null?{borderRadius:W}:{}}}:{}},oe=e.addLabel(P,Z.x,Z.y,{fontSize:V,color:B,anchor:L});if(Z.background){if(oe.style.backgroundColor=Z.background.backgroundColor,oe.style.display="inline-block",oe.style.boxSizing="border-box",Z.background.padding){const[ee,q,de,G]=Z.background.padding;oe.style.padding=`${ee}px ${q}px ${de}px ${G}px`}Z.background.borderRadius!=null&&(oe.style.borderRadius=`${Z.background.borderRadius}px`)}}}const $o=20,xc=.01,bc=.2,Mr=4;function vc(e,t){let n=0,i=Xe(e);for(;n<i;){const r=n+i>>>1;Ee(e,r)<t?n=r+1:i=r}return n}function wc(e,t,n){return e>=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom}const Fr=e=>Math.min(1,Math.max(0,e)),Cc=e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null},Mc=e=>{if(typeof e!="string")return"";const t=e.trim();return t.length>0?t:""},ta=e=>Array.isArray(e),Fc=e=>{if(ta(e)){const n=e[2];return typeof n=="number"&&Number.isFinite(n)?n:null}const t=e.size;return typeof t=="number"&&Number.isFinite(t)?t:null},Sc=e=>ta(e)?e:[e.x,e.y,e.size],Nc=(e,t)=>{try{const n=e(t);return typeof n=="number"&&Number.isFinite(n)?n:null}catch{return null}},Sr=(e,t)=>{const n=Fc(t);if(n!=null)return Math.max(0,n);const i=e.symbolSize;if(typeof i=="number")return Number.isFinite(i)?Math.max(0,i):Mr;if(typeof i=="function"){const r=Nc(i,Sc(t));return r==null?Mr:Math.max(0,r)}return Mr};function Tc(e){const t=new Map,n=new Array(e.length),i=new Array(e.length);let r=0;for(let o=0;o<e.length;o++){const s=Mc(e[o].stack);if(i[o]=s,s!==""){const a=t.get(s);if(a!==void 0)n[o]=a;else{const c=r++;t.set(s,c),n[o]=c}}else n[o]=r++}return{clusterIndexBySeries:n,clusterCount:Math.max(1,r),stackIdBySeries:i}}function Ic(e){const t=[];for(let i=0;i<e.length;i++){const r=e[i].data,o=Xe(r);for(let s=0;s<o;s++){const a=Ee(r,s);Number.isFinite(a)&&t.push(a)}}if(t.length<2)return 1;t.sort((i,r)=>i-r);let n=Number.POSITIVE_INFINITY;for(let i=1;i<t.length;i++){const r=t[i]-t[i-1];r>0&&r<n&&(n=r)}return Number.isFinite(n)&&n>0?n:1}function Pc(e,t,n){if(Number.isFinite(n)&&n>0){const s=t.scale(0),a=t.scale(0+n),c=Math.abs(a-s);if(Number.isFinite(c)&&c>0)return c}const i=[];for(let o=0;o<e.length;o++){const s=e[o].data,a=Xe(s);for(let c=0;c<a;c++){const u=Ee(s,c);if(!Number.isFinite(u))continue;const p=t.scale(u);Number.isFinite(p)&&i.push(p)}}if(i.length<2)return 0;i.sort((o,s)=>o-s);let r=Number.POSITIVE_INFINITY;for(let o=1;o<i.length;o++){const s=i[o]-i[o-1];s>0&&s<r&&(r=s)}return Number.isFinite(r)&&r>0?r:0}const Ac=e=>{let t,n,i;for(let r=0;r<e.length;r++){const o=e[r];t===void 0&&o.barWidth!==void 0&&(t=o.barWidth),n===void 0&&o.barGap!==void 0&&(n=o.barGap),i===void 0&&o.barCategoryGap!==void 0&&(i=o.barCategoryGap)}return{barWidth:t,barGap:n,barCategoryGap:i}};function na(e,t){const n=Tc(e),i=n.clusterCount,r=Ic(e),o=Pc(e,t,r),s=Ac(e),a=Fr(s.barGap??xc),c=Fr(s.barCategoryGap??bc),u=Math.max(0,o*(1-c)),p=i+Math.max(0,i-1)*a,h=p>0?u/p:0;let l=0;const m=s.barWidth;if(typeof m=="number")l=Math.max(0,m),l=Math.min(l,h);else if(typeof m=="string"){const R=Cc(m);l=R==null?0:h*Fr(R)}l>0||(l=h);const C=l*a,F=i*l+Math.max(0,i-1)*C;return{categoryStep:r,categoryWidthPx:o,barWidthPx:l,gapPx:C,clusterWidthPx:F,clusterSlots:n}}const Nr=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=e[i].data,o=Xe(r);for(let s=0;s<o;s++){const a=We(r,s);Number.isFinite(a)&&(a<t&&(t=a),a>n&&(n=a))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t)<Math.abs(n)?t:n};function Rc(e,t){let n=0;for(let i=0;i<e.length;i++){const r=e[i].data,o=Xe(r);for(let s=0;s<o;s++){const a=We(r,s);if(!Number.isFinite(a))continue;const c=t.scale(a);Number.isFinite(c)&&c>n&&(n=c)}}return Math.max(0,n)}function Ec(e,t,n){const i=t.invert(n),r=t.invert(0),o=Math.min(i,r),s=Math.max(i,r);let a;!Number.isFinite(o)||!Number.isFinite(s)?a=Nr(e):o<=0&&0<=s?a=0:o>0?a=o:s<0?a=s:a=Nr(e);let c=t.scale(a);return Number.isFinite(c)||(a=Nr(e),c=t.scale(a)),Number.isFinite(c)||(a=0,c=t.scale(0)),{baselineDomain:a,baselinePx:c}}function Dc(e,t,n,i){return Number.isFinite(t)&&t>0&&Number.isFinite(e)?Math.round(e/t):Number.isFinite(i)&&i>0&&Number.isFinite(n)?Math.round(n/i):Math.round(n*1e6)}function Zi(e,t,n,i,r,o=$o){var S;if(!Number.isFinite(t)||!Number.isFinite(n))return null;const s=Number.isFinite(o)?Math.max(0,o):$o,a=s*s,c=i.invert(t);if(!Number.isFinite(c))return null;let u=-1,p=-1,h=null,l=Number.POSITIVE_INFINITY;const m=[],C=[];for(let y=0;y<e.length;y++){const b=e[y];(b==null?void 0:b.type)==="bar"&&b.visible!==!1&&(m.push(b),C.push(y))}if(m.length>0){const y=na(m,i);if(y.barWidthPx>0&&y.clusterWidthPx>=0){const b=Rc(m,r),{baselineDomain:w,baselinePx:d}=Ec(m,r,b),{clusterSlots:g,barWidthPx:v,gapPx:M,clusterWidthPx:I,categoryWidthPx:T,categoryStep:E}=y,f=new Map;let x=null;for(let N=0;N<m.length;N++){const A=m[N],P=C[N]??-1;if(P<0)continue;const L=A.data,B=Xe(L),V=g.clusterIndexBySeries[N]??0,_=g.stackIdBySeries[N]??"";for(let re=0;re<B;re++){const Y=Ee(L,re),W=We(L,re);if(!Number.isFinite(Y)||!Number.isFinite(W))continue;const Z=i.scale(Y);if(!Number.isFinite(Z))continue;const oe=Z-I/2+V*(v+M),ee=oe+v;let q=w,de=W;if(_!==""){let ne=f.get(_);ne||(ne=new Map,f.set(_,ne));const H=Dc(Z,T,Y,E);let O=ne.get(H);O||(O={posSum:w,negSum:w},ne.set(H,O)),W>=0?(q=O.posSum,de=q+W,O.posSum=de):(q=O.negSum,de=q+W,O.negSum=de)}else q=w,de=W;const G=_!==""?r.scale(q):d,te=r.scale(de);if(!Number.isFinite(G)||!Number.isFinite(te))continue;const X={left:oe,right:ee,top:Math.min(G,te),bottom:Math.max(G,te)};if(!wc(t,n,X))continue;(x===null||X.top<x.top||X.top===x.top&&P>x.seriesIndex)&&(x={seriesIndex:P,dataIndex:re,top:X.top})}}if(x){const N=(S=e[x.seriesIndex])==null?void 0:S.data;if(N){const A=Ee(N,x.dataIndex),P=We(N,x.dataIndex),L=mt(N,x.dataIndex),B=L!==void 0?[A,P,L]:[A,P];return{seriesIndex:x.seriesIndex,dataIndex:x.dataIndex,point:B,distance:0}}}}}const F=[],R=[];for(let y=0;y<e.length;y++){const b=e[y];b.type==="pie"||b.type==="candlestick"||b.visible!==!1&&(F.push(b),R.push(y))}for(let y=0;y<F.length;y++){const b=F[y],w=R[y]??-1;if(w<0)continue;const d=b.data,g=Xe(d);if(g===0)continue;const M=b.type==="scatter"?b:null;if(ro(d)){const T=vc(d,c);for(let E=T;E<g;E++){const f=Ee(d,E),x=We(d,E);if(!Number.isFinite(f)||!Number.isFinite(x))continue;const N=i.scale(f),A=r.scale(x);if(!Number.isFinite(N)||!Number.isFinite(A))continue;const P=N-t,L=A-n,B=P*P+L*L;if(P*P>l)break;let _=a;if(M){const Y=mt(d,E),Z=Sr(M,Y!==void 0?[f,x,Y]:[f,x]),oe=s+Z;_=oe*oe}if(B>_)continue;if(B<l||B===l&&(h===null||w<u||w===u&&E<p)){l=B,u=w,p=E;const Y=mt(d,E);h=Y!==void 0?[f,x,Y]:[f,x]}}for(let E=T-1;E>=0;E--){const f=Ee(d,E),x=We(d,E);if(!Number.isFinite(f)||!Number.isFinite(x))continue;const N=i.scale(f),A=r.scale(x);if(!Number.isFinite(N)||!Number.isFinite(A))continue;const P=N-t,L=A-n,B=P*P+L*L;if(P*P>l)break;let _=a;if(M){const Y=mt(d,E),Z=Sr(M,Y!==void 0?[f,x,Y]:[f,x]),oe=s+Z;_=oe*oe}if(B>_)continue;if(B<l||B===l&&(h===null||w<u||w===u&&E<p)){l=B,u=w,p=E;const Y=mt(d,E);h=Y!==void 0?[f,x,Y]:[f,x]}}}else for(let T=0;T<g;T++){const E=Ee(d,T),f=We(d,T);if(!Number.isFinite(E)||!Number.isFinite(f))continue;const x=i.scale(E),N=r.scale(f);if(!Number.isFinite(x)||!Number.isFinite(N))continue;const A=x-t,P=N-n,L=A*A+P*P;let B=a;if(M){const _=mt(d,T),Y=Sr(M,_!==void 0?[E,f,_]:[E,f]),W=s+Y;B=W*W}if(L>B)continue;if(L<l||L===l&&(h===null||w<u||w===u&&T<p)){l=L,u=w,p=T;const _=mt(d,T);h=_!==void 0?[E,f,_]:[E,f]}}}return h===null||!Number.isFinite(l)?null:{seriesIndex:u,dataIndex:p,point:h,distance:Math.sqrt(l)}}const Bc=5,Lc=1,kc=4;function Uc(e,t){var l;const{currentOptions:n,xScale:i,yScale:r,gridArea:o,xTickCount:s,hasCartesianSeries:a,effectivePointer:c,interactionScales:u,seriesForRender:p,withAlpha:h}=t;if(e.gridRenderer.prepare(o,{color:n.theme.gridLineColor}),a&&(e.xAxisRenderer.prepare(n.xAxis,i,"x",o,n.theme.axisLineColor,n.theme.axisTickColor,s),e.yAxisRenderer.prepare(n.yAxis,r,"y",o,n.theme.axisLineColor,n.theme.axisTickColor,Bc)),c.hasPointer&&c.isInGrid){const m={showX:!0,showY:c.source!=="sync",color:h(n.theme.axisLineColor,.6),lineWidth:Lc};e.crosshairRenderer.prepare(c.x,c.y,o,m),e.crosshairRenderer.setVisible(!0)}else e.crosshairRenderer.setVisible(!1);if(c.source==="mouse"&&c.hasPointer&&c.isInGrid)if(u){const m=Zi(p,c.gridX,c.gridY,u.xScale,u.yScale);if(m){const{x:C,y:F}=tc(m.point),R=u.xScale.scale(C),S=u.yScale.scale(F);if(Number.isFinite(R)&&Number.isFinite(S)){const y=o.left+R,b=o.top+S,w=nc(o),d={centerDeviceX:y*o.devicePixelRatio,centerDeviceY:b*o.devicePixelRatio,devicePixelRatio:o.devicePixelRatio,canvasWidth:o.canvasWidth,canvasHeight:o.canvasHeight,scissor:w},g=((l=n.series[m.seriesIndex])==null?void 0:l.color)??"#888";e.highlightRenderer.prepare(d,g,kc),e.highlightRenderer.setVisible(!0)}else e.highlightRenderer.setVisible(!1)}else e.highlightRenderer.setVisible(!1)}else e.highlightRenderer.setVisible(!1);else e.highlightRenderer.setVisible(!1)}function Wo(e,t,n){const i=pt(e??n)??pt(n)??[1,1,1,1],r=t==null?1:Mt(t);return[Mt(i[0]),Mt(i[1]),Mt(i[2]),Mt(i[3]*r)]}function _c(e,t){const n=pt(e)??[0,0,0,1],i=Mt(n[3]*Mt(t)),r=Math.round(Mt(n[0])*255),o=Math.round(Mt(n[1])*255),s=Math.round(Mt(n[2])*255);return`rgba(${r}, ${o}, ${s}, ${i})`}function Gc(e,t){if(!Number.isFinite(e))return"";if(t==null)return String(e);const n=Math.min(20,Math.max(0,Math.floor(t)));return e.toFixed(n)}function Xo(e,t,n){const i=/\{(x|y|value|name)\}/g;return e.replace(i,(r,o)=>{if(o==="name")return t.name??"";const s=t[o];return s==null?"":Gc(s,n)})}function zc(e){switch(e){case"center":return"middle";case"end":return"end";case"start":default:return"start"}}function Vc(e){var b,w,d,g,v,M,I,T,E,f,x,N,A,P;const{annotations:t,xScale:n,yScale:i,plotBounds:r,canvasCssWidth:o,canvasCssHeight:s,theme:a,offsetX:c=0,offsetY:u=0}=e,{leftCss:p,topCss:h,widthCss:l,heightCss:m}=r,C=[],F=[],R=[],S=[],y=[];if(t.length===0||o<=0||s<=0||l<=0||m<=0)return{linesBelow:C,linesAbove:F,markersBelow:R,markersAbove:S,labels:y};for(let L=0;L<t.length;L++){const B=t[L],V=B.layer??"aboveSeries",_=V==="belowSeries"?C:F,re=V==="belowSeries"?R:S,Y=(b=B.style)==null?void 0:b.color,W=(w=B.style)==null?void 0:w.opacity,Z=typeof((d=B.style)==null?void 0:d.lineWidth)=="number"&&Number.isFinite(B.style.lineWidth)?Math.max(0,B.style.lineWidth):1,oe=(g=B.style)==null?void 0:g.lineDash,ee=Wo(Y,W,a.textColor);switch(B.type){case"lineX":{const he=n.scale(B.x),be=Qn(he,o);if(!Number.isFinite(be))break;_.push({axis:"vertical",positionCssPx:be,lineWidth:Z,lineDash:oe,rgba:ee});break}case"lineY":{const he=i.scale(B.y),be=ei(he,s);if(!Number.isFinite(be))break;_.push({axis:"horizontal",positionCssPx:be,lineWidth:Z,lineDash:oe,rgba:ee});break}case"point":{const he=n.scale(B.x),be=i.scale(B.y),Ge=Qn(he,o),ze=ei(be,s);if(!Number.isFinite(Ge)||!Number.isFinite(ze))break;const rt=typeof((v=B.marker)==null?void 0:v.size)=="number"&&Number.isFinite(B.marker.size)?Math.max(1,B.marker.size):6,Ze=((I=(M=B.marker)==null?void 0:M.style)==null?void 0:I.color)??((T=B.style)==null?void 0:T.color),ht=((f=(E=B.marker)==null?void 0:E.style)==null?void 0:f.opacity)??((x=B.style)==null?void 0:x.opacity),gt=Wo(Ze,ht,a.textColor);re.push({xCssPx:Ge,yCssPx:ze,sizeCssPx:rt,fillRgba:gt});break}case"text":break;default:Xr(B)}const q=B.label;if(!(q!=null||B.type==="text"))continue;let G=null,te=null,X={name:B.id??""};switch(B.type){case"lineX":{const he=n.scale(B.x);G=Qn(he,o),te=h,X={...X,x:B.x,value:B.x};break}case"lineY":{const he=i.scale(B.y),be=ei(he,s);G=p,te=be-8,X={...X,y:B.y,value:B.y};break}case"point":{const he=n.scale(B.x),be=i.scale(B.y),Ge=Qn(he,o),ze=ei(be,s);G=Ge,te=ze,X={...X,x:B.x,y:B.y,value:B.y};break}case"text":{if(B.position.space==="data"){const he=n.scale(B.position.x),be=i.scale(B.position.y),Ge=Qn(he,o),ze=ei(be,s);G=Ge,te=ze,X={...X,x:B.position.x,y:B.position.y,value:B.position.y}}else{const he=p+B.position.x*l,be=h+B.position.y*m;G=he,te=be,X={...X,x:B.position.x,y:B.position.y,value:B.position.y}}break}default:Xr(B)}if(G==null||te==null||!Number.isFinite(G)||!Number.isFinite(te))continue;const Q=((N=q==null?void 0:q.offset)==null?void 0:N[0])??0,ne=((A=q==null?void 0:q.offset)==null?void 0:A[1])??0,H=G+Q,O=te+ne,se=(q==null?void 0:q.text)??(q!=null&&q.template?Xo(q.template,X,q.decimals):q?(()=>{const he=B.type==="lineX"?"x={x}":B.type==="lineY"?"y={y}":B.type==="point"?"({x}, {y})":B.type==="text"?B.text:"";return he.includes("{")?Xo(he,X,q.decimals):he})():B.type==="text"?B.text:""),ce=typeof se=="string"?se.trim():"";if(ce.length===0)continue;const le=zc(q==null?void 0:q.anchor),me=((P=B.style)==null?void 0:P.color)??a.textColor,ge=a.fontSize,we=q==null?void 0:q.background,it=(we==null?void 0:we.color)!=null?_c(we.color,we.opacity??1):void 0,Ke=(()=>{const he=we==null?void 0:we.padding;return typeof he=="number"&&Number.isFinite(he)?[he,he,he,he]:Array.isArray(he)&&he.length===4&&he.every(be=>typeof be=="number"&&Number.isFinite(be))?[he[0],he[1],he[2],he[3]]:we?[2,4,2,4]:void 0})(),et=typeof(we==null?void 0:we.borderRadius)=="number"&&Number.isFinite(we.borderRadius)?we.borderRadius:void 0,ke={text:ce,x:c+H,y:u+O,anchor:le,color:me,fontSize:ge,...it?{background:{backgroundColor:it,...Ke?{padding:Ke}:{},...et!=null?{borderRadius:et}:{}}}:{}};y.push(ke)}return{linesBelow:C,linesAbove:F,markersBelow:R,markersAbove:S,labels:y}}function ia(e){return Math.max(0,Math.min(1,e))}function Oc(e){return e.type==="area"||e.type==="line"&&!!e.areaStyle}function $c(e,t){const{currentOptions:n,seriesForRender:i,xScale:r,yScale:o,gridArea:s,dataStore:a,appendedGpuThisFrame:c,gpuSeriesKindByIndex:u,zoomState:p,visibleXDomain:h,introPhase:l,introProgress01:m,withAlpha:C,maxRadiusCss:F}=t,R=n.yAxis.min??n.yAxis.min??0,S=[],y=l==="running"?ia(m):1;for(let d=0;d<i.length;d++){const g=i[d];switch(g.type){case"area":{const v=g.baseline??R;e.areaRenderers[d].prepare(g,g.data,r,o,v);break}case"line":{const v=(()=>{if(n.xAxis.type!=="time")return 0;const E=g.data;for(let f=0;f<E.length;f++){const x=E[f],N=ea(x)?x[0]:x.x;if(Number.isFinite(N))return N}return 0})();c.has(d)||a.setSeries(d,g.data,{xOffset:v});const M=a.getSeriesBuffer(d);e.lineRenderers[d].prepare(g,M,r,o,v);const I=(p==null?void 0:p.getRange())??null;if((I==null||Number.isFinite(I.start)&&Number.isFinite(I.end)&&I.start<=0&&I.end>=100)&&g.sampling==="none"?u[d]="fullRawLine":u[d]="other",g.areaStyle){const E={type:"area",name:g.name,rawData:g.data,data:g.data,color:g.areaStyle.color,areaStyle:g.areaStyle,sampling:g.sampling,samplingThreshold:g.samplingThreshold};e.areaRenderers[d].prepare(E,E.data,r,o,R)}break}case"bar":{S.push(g);break}case"scatter":{if(g.mode==="density"){const v=g.rawData??g.data,M=ja(v,h.min,h.max);c.has(d)||a.setSeries(d,v);const I=a.getSeriesBuffer(d),T=a.getSeriesPointCount(d);e.scatterDensityRenderers[d].prepare(g,I,T,M.start,M.end,r,o,s,g.rawBounds),u[d]="other"}else{const v=y<1?{...g,color:C(g.color,y)}:g;e.scatterRenderers[d].prepare(v,g.data,r,o,s)}break}case"pie":{if(y<1&&F>0){const v=ac(g.radius,F),M=Math.max(0,v.inner)*y,I=Math.max(M,v.outer)*y,T={...g,radius:[M,I]};e.pieRenderers[d].prepare(T,s);break}e.pieRenderers[d].prepare(g,s);break}case"candlestick":{e.candlestickRenderers[d].prepare(g,g.data,r,o,s,n.theme.backgroundColor);break}default:{const v=g;throw new Error(`Unhandled series type: ${v.type}`)}}}const b=i.map((d,g)=>({series:d,originalIndex:g})).filter(({series:d})=>d.visible!==!1),w=S.filter(d=>d.visible!==!1);return{visibleSeriesForRender:b,barSeriesConfigs:S,visibleBarSeriesConfigs:w}}function Wc(e,t,n){for(let i=0;i<t.length;i++){const r=t[i];r.visible!==!1&&r.type==="scatter"&&r.mode==="density"&&e.scatterDensityRenderers[i].encodeCompute(n)}}function Xc(e,t,n,i){const{hasCartesianSeries:r,gridArea:o,mainPass:s,plotScissor:a,introPhase:c,introProgress01:u,referenceLineBelowCount:p,markerBelowCount:h}=n,{visibleSeriesForRender:l}=i,m=c==="running"?ia(u):1;for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];F.type==="pie"&&e.pieRenderers[R].render(s)}r&&a.w>0&&a.h>0&&(p>0||h>0)&&(s.setScissorRect(a.x,a.y,a.w,a.h),p>0&&t.referenceLineRenderer.render(s,0,p),h>0&&t.annotationMarkerRenderer.render(s,0,h),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight));for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];if(Oc(F))if(m<1){const S=pn(Math.floor(a.w*m),0,a.w);S>0&&a.h>0&&(s.setScissorRect(a.x,a.y,S,a.h),e.areaRenderers[R].render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight))}else s.setScissorRect(a.x,a.y,a.w,a.h),e.areaRenderers[R].render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight)}a.w>0&&a.h>0&&(s.setScissorRect(a.x,a.y,a.w,a.h),e.barRenderer.render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight));for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];F.type==="candlestick"&&e.candlestickRenderers[R].render(s)}for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];F.type==="scatter"&&(F.mode==="density"?e.scatterDensityRenderers[R].render(s):e.scatterRenderers[R].render(s))}for(let C=0;C<l.length;C++){const{series:F,originalIndex:R}=l[C];if(F.type==="line")if(m<1){const S=pn(Math.floor(a.w*m),0,a.w);S>0&&a.h>0&&(s.setScissorRect(a.x,a.y,S,a.h),e.lineRenderers[R].render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight))}else s.setScissorRect(a.x,a.y,a.w,a.h),e.lineRenderers[R].render(s),s.setScissorRect(0,0,o.canvasWidth,o.canvasHeight)}}function Yc(e,t){const{hasCartesianSeries:n,gridArea:i,overlayPass:r,plotScissor:o,referenceLineBelowCount:s,referenceLineAboveCount:a,markerBelowCount:c,markerAboveCount:u}=t;if(n&&o.w>0&&o.h>0&&(a>0||u>0)){const h=s,l=c;r.setScissorRect(o.x,o.y,o.w,o.h),a>0&&e.referenceLineRendererMsaa.render(r,h,a),u>0&&e.annotationMarkerRendererMsaa.render(r,l,u),r.setScissorRect(0,0,i.canvasWidth,i.canvasHeight)}}const ji=`// grid.wgsl
|
|
2
|
+
// Minimal grid line shader:
|
|
3
|
+
// - Vertex input: vec2<f32> position in clip-space coordinates
|
|
4
|
+
// - Uniforms: identity transform + solid RGBA color
|
|
5
|
+
|
|
6
|
+
struct VSUniforms {
|
|
7
|
+
transform: mat4x4<f32>,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
11
|
+
|
|
12
|
+
struct FSUniforms {
|
|
13
|
+
color: vec4<f32>,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
17
|
+
|
|
18
|
+
struct VSIn {
|
|
19
|
+
@location(0) position: vec2<f32>,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
struct VSOut {
|
|
23
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
@vertex
|
|
27
|
+
fn vsMain(in: VSIn) -> VSOut {
|
|
28
|
+
var out: VSOut;
|
|
29
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(in.position, 0.0, 1.0);
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@fragment
|
|
34
|
+
fn fsMain() -> @location(0) vec4<f32> {
|
|
35
|
+
return fsUniforms.color;
|
|
36
|
+
}
|
|
37
|
+
`,Hc="vsMain",qc="fsMain",Zc=e=>Number.isInteger(e)&&e>0&&(e&e-1)===0,jc=(e,t)=>{if(!Number.isFinite(e)||e<0)throw new Error(`alignTo(value): value must be a finite non-negative number. Received: ${String(e)}`);if(!Zc(t))throw new Error(`alignTo(alignment): alignment must be a positive power of two. Received: ${String(t)}`);return Math.floor(e)+t-1&~(t-1)},Yo=(e,t)=>"module"in t?{module:t.module,entryPoint:t.entryPoint||"",constants:t.constants}:{module:ra(e,t.code,t.label),entryPoint:t.entryPoint||"",constants:t.constants};function ra(e,t,n){if(typeof t!="string"||t.length===0)throw new Error("createShaderModule(code): WGSL code must be a non-empty string.");return e.createShaderModule({code:t,label:n})}function Tt(e,t){const n=t.layout??(t.bindGroupLayouts?e.createPipelineLayout({bindGroupLayouts:[...t.bindGroupLayouts]}):"auto"),i=Yo(e,t.vertex),r=i.entryPoint||Hc;let o;if(t.fragment){const c=Yo(e,t.fragment),u=c.entryPoint||qc;let p=t.fragment.targets;if(!p){const h=t.fragment.formats;if(!h)throw new Error("createRenderPipeline(fragment): provide either `fragment.targets` or `fragment.formats` when a fragment stage is present.");p=(Array.isArray(h)?h:[h]).map(m=>({format:m,blend:t.fragment.blend,writeMask:t.fragment.writeMask}))}o={module:c.module,entryPoint:u,targets:[...p],constants:c.constants}}const s=t.primitive??{topology:"triangle-list"},a=t.multisample??{count:1};return e.createRenderPipeline({label:t.label,layout:n,vertex:{module:i.module,entryPoint:r,buffers:t.vertex.buffers?[...t.vertex.buffers]:[],constants:i.constants},fragment:o,primitive:s,depthStencil:t.depthStencil,multisample:a})}function nt(e,t,n){if(!Number.isFinite(t)||t<=0)throw new Error(`createUniformBuffer(size): size must be a positive number. Received: ${String(t)}`);const i=(n==null?void 0:n.alignment)??16,r=jc(t,Math.max(4,i)),o=e.limits.maxUniformBufferBindingSize;if(r>o)throw new Error(`createUniformBuffer(size): requested size ${r} exceeds device.limits.maxUniformBufferBindingSize (${o}).`);return e.createBuffer({label:n==null?void 0:n.label,size:r,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST})}function Qe(e,t,n){const i=n instanceof ArrayBuffer?{arrayBuffer:n,offset:0,size:n.byteLength}:{arrayBuffer:n.buffer,offset:n.byteOffset,size:n.byteLength};if(i.size!==0){if(i.offset&3||i.size&3)throw new Error(`writeUniformBuffer(data): data byteOffset (${i.offset}) and byteLength (${i.size}) must be multiples of 4 for queue.writeBuffer().`);if(i.size>t.size)throw new Error(`writeUniformBuffer(data): data byteLength (${i.size}) exceeds buffer.size (${t.size}).`);e.queue.writeBuffer(t,0,i.arrayBuffer,i.offset,i.size)}}const Kc="bgra8unorm",Jc=5,Qc=6,el=[1,1,1,.8],tl=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e},nl=e=>Number.isFinite(e.left)&&Number.isFinite(e.right)&&Number.isFinite(e.top)&&Number.isFinite(e.bottom)&&Number.isFinite(e.canvasWidth)&&Number.isFinite(e.canvasHeight),Ho=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,il=(e,t)=>{let n=e,i=t;if((!Number.isFinite(n)||!Number.isFinite(i))&&(n=0,i=1),n===i)i=n+1;else if(n>i){const r=n;n=i,i=r}return{min:n,max:i}},rl=(e,t,n,i,r)=>{const{left:o,right:s,top:a,bottom:c,canvasWidth:u,canvasHeight:p}=i,h=Number.isFinite(i.devicePixelRatio)&&i.devicePixelRatio>0?i.devicePixelRatio:1;if(!nl(i))throw new Error("AxisRenderer.prepare: gridArea dimensions must be finite numbers.");if(u<=0||p<=0)throw new Error("AxisRenderer.prepare: canvas dimensions must be positive.");if(o<0||s<0||a<0||c<0)throw new Error("AxisRenderer.prepare: gridArea margins must be non-negative.");const l=o*h,m=u-s*h,C=a*h,F=p-c*h,R=l/u*2-1,S=m/u*2-1,y=1-C/p*2,b=1-F/p*2,w=e.tickLength??Qc;if(!Number.isFinite(w)||w<0)throw new Error("AxisRenderer.prepare: tickLength must be a finite non-negative number.");const d=r??Jc,g=Math.max(1,Math.floor(d));if(!Number.isFinite(d)||g<1)throw new Error("AxisRenderer.prepare: tickCount must be a finite number >= 1.");const v=w*h,M=v/u*2,I=v/p*2,T=Ho(e.min)??(n==="x"?t.invert(R):t.invert(b)),E=Ho(e.max)??(n==="x"?t.invert(S):t.invert(y)),f=il(T,E),x=f.min,N=f.max,A=1+g,P=new Float32Array(A*2*2);let L=0;if(n==="x"){P[L++]=R,P[L++]=b,P[L++]=S,P[L++]=b;const B=b,V=B-I;for(let _=0;_<g;_++){const re=g===1?.5:_/(g-1),Y=x+re*(N-x),W=t.scale(Y);P[L++]=W,P[L++]=B,P[L++]=W,P[L++]=V}}else{P[L++]=R,P[L++]=b,P[L++]=R,P[L++]=y;const B=R,V=B-M;for(let _=0;_<g;_++){const re=g===1?.5:_/(g-1),Y=x+re*(N-x),W=t.scale(Y);P[L++]=B,P[L++]=W,P[L++]=V,P[L++]=W}}return P};function qo(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??Kc,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,64,{label:"axisRenderer/vsUniforms"}),s=nt(e,16,{label:"axisRenderer/fsUniformsLine"}),a=nt(e,16,{label:"axisRenderer/fsUniformsTick"}),c=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),u=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:a}}]}),p=Tt(e,{label:"axisRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:ji,label:"grid.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:ji,label:"grid.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"line-list",cullMode:"none"},multisample:{count:1}});let h=null,l=0;const m=()=>{if(n)throw new Error("AxisRenderer is disposed.")};return{prepare:(S,y,b,w,d,g,v)=>{if(m(),b!=="x"&&b!=="y")throw new Error("AxisRenderer.prepare: orientation must be 'x' or 'y'.");const M=rl(S,y,b,w,v),I=M.byteLength,T=Math.max(4,I);if(!h||h.size<T){if(h)try{h.destroy()}catch{}h=e.createBuffer({label:"axisRenderer/vertexBuffer",size:T,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}e.queue.writeBuffer(h,0,M.buffer,0,M.byteLength),l=M.length/2,Qe(e,o,tl());const E=d??"rgba(255,255,255,0.8)",f=g??E,x=pt(E)??el,N=pt(f)??x,A=new ArrayBuffer(4*4);new Float32Array(A).set([x[0],x[1],x[2],x[3]]),Qe(e,s,A);const P=new ArrayBuffer(4*4);new Float32Array(P).set([N[0],N[1],N[2],N[3]]),Qe(e,a,P)},render:S=>{m(),!(l===0||!h)&&(S.setPipeline(p),S.setVertexBuffer(0,h),S.setBindGroup(0,c),S.draw(Math.min(2,l)),l>2&&(S.setBindGroup(0,u),S.draw(l-2,1,2,0)))},dispose:()=>{if(!n){n=!0;try{o.destroy()}catch{}try{s.destroy()}catch{}try{a.destroy()}catch{}if(h)try{h.destroy()}catch{}h=null,l=0}}}}const ol="bgra8unorm",sl=5,al=6,cl="rgba(255,255,255,0.15)",ll=[1,1,1,.15],ul=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e},fl=(e,t,n)=>{const{left:i,right:r,top:o,bottom:s,canvasWidth:a,canvasHeight:c}=e,u=Number.isFinite(e.devicePixelRatio)&&e.devicePixelRatio>0?e.devicePixelRatio:1,p=i*u,h=a-r*u,l=o*u,m=c-s*u,C=h-p,F=m-l,R=t+n,S=new Float32Array(R*2*2);let y=0;for(let b=0;b<t;b++){const w=t===1?.5:b/(t-1),d=l+w*F,g=p/a*2-1,v=h/a*2-1,M=1-d/c*2;S[y++]=g,S[y++]=M,S[y++]=v,S[y++]=M}for(let b=0;b<n;b++){const w=n===1?.5:b/(n-1),g=(p+w*C)/a*2-1,v=1-l/c*2,M=1-m/c*2;S[y++]=g,S[y++]=v,S[y++]=g,S[y++]=M}return S};function dl(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??ol,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,64,{label:"gridRenderer/vsUniforms"}),s=nt(e,16,{label:"gridRenderer/fsUniforms"}),a=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),c=Tt(e,{label:"gridRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:ji,label:"grid.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:ji,label:"grid.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"line-list",cullMode:"none"},multisample:{count:1}});let u=null,p=0;const h=()=>{if(n)throw new Error("GridRenderer is disposed.")};return{prepare:(F,R)=>{h();const S=R!=null&&typeof R=="object"&&("lineCount"in R||"color"in R),y=S?R:void 0,b=S?y==null?void 0:y.lineCount:R,w=(b==null?void 0:b.horizontal)??sl,d=(b==null?void 0:b.vertical)??al,g=(y==null?void 0:y.color)??cl;if(w<0||d<0)throw new Error("GridRenderer.prepare: line counts must be non-negative.");if(!Number.isFinite(F.left)||!Number.isFinite(F.right)||!Number.isFinite(F.top)||!Number.isFinite(F.bottom)||!Number.isFinite(F.canvasWidth)||!Number.isFinite(F.canvasHeight))throw new Error("GridRenderer.prepare: gridArea dimensions must be finite numbers.");if(F.canvasWidth<=0||F.canvasHeight<=0)throw new Error("GridRenderer.prepare: canvas dimensions must be positive.");if(w===0&&d===0){p=0;return}const v=fl(F,w,d),M=v.byteLength,I=Math.max(4,M);if(!u||u.size<I){if(u)try{u.destroy()}catch{}u=e.createBuffer({label:"gridRenderer/vertexBuffer",size:I,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}e.queue.writeBuffer(u,0,v.buffer,0,v.byteLength),p=(w+d)*2;const T=ul();Qe(e,o,T);const E=pt(g)??ll,f=new ArrayBuffer(4*4);new Float32Array(f).set([E[0],E[1],E[2],E[3]]),Qe(e,s,f)},render:F=>{h(),!(p===0||!u)&&(F.setPipeline(c),F.setBindGroup(0,a),F.setVertexBuffer(0,u),F.draw(p))},dispose:()=>{if(!n){n=!0;try{o.destroy()}catch{}try{s.destroy()}catch{}if(u)try{u.destroy()}catch{}u=null,p=0}}}}const Zo=`// area.wgsl
|
|
38
|
+
// Minimal area-fill shader (triangle-strip):
|
|
39
|
+
// - Vertex input: vec2<f32> position in data coords
|
|
40
|
+
// - Uniforms: clip-space transform + baseline value + solid RGBA color
|
|
41
|
+
// - Topology: triangle-strip
|
|
42
|
+
// - CPU duplicates vertices as p0,p0,p1,p1,... and we use vertex_index parity:
|
|
43
|
+
// even index -> "top" vertex (original y)
|
|
44
|
+
// odd index -> "baseline" vertex (uniform baseline)
|
|
45
|
+
|
|
46
|
+
struct VSUniforms {
|
|
47
|
+
transform: mat4x4<f32>,
|
|
48
|
+
baseline: f32,
|
|
49
|
+
// Pad to 16-byte multiple (uniform buffer layout requirements).
|
|
50
|
+
_pad0: vec3<f32>,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
54
|
+
|
|
55
|
+
struct FSUniforms {
|
|
56
|
+
color: vec4<f32>,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
60
|
+
|
|
61
|
+
struct VSIn {
|
|
62
|
+
@location(0) position: vec2<f32>,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
struct VSOut {
|
|
66
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
@vertex
|
|
70
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
71
|
+
var out: VSOut;
|
|
72
|
+
let useBaseline = (vertexIndex & 1u) == 1u;
|
|
73
|
+
let y = select(in.position.y, vsUniforms.baseline, useBaseline);
|
|
74
|
+
let pos = vec2<f32>(in.position.x, y);
|
|
75
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(pos, 0.0, 1.0);
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@fragment
|
|
80
|
+
fn fsMain() -> @location(0) vec4<f32> {
|
|
81
|
+
return fsUniforms.color;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
`,ml="bgra8unorm",jo=e=>Math.min(1,Math.max(0,e)),pl=e=>pt(e)??[0,0,0,1],hl=e=>Array.isArray(e),oa=e=>hl(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},yl=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(let o=0;o<e.length;o++){const{x:s,y:a}=oa(e[o]);!Number.isFinite(s)||!Number.isFinite(a)||(s<t&&(t=s),s>n&&(n=s),a<i&&(i=a),a>r&&(r=a))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?{xMin:0,xMax:1,yMin:0,yMax:1}:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})},Ko=(e,t,n)=>{const i=e.scale(t),r=e.scale(n);if(!Number.isFinite(t)||!Number.isFinite(n)||t===n||!Number.isFinite(i)||!Number.isFinite(r))return{a:0,b:Number.isFinite(i)?i:0};const o=(r-i)/(n-t),s=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(s)?s:0}},gl=(e,t,n,i,r)=>{e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=n,e[13]=r,e[14]=0,e[15]=1},xl=e=>{const t=e.length,n=new Float32Array(t*2*2);let i=0;for(let r=0;r<t;r++){const{x:o,y:s}=oa(e[r]);n[i++]=o,n[i++]=s,n[i++]=o,n[i++]=s}return n};function bl(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??ml,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,96,{label:"areaRenderer/vsUniforms"}),s=nt(e,16,{label:"areaRenderer/fsUniforms"}),a=new ArrayBuffer(96),c=new Float32Array(a),u=new Float32Array(4),p=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),h=Tt(e,{label:"areaRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:Zo,label:"area.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:Zo,label:"area.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-strip",cullMode:"none"},multisample:{count:1}});let l=null,m=0;const C=()=>{if(n)throw new Error("AreaRenderer is disposed.")},F=(b,w,d,g,v)=>{gl(c,b,w,d,g),c[16]=v,c[17]=0,c[18]=0,c[19]=0,c[20]=0,c[21]=0,c[22]=0,c[23]=0,Qe(e,o,a)};return{prepare:(b,w,d,g,v)=>{C();const M=xl(w),I=M.byteLength,T=Math.max(4,I);if(!l||l.size<T){if(l)try{l.destroy()}catch{}l=e.createBuffer({label:"areaRenderer/vertexBuffer",size:T,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}M.byteLength>0&&e.queue.writeBuffer(l,0,M.buffer,0,M.byteLength),m=M.length/2;const{xMin:E,xMax:f,yMin:x,yMax:N}=yl(w),{a:A,b:P}=Ko(d,E,f),{a:L,b:B}=Ko(g,x,N),V=Number.isFinite(v??Number.NaN)?v:Number.isFinite(x)?x:0;F(A,P,L,B,V);const[_,re,Y,W]=pl(b.areaStyle.color),Z=jo(b.areaStyle.opacity);u[0]=_,u[1]=re,u[2]=Y,u[3]=jo(W*Z),Qe(e,s,u)},render:b=>{C(),!(!l||m<4)&&(b.setPipeline(h),b.setBindGroup(0,p),b.setVertexBuffer(0,l),b.draw(m))},dispose:()=>{if(!n){if(n=!0,l)try{l.destroy()}catch{}l=null,m=0;try{o.destroy()}catch{}try{s.destroy()}catch{}}}}}const Jo=`// line.wgsl
|
|
85
|
+
// Minimal line-strip shader:
|
|
86
|
+
// - Vertex input: vec2<f32> position in data coords
|
|
87
|
+
// - Uniforms: clip-space transform + solid RGBA color
|
|
88
|
+
|
|
89
|
+
struct VSUniforms {
|
|
90
|
+
transform: mat4x4<f32>,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
94
|
+
|
|
95
|
+
struct FSUniforms {
|
|
96
|
+
color: vec4<f32>,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
100
|
+
|
|
101
|
+
struct VSIn {
|
|
102
|
+
@location(0) position: vec2<f32>,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
struct VSOut {
|
|
106
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
@vertex
|
|
110
|
+
fn vsMain(in: VSIn) -> VSOut {
|
|
111
|
+
var out: VSOut;
|
|
112
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(in.position, 0.0, 1.0);
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@fragment
|
|
117
|
+
fn fsMain() -> @location(0) vec4<f32> {
|
|
118
|
+
return fsUniforms.color;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
`,vl="bgra8unorm",Qo=e=>Math.min(1,Math.max(0,e)),wl=e=>pt(e)??[0,0,0,1],Cl=e=>Array.isArray(e),Ml=e=>Cl(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Fl=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(let o=0;o<e.length;o++){const{x:s,y:a}=Ml(e[o]);!Number.isFinite(s)||!Number.isFinite(a)||(s<t&&(t=s),s>n&&(n=s),a<i&&(i=a),a>r&&(r=a))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?{xMin:0,xMax:1,yMin:0,yMax:1}:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})},es=(e,t,n)=>{const i=e.scale(t),r=e.scale(n);if(!Number.isFinite(t)||!Number.isFinite(n)||t===n||!Number.isFinite(i)||!Number.isFinite(r))return{a:0,b:Number.isFinite(i)?i:0};const o=(r-i)/(n-t),s=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(s)?s:0}},Sl=(e,t,n,i,r)=>{e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=n,e[13]=r,e[14]=0,e[15]=1};function Nl(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??vl,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,64,{label:"lineRenderer/vsUniforms"}),s=nt(e,16,{label:"lineRenderer/fsUniforms"}),a=new ArrayBuffer(64),c=new Float32Array(a),u=new Float32Array(4),p=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),h=Tt(e,{label:"lineRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:Jo,label:"line.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:Jo,label:"line.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"line-strip",cullMode:"none"},multisample:{count:1}});let l=null,m=0;const C=()=>{if(n)throw new Error("LineRenderer is disposed.")};return{prepare:(y,b,w,d,g=0)=>{C(),l=b;const v=y.data;m=v.length;const{xMin:M,xMax:I,yMin:T,yMax:E}=Fl(v),{a:f,b:x}=es(w,M,I),{a:N,b:A}=es(d,T,E),P=x+f*g;Sl(c,f,P,N,A),Qe(e,o,a);const[L,B,V,_]=wl(y.color),re=Qo(y.lineStyle.opacity);u[0]=L,u[1]=B,u[2]=V,u[3]=Qo(_*re),Qe(e,s,u)},render:y=>{C(),!(!l||m<2)&&(y.setPipeline(h),y.setBindGroup(0,p),y.setVertexBuffer(0,l),y.draw(m))},dispose:()=>{if(!n){n=!0,l=null,m=0;try{o.destroy()}catch{}try{s.destroy()}catch{}}}}}const ts=`// bar.wgsl
|
|
122
|
+
// Instanced bar/rect shader:
|
|
123
|
+
// - Per-instance vertex input:
|
|
124
|
+
// - rect = vec4<f32>(x, y, width, height) in CLIP space
|
|
125
|
+
// - color = vec4<f32>(r, g, b, a) in [0..1]
|
|
126
|
+
// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS
|
|
127
|
+
// - Uniforms:
|
|
128
|
+
// - @group(0) @binding(0): VSUniforms { transform }
|
|
129
|
+
|
|
130
|
+
struct VSUniforms {
|
|
131
|
+
transform: mat4x4<f32>,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
135
|
+
|
|
136
|
+
struct VSIn {
|
|
137
|
+
// rect.xy = origin, rect.zw = size (width, height)
|
|
138
|
+
@location(0) rect: vec4<f32>,
|
|
139
|
+
@location(1) color: vec4<f32>,
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
struct VSOut {
|
|
143
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
144
|
+
@location(0) color: vec4<f32>,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
@vertex
|
|
148
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
149
|
+
// Fixed local corners for 2 triangles (triangle-list).
|
|
150
|
+
let corners = array<vec2<f32>, 6>(
|
|
151
|
+
vec2<f32>(0.0, 0.0),
|
|
152
|
+
vec2<f32>(1.0, 0.0),
|
|
153
|
+
vec2<f32>(0.0, 1.0),
|
|
154
|
+
vec2<f32>(0.0, 1.0),
|
|
155
|
+
vec2<f32>(1.0, 0.0),
|
|
156
|
+
vec2<f32>(1.0, 1.0)
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
// Normalize negative width/height by computing min/max extents.
|
|
160
|
+
let p0 = in.rect.xy;
|
|
161
|
+
let p1 = in.rect.xy + in.rect.zw;
|
|
162
|
+
let rectMin = min(p0, p1);
|
|
163
|
+
let rectMax = max(p0, p1);
|
|
164
|
+
let rectSize = rectMax - rectMin;
|
|
165
|
+
|
|
166
|
+
let corner = corners[vertexIndex];
|
|
167
|
+
let pos = rectMin + corner * rectSize;
|
|
168
|
+
|
|
169
|
+
var out: VSOut;
|
|
170
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(pos, 0.0, 1.0);
|
|
171
|
+
out.color = in.color;
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@fragment
|
|
176
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
177
|
+
return in.color;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
`,Tl="bgra8unorm",Il=.01,Pl=.2,Ui=32,Tr=Ui/4,Ir=e=>Math.min(1,Math.max(0,e)),Al=e=>pt(e)??[0,0,0,1],ns=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},Rl=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e},El=e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null},is=e=>{if(typeof e!="string")return"";const t=e.trim();return t.length>0?t:""},Dl=e=>Array.isArray(e),Pr=e=>Dl(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Bl=e=>{const t=e.devicePixelRatio;if(!(t>0))return null;const n=e.canvasWidth/t,i=e.canvasHeight/t,r=n-e.left-e.right,o=i-e.top-e.bottom;return!(r>0)||!(o>0)?null:{plotWidthCss:r,plotHeightCss:o}},Ll=e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:s,devicePixelRatio:a}=e,c=t*a,u=o-n*a,p=i*a,h=s-r*a,l=c/o*2-1,m=u/o*2-1,C=1-p/s*2,F=1-h/s*2;return{left:l,right:m,top:C,bottom:F}},kl=(e,t,n,i)=>{if(Number.isFinite(t)&&t>0){const a=e.scale(0),c=e.scale(0+t),u=Math.abs(c-a);if(Number.isFinite(u)&&u>0)return u}const r=Math.abs(n.right-n.left);if(!(r>0))return 0;const o=Math.max(1,Math.floor(i));return r/o};function Ul(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??Tl,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),o=nt(e,64,{label:"barRenderer/vsUniforms"});Qe(e,o,Rl());const s=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}}]}),a=Tt(e,{label:"barRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:ts,label:"bar.wgsl",buffers:[{arrayStride:Ui,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x4",offset:0},{shaderLocation:1,format:"float32x4",offset:16}]}]},fragment:{code:ts,label:"bar.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let c=null,u=0,p=new ArrayBuffer(0),h=new Float32Array(p);const l=[],m=()=>{if(n)throw new Error("BarRenderer is disposed.")},C=g=>{if(g<=h.length)return;const v=Math.max(8,ns(g));p=new ArrayBuffer(v*4),h=new Float32Array(p)},F=g=>{l.length=0;for(let M=0;M<g.length;M++){const I=g[M].data;for(let T=0;T<I.length;T++){const{x:E}=Pr(I[T]);Number.isFinite(E)&&l.push(E)}}if(l.length<2)return 1;l.sort((M,I)=>M-I);let v=Number.POSITIVE_INFINITY;for(let M=1;M<l.length;M++){const I=l[M]-l[M-1];I>0&&I<v&&(v=I)}return Number.isFinite(v)&&v>0?v:1},R=g=>{let v,M,I;for(let T=0;T<g.length;T++){const E=g[T];v===void 0&&E.barWidth!==void 0&&(v=E.barWidth),M===void 0&&E.barGap!==void 0&&(M=E.barGap),I===void 0&&E.barCategoryGap!==void 0&&(I=E.barCategoryGap)}return{barWidth:v,barGap:M,barCategoryGap:I}},S=g=>{let v=Number.POSITIVE_INFINITY,M=Number.NEGATIVE_INFINITY;for(let I=0;I<g.length;I++){const T=g[I].data;for(let E=0;E<T.length;E++){const{y:f}=Pr(T[E]);Number.isFinite(f)&&(f<v&&(v=f),f>M&&(M=f))}}return!Number.isFinite(v)||!Number.isFinite(M)||v<=0&&0<=M?0:Math.abs(v)<Math.abs(M)?v:M},y=(g,v,M)=>{const I=v.invert(M.bottom),T=v.invert(M.top),E=Math.min(I,T),f=Math.max(I,T);return!Number.isFinite(E)||!Number.isFinite(f)?S(g):E<=0&&0<=f?0:E>0?E:f<0?f:S(g)};return{prepare:(g,v,M,I,T)=>{if(m(),g.length===0){u=0;return}const E=Bl(T);if(!E){u=0;return}const f=Ll(T),x=f.right-f.left,N=E.plotWidthCss>0?x/E.plotWidthCss:0,A=new Map,P=new Array(g.length);let L=0;for(let le=0;le<g.length;le++){const me=is(g[le].stack);if(me!==""){const ge=A.get(me);if(ge!==void 0)P[le]=ge;else{const we=L++;A.set(me,we),P[le]=we}}else P[le]=L++}L=Math.max(1,L);const B=F(g),V=R(g),_=Ir(V.barGap??Il),re=Ir(V.barCategoryGap??Pl);let Y=1;for(let le=0;le<g.length;le++){const me=g[le].data.length;Y=Math.max(Y,Math.floor(me))}const W=kl(M,B,f,Y),Z=Math.max(0,W*(1-re)),oe=L+Math.max(0,L-1)*_,ee=oe>0?Z/oe:0;let q=0;const de=V.barWidth;if(typeof de=="number")q=Math.max(0,de)*N,q=Math.min(q,ee);else if(typeof de=="string"){const le=El(de);q=le==null?0:ee*Ir(le)}q>0||(q=ee);const G=q*_,te=L*q+Math.max(0,L-1)*G;let X=y(g,I,f),Q=I.scale(X);if(!Number.isFinite(Q)){const le=S(g);if(X=le,Q=I.scale(le),Number.isFinite(Q)||(X=0,Q=I.scale(0)),!Number.isFinite(Q)){u=0;return}}let ne=0;for(let le=0;le<g.length;le++)ne+=Math.max(0,g[le].data.length);C(ne*Tr);const H=h;let O=0;const se=new Map;for(let le=0;le<g.length;le++){const me=g[le],ge=me.data,[we,it,Ke,et]=Al(me.color),ke=is(me.stack),he=P[le]??0;for(let be=0;be<ge.length;be++){const{x:Ge,y:ze}=Pr(ge[be]),rt=M.scale(Ge);if(!Number.isFinite(rt)||!Number.isFinite(ze))continue;const Ze=rt-te/2+he*(q+G);let ht=Q,gt=0;if(ke!==""){let ot=se.get(ke);ot||(ot=new Map,se.set(ke,ot));let Ft;Number.isFinite(W)&&W>0&&Number.isFinite(rt)?Ft=Math.round((rt-f.left)/W):Number.isFinite(B)&&B>0?Ft=Math.round(Ge/B):Ft=Math.round(Ge*1e6);let It=ot.get(Ft);It||(It={posSum:X,negSum:X},ot.set(Ft,It));let Bt,Lt;ze>=0?(Bt=It.posSum,Lt=Bt+ze,It.posSum=Lt):(Bt=It.negSum,Lt=Bt+ze,It.negSum=Lt);const k=I.scale(Bt),j=I.scale(Lt);if(!Number.isFinite(k)||!Number.isFinite(j))continue;ht=k,gt=j-k}else{const ot=I.scale(ze);if(!Number.isFinite(ot))continue;gt=ot-Q}H[O+0]=Ze,H[O+1]=ht,H[O+2]=q,H[O+3]=gt,H[O+4]=we,H[O+5]=it,H[O+6]=Ke,H[O+7]=et,O+=Tr}}u=O/Tr;const ce=Math.max(4,u*Ui);if(!c||c.size<ce){const le=Math.max(Math.max(4,ns(ce)),c?c.size:0);if(c)try{c.destroy()}catch{}c=e.createBuffer({label:"barRenderer/instanceBuffer",size:le,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}u>0&&e.queue.writeBuffer(c,0,p,0,u*Ui)},render:g=>{m(),!(!c||u===0)&&(g.setPipeline(a),g.setBindGroup(0,s),g.setVertexBuffer(0,c),g.draw(6,u))},dispose:()=>{if(!n){if(n=!0,c)try{c.destroy()}catch{}c=null,u=0;try{o.destroy()}catch{}}}}}const rs=`// scatter.wgsl
|
|
181
|
+
// Instanced anti-aliased circle shader (SDF):
|
|
182
|
+
// - Per-instance vertex input:
|
|
183
|
+
// - center = vec2<f32> point center (transformed by VSUniforms.transform)
|
|
184
|
+
// - radiusPx = f32 circle radius in pixels
|
|
185
|
+
// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS
|
|
186
|
+
// - Uniforms:
|
|
187
|
+
// - @group(0) @binding(0): VSUniforms { transform, viewportPx }
|
|
188
|
+
// - @group(0) @binding(1): FSUniforms { color }
|
|
189
|
+
//
|
|
190
|
+
// Notes:
|
|
191
|
+
// - \`viewportPx\` is the current render target size in pixels (width, height).
|
|
192
|
+
// - The quad is expanded in clip space using \`radiusPx\` and \`viewportPx\`.
|
|
193
|
+
|
|
194
|
+
struct VSUniforms {
|
|
195
|
+
transform: mat4x4<f32>,
|
|
196
|
+
viewportPx: vec2<f32>,
|
|
197
|
+
// Pad to 16-byte alignment (mat4x4 is 64B; vec2 adds 8B; pad to 80B).
|
|
198
|
+
_pad0: vec2<f32>,
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
202
|
+
|
|
203
|
+
struct FSUniforms {
|
|
204
|
+
color: vec4<f32>,
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
208
|
+
|
|
209
|
+
struct VSIn {
|
|
210
|
+
@location(0) center: vec2<f32>,
|
|
211
|
+
@location(1) radiusPx: f32,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
struct VSOut {
|
|
215
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
216
|
+
@location(0) localPx: vec2<f32>,
|
|
217
|
+
@location(1) radiusPx: f32,
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
@vertex
|
|
221
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
222
|
+
// Fixed local corners for 2 triangles (triangle-list).
|
|
223
|
+
// \`localNdc\` is a quad in [-1, 1]^2; we convert it to pixel offsets via radiusPx.
|
|
224
|
+
let localNdc = array<vec2<f32>, 6>(
|
|
225
|
+
vec2<f32>(-1.0, -1.0),
|
|
226
|
+
vec2<f32>( 1.0, -1.0),
|
|
227
|
+
vec2<f32>(-1.0, 1.0),
|
|
228
|
+
vec2<f32>(-1.0, 1.0),
|
|
229
|
+
vec2<f32>( 1.0, -1.0),
|
|
230
|
+
vec2<f32>( 1.0, 1.0)
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
let corner = localNdc[vertexIndex];
|
|
234
|
+
let localPx = corner * in.radiusPx;
|
|
235
|
+
|
|
236
|
+
// Convert pixel offset to clip-space offset.
|
|
237
|
+
// Clip space spans [-1, 1] across the viewport, so px -> clip is (2 / viewportPx).
|
|
238
|
+
let localClip = localPx * (2.0 / vsUniforms.viewportPx);
|
|
239
|
+
|
|
240
|
+
let centerClip = (vsUniforms.transform * vec4<f32>(in.center, 0.0, 1.0)).xy;
|
|
241
|
+
|
|
242
|
+
var out: VSOut;
|
|
243
|
+
out.clipPosition = vec4<f32>(centerClip + localClip, 0.0, 1.0);
|
|
244
|
+
out.localPx = localPx;
|
|
245
|
+
out.radiusPx = in.radiusPx;
|
|
246
|
+
return out;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
@fragment
|
|
250
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
251
|
+
// Signed distance to the circle boundary (negative inside).
|
|
252
|
+
let dist = length(in.localPx) - in.radiusPx;
|
|
253
|
+
|
|
254
|
+
// Analytic-ish AA: smooth edge based on derivative of dist in screen space.
|
|
255
|
+
let w = fwidth(dist);
|
|
256
|
+
let a = 1.0 - smoothstep(0.0, w, dist);
|
|
257
|
+
|
|
258
|
+
// Discard fully outside to avoid unnecessary blending work.
|
|
259
|
+
if (a <= 0.0) {
|
|
260
|
+
discard;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return vec4<f32>(fsUniforms.color.rgb, fsUniforms.color.a * a);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
`,_l="bgra8unorm",Ar=4,_i=16,Rr=_i/4,Gl=e=>Math.min(1,Math.max(0,e)),Ci=(e,t,n)=>Math.min(n,Math.max(t,e|0)),zl=e=>pt(e)??[0,0,0,1],os=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},oo=e=>Array.isArray(e),sa=e=>oo(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Vl=e=>{if(oo(e)){const n=e[2];return typeof n=="number"&&Number.isFinite(n)?n:null}const t=e.size;return typeof t=="number"&&Number.isFinite(t)?t:null},Ol=e=>oo(e)?e:[e.x,e.y,e.size],$l=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(let o=0;o<e.length;o++){const{x:s,y:a}=sa(e[o]);!Number.isFinite(s)||!Number.isFinite(a)||(s<t&&(t=s),s>n&&(n=s),a<i&&(i=a),a>r&&(r=a))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?{xMin:0,xMax:1,yMin:0,yMax:1}:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})},ss=(e,t,n)=>{const i=e.scale(t),r=e.scale(n);if(!Number.isFinite(t)||!Number.isFinite(n)||t===n||!Number.isFinite(i)||!Number.isFinite(r))return{a:0,b:Number.isFinite(i)?i:0};const o=(r-i)/(n-t),s=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(s)?s:0}},Wl=(e,t,n,i,r)=>{e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=n,e[13]=r,e[14]=0,e[15]=1},Xl=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=Ci(Math.floor(r),0,Math.max(0,t)),u=Ci(Math.floor(s),0,Math.max(0,n)),p=Ci(Math.ceil(o),0,Math.max(0,t)),h=Ci(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}};function Yl(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??_l,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),o=nt(e,80,{label:"scatterRenderer/vsUniforms"}),s=nt(e,16,{label:"scatterRenderer/fsUniforms"}),a=new ArrayBuffer(80),c=new Float32Array(a),u=new Float32Array(4),p=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}},{binding:1,resource:{buffer:s}}]}),h=Tt(e,{label:"scatterRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:rs,label:"scatter.wgsl",buffers:[{arrayStride:_i,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32",offset:8}]}]},fragment:{code:rs,label:"scatter.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let l=null,m=0,C=new ArrayBuffer(0),F=new Float32Array(C),R=0,S=0,y=[1,1],b=null;const w=()=>{if(n)throw new Error("ScatterRenderer is disposed.")},d=T=>{if(T<=F.length)return;const E=Math.max(8,os(T));C=new ArrayBuffer(E*4),F=new Float32Array(C)},g=(T,E,f,x,N,A)=>{const P=Number.isFinite(N)&&N>0?N:1,L=Number.isFinite(A)&&A>0?A:1;Wl(c,T,E,f,x),c[16]=P,c[17]=L,c[18]=0,c[19]=0,Qe(e,o,a),y=[P,L]};return{prepare:(T,E,f,x,N)=>{w();const{xMin:A,xMax:P,yMin:L,yMax:B}=$l(E),{a:V,b:_}=ss(f,A,P),{a:re,b:Y}=ss(x,L,B);N?(R=N.canvasWidth,S=N.canvasHeight,g(V,_,re,Y,N.canvasWidth,N.canvasHeight),b=Xl(N)):(g(V,_,re,Y,y[0],y[1]),b=null);const[W,Z,oe,ee]=zl(T.color);u[0]=W,u[1]=Z,u[2]=oe,u[3]=Gl(ee),Qe(e,s,u);const q=(N==null?void 0:N.devicePixelRatio)??1,de=q>0&&Number.isFinite(q),G=T.symbolSize,te=typeof G=="function"?H=>{const O=G(Ol(H));return typeof O=="number"&&Number.isFinite(O)?O:Ar}:typeof G=="number"&&Number.isFinite(G)?()=>G:()=>Ar;d(E.length*Rr);const X=F;let Q=0;for(let H=0;H<E.length;H++){const O=E[H],{x:se,y:ce}=sa(O);if(!Number.isFinite(se)||!Number.isFinite(ce))continue;const le=Vl(O)??te(O),me=Number.isFinite(le)?Math.max(0,le):Ar,ge=de?me*q:me;ge>0&&(X[Q+0]=se,X[Q+1]=ce,X[Q+2]=ge,X[Q+3]=0,Q+=Rr)}m=Q/Rr;const ne=Math.max(4,m*_i);if(!l||l.size<ne){const H=Math.max(Math.max(4,os(ne)),l?l.size:0);if(l)try{l.destroy()}catch{}l=e.createBuffer({label:"scatterRenderer/instanceBuffer",size:H,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}l&&m>0&&e.queue.writeBuffer(l,0,C,0,m*_i)},render:T=>{w(),!(!l||m===0)&&(b&&R>0&&S>0&&T.setScissorRect(b.x,b.y,b.w,b.h),T.setPipeline(h),T.setBindGroup(0,p),T.setVertexBuffer(0,l),T.draw(6,m),b&&R>0&&S>0&&T.setScissorRect(0,0,R,S))},dispose:()=>{if(!n){if(n=!0,l)try{l.destroy()}catch{}l=null,m=0;try{o.destroy()}catch{}try{s.destroy()}catch{}R=0,S=0,y=[1,1],b=null}}}}const Hl=`struct ComputeUniforms {
|
|
267
|
+
transform: mat4x4<f32>,
|
|
268
|
+
viewportPx: vec2f,
|
|
269
|
+
_pad0: vec2f,
|
|
270
|
+
plotOriginPx: vec2<u32>,
|
|
271
|
+
plotSizePx: vec2<u32>,
|
|
272
|
+
binSizePx: u32,
|
|
273
|
+
binCountX: u32,
|
|
274
|
+
binCountY: u32,
|
|
275
|
+
visibleStart: u32,
|
|
276
|
+
visibleEnd: u32,
|
|
277
|
+
normalization: u32,
|
|
278
|
+
_pad1: vec2<u32>,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
@group(0) @binding(0) var<uniform> u: ComputeUniforms;
|
|
282
|
+
@group(0) @binding(1) var<storage, read> points: array<vec2f>;
|
|
283
|
+
@group(0) @binding(2) var<storage, read_write> bins: array<atomic<u32>>;
|
|
284
|
+
|
|
285
|
+
struct MaxBuffer {
|
|
286
|
+
value: atomic<u32>,
|
|
287
|
+
};
|
|
288
|
+
@group(0) @binding(3) var<storage, read_write> maxBuf: MaxBuffer;
|
|
289
|
+
|
|
290
|
+
fn clipToDevicePx(clip: vec2f) -> vec2f {
|
|
291
|
+
// clip in [-1,1] -> device pixel in [0, viewport]
|
|
292
|
+
return vec2f(
|
|
293
|
+
(clip.x * 0.5 + 0.5) * u.viewportPx.x,
|
|
294
|
+
(-clip.y * 0.5 + 0.5) * u.viewportPx.y
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
@compute @workgroup_size(256)
|
|
299
|
+
fn binPoints(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
300
|
+
let idx = u.visibleStart + gid.x;
|
|
301
|
+
if (idx >= u.visibleEnd) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
let p = points[idx];
|
|
306
|
+
let clip4 = u.transform * vec4f(p.x, p.y, 0.0, 1.0);
|
|
307
|
+
let clip = clip4.xy / max(1e-9, clip4.w);
|
|
308
|
+
let px = clipToDevicePx(clip);
|
|
309
|
+
|
|
310
|
+
// Scissor bounds in device px
|
|
311
|
+
let left = f32(u.plotOriginPx.x);
|
|
312
|
+
let top = f32(u.plotOriginPx.y);
|
|
313
|
+
let right = left + f32(u.plotSizePx.x);
|
|
314
|
+
let bottom = top + f32(u.plotSizePx.y);
|
|
315
|
+
|
|
316
|
+
if (px.x < left || px.x >= right || px.y < top || px.y >= bottom) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
let localX = u32((px.x - left) / f32(u.binSizePx));
|
|
321
|
+
let localY = u32((px.y - top) / f32(u.binSizePx));
|
|
322
|
+
if (localX >= u.binCountX || localY >= u.binCountY) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let binIndex = localY * u.binCountX + localX;
|
|
327
|
+
atomicAdd(&bins[binIndex], 1u);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
@compute @workgroup_size(256)
|
|
331
|
+
fn reduceMax(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
332
|
+
let binTotal = u.binCountX * u.binCountY;
|
|
333
|
+
let i = gid.x;
|
|
334
|
+
if (i >= binTotal) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
let v = atomicLoad(&bins[i]);
|
|
339
|
+
atomicMax(&maxBuf.value, v);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
`,as=`struct RenderUniforms {
|
|
343
|
+
plotOriginPx: vec2<u32>,
|
|
344
|
+
plotSizePx: vec2<u32>,
|
|
345
|
+
binSizePx: u32,
|
|
346
|
+
binCountX: u32,
|
|
347
|
+
binCountY: u32,
|
|
348
|
+
normalization: u32,
|
|
349
|
+
_pad: vec2<u32>,
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
@group(0) @binding(0) var<uniform> u: RenderUniforms;
|
|
353
|
+
@group(0) @binding(1) var<storage, read> bins: array<u32>;
|
|
354
|
+
@group(0) @binding(2) var<storage, read> maxBuf: array<u32>;
|
|
355
|
+
@group(0) @binding(3) var lutTex: texture_2d<f32>;
|
|
356
|
+
|
|
357
|
+
struct VsOut {
|
|
358
|
+
@builtin(position) position: vec4f,
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
@vertex
|
|
362
|
+
fn vsMain(@builtin(vertex_index) vid: u32) -> VsOut {
|
|
363
|
+
// Fullscreen triangle (covers clip space).
|
|
364
|
+
// (0,0)->(-1,-1), (2,0)->(3,-1), (0,2)->(-1,3)
|
|
365
|
+
var pos = array<vec2f, 3>(
|
|
366
|
+
vec2f(-1.0, -1.0),
|
|
367
|
+
vec2f(3.0, -1.0),
|
|
368
|
+
vec2f(-1.0, 3.0)
|
|
369
|
+
);
|
|
370
|
+
var out: VsOut;
|
|
371
|
+
out.position = vec4f(pos[vid], 0.0, 1.0);
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
fn applyNormalization(count: f32, maxCount: f32, mode: u32) -> f32 {
|
|
376
|
+
if (maxCount <= 0.0) {
|
|
377
|
+
return 0.0;
|
|
378
|
+
}
|
|
379
|
+
let t = clamp(count / maxCount, 0.0, 1.0);
|
|
380
|
+
if (mode == 1u) { // sqrt
|
|
381
|
+
return sqrt(t);
|
|
382
|
+
}
|
|
383
|
+
if (mode == 2u) { // log
|
|
384
|
+
// log1p(count) / log1p(max)
|
|
385
|
+
return clamp(log(1.0 + count) / max(1e-9, log(1.0 + maxCount)), 0.0, 1.0);
|
|
386
|
+
}
|
|
387
|
+
return t; // linear
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
@fragment
|
|
391
|
+
fn fsMain(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
392
|
+
// pos.xy is framebuffer pixel coords (device px) with origin top-left.
|
|
393
|
+
let x = pos.x;
|
|
394
|
+
let y = pos.y;
|
|
395
|
+
|
|
396
|
+
let left = f32(u.plotOriginPx.x);
|
|
397
|
+
let top = f32(u.plotOriginPx.y);
|
|
398
|
+
// plot scissor also applied on CPU; keep a guard anyway.
|
|
399
|
+
if (x < left || y < top) {
|
|
400
|
+
return vec4f(0.0);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
let localX = u32((x - left) / f32(u.binSizePx));
|
|
404
|
+
let localY = u32((y - top) / f32(u.binSizePx));
|
|
405
|
+
if (localX >= u.binCountX || localY >= u.binCountY) {
|
|
406
|
+
return vec4f(0.0);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
let idx = localY * u.binCountX + localX;
|
|
410
|
+
let c = f32(bins[idx]);
|
|
411
|
+
let maxC = f32(maxBuf[0]);
|
|
412
|
+
|
|
413
|
+
let t = applyNormalization(c, maxC, u.normalization);
|
|
414
|
+
let lutX = i32(round(t * 255.0));
|
|
415
|
+
let lut = textureLoad(lutTex, vec2<i32>(lutX, 0), 0);
|
|
416
|
+
return vec4f(lut.rgb, 1.0);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
`,ql="bgra8unorm",Mi=e=>Math.min(1,Math.max(0,e)),hn=(e,t,n)=>Math.min(n,Math.max(t,e|0)),Zl=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},cs=(e,t,n)=>{const i=e.scale(t),r=e.scale(n);if(!Number.isFinite(t)||!Number.isFinite(n)||t===n||!Number.isFinite(i)||!Number.isFinite(r))return{a:0,b:Number.isFinite(i)?i:0};const o=(r-i)/(n-t),s=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(s)?s:0}},jl=(e,t,n,i,r)=>{e[0]=t,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=n,e[13]=r,e[14]=0,e[15]=1},Kl=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=hn(Math.floor(r),0,Math.max(0,t)),u=hn(Math.floor(s),0,Math.max(0,n)),p=hn(Math.ceil(o),0,Math.max(0,t)),h=hn(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},Fi=(e,t,n)=>e+(t-e)*n,Jl=(e,t,n)=>[Fi(e[0],t[0],n),Fi(e[1],t[1],n),Fi(e[2],t[2],n),Fi(e[3],t[3],n)],Ql=e=>pt(e)??[0,0,0,1],ls=e=>e==="plasma"?["#0d0887","#6a00a8","#b12a90","#e16462","#fca636","#f0f921"]:e==="inferno"?["#000004","#420a68","#932667","#dd513a","#fca50a","#fcffa4"]:["#440154","#3b528b","#21918c","#5ec962","#fde725"],eu=e=>{const n=(typeof e=="string"?ls(e):Array.isArray(e)&&e.length>0?e:ls("viridis")).map(Ql),i=Math.max(2,n.length),r=new Uint8Array(new ArrayBuffer(256*4));for(let o=0;o<256;o++){const a=o/255*(i-1),c=Math.min(i-2,Math.max(0,Math.floor(a))),u=a-c,p=Jl(n[c],n[c+1],u);r[o*4+0]=hn(Math.round(Mi(p[0])*255),0,255),r[o*4+1]=hn(Math.round(Mi(p[1])*255),0,255),r[o*4+2]=hn(Math.round(Mi(p[2])*255),0,255),r[o*4+3]=hn(Math.round(Mi(p[3])*255),0,255)}return r},tu=e=>{if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return"custom"}},nu=e=>e==="sqrt"?1:e==="log"?2:0;function iu(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??ql,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}}]}),o=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float"}}]}),s=nt(e,128,{label:"scatterDensity/computeUniforms"}),a=new ArrayBuffer(128),c=new Float32Array(a,0,20),u=new Uint32Array(a),p=nt(e,48,{label:"scatterDensity/renderUniforms"}),h=new ArrayBuffer(48),l=new Uint32Array(h),m=ra(e,Hl,"scatterDensityBinning.wgsl"),C=e.createComputePipeline({label:"scatterDensity/binPointsPipeline",layout:e.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:m,entryPoint:"binPoints"}}),F=e.createComputePipeline({label:"scatterDensity/reduceMaxPipeline",layout:e.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:m,entryPoint:"reduceMax"}}),R=Tt(e,{label:"scatterDensity/renderPipeline",bindGroupLayouts:[o],vertex:{code:as,label:"scatterDensityColormap.wgsl"},fragment:{code:as,label:"scatterDensityColormap.wgsl",formats:i,blend:void 0},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let S=null,y=null,b=0,w=null,d=null,g="",v=null,M=null,I=null,T=-1,E=0,f=0,x=0,N=0,A=0,P=null,L=0,B=0,V=2,_=!0,re=!1,Y=new Uint32Array(0);const W=()=>{if(n)throw new Error("ScatterDensityRenderer is disposed.")},Z=X=>{const Q=tu(X.densityColormap);if(w||(w=e.createTexture({label:"scatterDensity/lutTexture",size:{width:256,height:1,depthOrArrayLayers:1},format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),d=w.createView(),g=""),Q===g)return;const ne=eu(X.densityColormap);e.queue.writeTexture({texture:w},ne,{bytesPerRow:256*4,rowsPerImage:1},{width:256,height:1,depthOrArrayLayers:1}),g=Q},oe=(X,Q)=>{const ne=Math.max(1,X|0)*Math.max(1,Q|0);if(S&&y&&ne<=b)return;const H=Math.max(1,ne);if(b=Math.max(256,Zl(H)),S){try{S.destroy()}catch{}S=null}if(y){try{y.destroy()}catch{}y=null}S=e.createBuffer({label:"scatterDensity/binsBuffer",size:b*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),y=e.createBuffer({label:"scatterDensity/maxBuffer",size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),Y=new Uint32Array(b),v=null,M=null,_=!0},ee=()=>{!S||!y||!d||!I||(v||(v=e.createBindGroup({label:"scatterDensity/computeBindGroup",layout:r,entries:[{binding:0,resource:{buffer:s}},{binding:1,resource:{buffer:I}},{binding:2,resource:{buffer:S}},{binding:3,resource:{buffer:y}}]})),M||(M=e.createBindGroup({label:"scatterDensity/renderBindGroup",layout:o,entries:[{binding:0,resource:{buffer:p}},{binding:1,resource:{buffer:S}},{binding:2,resource:{buffer:y}},{binding:3,resource:d}]})))};return{prepare:(X,Q,ne,H,O,se,ce,le,me)=>{W(),re=!0;const ge=Kl(le),we=le.devicePixelRatio,it=Number.isFinite(X.binSize)?Math.max(1e-6,X.binSize):2,Ke=Math.max(1,Math.round(it*(Number.isFinite(we)&&we>0?we:1))),et=Math.max(1,Math.ceil(ge.w/Ke)),ke=Math.max(1,Math.ceil(ge.h/Ke));oe(et,ke),Z(X);const he=nu(X.densityNormalization);I!==Q&&(I=Q,v=null,M=null,_=!0),T!==ne&&(T=ne,_=!0),(E!==H||f!==O)&&(E=H,f=O,_=!0),(x!==Ke||N!==et||A!==ke)&&(x=Ke,N=et,A=ke,_=!0),(!P||P.x!==ge.x||P.y!==ge.y||P.w!==ge.w||P.h!==ge.h)&&(P=ge,_=!0),(L!==le.canvasWidth||B!==le.canvasHeight)&&(L=le.canvasWidth,B=le.canvasHeight,_=!0),V!==he&&(V=he,_=!0);const be=me,Ge=(be==null?void 0:be.xMin)??0,ze=(be==null?void 0:be.xMax)??1,rt=(be==null?void 0:be.yMin)??0,Ze=(be==null?void 0:be.yMax)??1,{a:ht,b:gt}=cs(se,Ge,ze),{a:ot,b:Ft}=cs(ce,rt,Ze);jl(c,ht,gt,ot,Ft),c[16]=le.canvasWidth>0?le.canvasWidth:1,c[17]=le.canvasHeight>0?le.canvasHeight:1,c[18]=0,c[19]=0,u[20]=ge.x>>>0,u[21]=ge.y>>>0,u[22]=ge.w>>>0,u[23]=ge.h>>>0,u[24]=Ke>>>0,u[25]=et>>>0,u[26]=ke>>>0,u[27]=(Math.max(0,H)|0)>>>0,u[28]=(Math.max(0,O)|0)>>>0,u[29]=he>>>0,Qe(e,s,a),l[0]=ge.x>>>0,l[1]=ge.y>>>0,l[2]=ge.w>>>0,l[3]=ge.h>>>0,l[4]=Ke>>>0,l[5]=et>>>0,l[6]=ke>>>0,l[7]=he>>>0,Qe(e,p,h),ee()},encodeCompute:X=>{if(W(),!re||!_)return;if(!S||!y||!v||T<=0){_=!1;return}if(!P||P.w<=0||P.h<=0){_=!1;return}e.queue.writeBuffer(S,0,Y.buffer,0,b*4),e.queue.writeBuffer(y,0,new Uint32Array([0]).buffer);const Q=N*A|0,ne=Math.max(0,f-E|0),H=X.beginComputePass({label:"scatterDensity/computePass"});H.setBindGroup(0,v),H.setPipeline(C);const O=256,se=Math.ceil(ne/O);se>0&&H.dispatchWorkgroups(se),H.setPipeline(F);const ce=Math.ceil(Q/O);ce>0&&H.dispatchWorkgroups(ce),H.end(),_=!1},render:X=>{W(),re&&(!M||!P||!d||P.w<=0||P.h<=0||(X.setScissorRect(P.x,P.y,P.w,P.h),X.setPipeline(R),X.setBindGroup(0,M),X.draw(3),L>0&&B>0&&X.setScissorRect(0,0,L,B)))},dispose:()=>{if(!n){n=!0;try{s.destroy()}catch{}try{p.destroy()}catch{}if(S)try{S.destroy()}catch{}if(y)try{y.destroy()}catch{}if(S=null,y=null,b=0,w)try{w.destroy()}catch{}w=null,d=null,v=null,M=null,I=null}}}}const us=`// pie.wgsl
|
|
420
|
+
// Instanced anti-aliased pie-slice shader (instanced quad + SDF mask).
|
|
421
|
+
//
|
|
422
|
+
// - Per-instance vertex input:
|
|
423
|
+
// - center = vec2<f32> slice center (transformed by VSUniforms.transform)
|
|
424
|
+
// - startAngleRad = f32 start angle in radians
|
|
425
|
+
// - endAngleRad = f32 end angle in radians
|
|
426
|
+
// - radiiPx = vec2<f32>(innerRadiusPx, outerRadiusPx) in *device pixels*
|
|
427
|
+
// - color = vec4<f32> RGBA color in [0..1]
|
|
428
|
+
//
|
|
429
|
+
// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS
|
|
430
|
+
//
|
|
431
|
+
// - Uniforms:
|
|
432
|
+
// - @group(0) @binding(0): VSUniforms { transform, viewportPx }
|
|
433
|
+
//
|
|
434
|
+
// Notes:
|
|
435
|
+
// - The quad is expanded in clip space using \`radiusPx\` and \`viewportPx\`.
|
|
436
|
+
// - Fragment uses an SDF mask for the circle boundary + an angular wedge mask.
|
|
437
|
+
// - Fully outside fragments are discarded to avoid unnecessary blending work.
|
|
438
|
+
//
|
|
439
|
+
// Conventions: matches other shaders in this repo (vsMain/fsMain, group 0 bindings,
|
|
440
|
+
// and explicit uniform padding/alignment where needed).
|
|
441
|
+
|
|
442
|
+
const PI: f32 = 3.141592653589793;
|
|
443
|
+
const TAU: f32 = 6.283185307179586; // 2*pi
|
|
444
|
+
|
|
445
|
+
struct VSUniforms {
|
|
446
|
+
transform: mat4x4<f32>,
|
|
447
|
+
viewportPx: vec2<f32>,
|
|
448
|
+
// Pad to 16-byte alignment (mat4x4 is 64B; vec2 adds 8B; pad to 80B).
|
|
449
|
+
_pad0: vec2<f32>,
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
453
|
+
|
|
454
|
+
struct VSIn {
|
|
455
|
+
@location(0) center: vec2<f32>,
|
|
456
|
+
@location(1) startAngleRad: f32,
|
|
457
|
+
@location(2) endAngleRad: f32,
|
|
458
|
+
@location(3) radiiPx: vec2<f32>, // (innerPx, outerPx)
|
|
459
|
+
@location(4) color: vec4<f32>,
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
struct VSOut {
|
|
463
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
464
|
+
@location(0) localPx: vec2<f32>,
|
|
465
|
+
@location(1) startAngleRad: f32,
|
|
466
|
+
@location(2) endAngleRad: f32,
|
|
467
|
+
@location(3) radiiPx: vec2<f32>,
|
|
468
|
+
@location(4) color: vec4<f32>,
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
@vertex
|
|
472
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
473
|
+
// Fixed local corners for 2 triangles (triangle-list).
|
|
474
|
+
// \`localNdc\` is a quad in [-1, 1]^2; we convert it to pixel offsets via radiusPx.
|
|
475
|
+
let localNdc = array<vec2<f32>, 6>(
|
|
476
|
+
vec2<f32>(-1.0, -1.0),
|
|
477
|
+
vec2<f32>( 1.0, -1.0),
|
|
478
|
+
vec2<f32>(-1.0, 1.0),
|
|
479
|
+
vec2<f32>(-1.0, 1.0),
|
|
480
|
+
vec2<f32>( 1.0, -1.0),
|
|
481
|
+
vec2<f32>( 1.0, 1.0)
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
let corner = localNdc[vertexIndex];
|
|
485
|
+
let outerPx = in.radiiPx.y;
|
|
486
|
+
let localPx = corner * outerPx;
|
|
487
|
+
|
|
488
|
+
// Convert pixel offset to clip-space offset.
|
|
489
|
+
// Clip space spans [-1, 1] across the viewport, so px -> clip is (2 / viewportPx).
|
|
490
|
+
let localClip = localPx * (2.0 / vsUniforms.viewportPx);
|
|
491
|
+
|
|
492
|
+
let centerClip = (vsUniforms.transform * vec4<f32>(in.center, 0.0, 1.0)).xy;
|
|
493
|
+
|
|
494
|
+
var out: VSOut;
|
|
495
|
+
out.clipPosition = vec4<f32>(centerClip + localClip, 0.0, 1.0);
|
|
496
|
+
out.localPx = localPx;
|
|
497
|
+
out.startAngleRad = in.startAngleRad;
|
|
498
|
+
out.endAngleRad = in.endAngleRad;
|
|
499
|
+
out.radiiPx = in.radiiPx;
|
|
500
|
+
out.color = in.color;
|
|
501
|
+
return out;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
fn wrapToTau(theta: f32) -> f32 {
|
|
505
|
+
// Maps theta to [0, TAU). (Input often comes from atan2 in [-PI, PI].)
|
|
506
|
+
return select(theta, theta + TAU, theta < 0.0);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
@fragment
|
|
510
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
511
|
+
let p = in.localPx;
|
|
512
|
+
let r = length(p);
|
|
513
|
+
|
|
514
|
+
let innerPx = in.radiiPx.x;
|
|
515
|
+
let outerPx = in.radiiPx.y;
|
|
516
|
+
|
|
517
|
+
// --- Radial mask: ring between inner and outer radii (inner==0 => pie) ---
|
|
518
|
+
// Positive inside the ring, negative outside.
|
|
519
|
+
let radialDist = min(r - innerPx, outerPx - r);
|
|
520
|
+
let radialW = fwidth(radialDist);
|
|
521
|
+
let radialA = smoothstep(-radialW, radialW, radialDist);
|
|
522
|
+
|
|
523
|
+
if (radialA <= 0.0) {
|
|
524
|
+
discard;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Compute fragment angle in [0, TAU).
|
|
528
|
+
let angle = wrapToTau(atan2(p.y, p.x));
|
|
529
|
+
|
|
530
|
+
// --- Angular mask: wedge between start/end angles with wrap ---
|
|
531
|
+
let start = in.startAngleRad;
|
|
532
|
+
let end = in.endAngleRad;
|
|
533
|
+
|
|
534
|
+
// Compute span in [0, 2π) with wrap.
|
|
535
|
+
var span = end - start;
|
|
536
|
+
span = span + select(0.0, TAU, span < 0.0);
|
|
537
|
+
|
|
538
|
+
// Compute rel in [0, 2π) with wrap.
|
|
539
|
+
var rel = angle - start;
|
|
540
|
+
rel = rel + select(0.0, TAU, rel < 0.0);
|
|
541
|
+
|
|
542
|
+
let inside = rel <= span;
|
|
543
|
+
|
|
544
|
+
// Signed angular distance (in radians) to nearest boundary.
|
|
545
|
+
// - Inside: +min(rel, span-rel)
|
|
546
|
+
// - Outside: -min(rel-span, 2π-rel)
|
|
547
|
+
let dIn = min(rel, max(span - rel, 0.0));
|
|
548
|
+
let dOutA = max(rel - span, 0.0);
|
|
549
|
+
let dOutB = max(TAU - rel, 0.0);
|
|
550
|
+
let dOut = min(dOutA, dOutB);
|
|
551
|
+
|
|
552
|
+
let signedAngleDist = select(-dOut, dIn, inside);
|
|
553
|
+
|
|
554
|
+
// Convert to approximate pixel distance to the boundary ray.
|
|
555
|
+
// (For small angles, perpendicular distance to a ray ≈ r * angle.)
|
|
556
|
+
let angleDistPx = signedAngleDist * max(r, 1.0);
|
|
557
|
+
|
|
558
|
+
let angW = fwidth(angleDistPx);
|
|
559
|
+
let angularA = smoothstep(-angW, angW, angleDistPx);
|
|
560
|
+
|
|
561
|
+
let aOut = radialA * angularA;
|
|
562
|
+
if (aOut <= 0.0) {
|
|
563
|
+
discard;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
return vec4<f32>(in.color.rgb, in.color.a * aOut);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
`,ru="bgra8unorm",Gi=40,Er=Gi/4,Gn=Math.PI*2,fs=e=>Math.min(1,Math.max(0,e)),Si=(e,t,n)=>Math.min(n,Math.max(t,e|0)),ds=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},Dr=e=>{if(!Number.isFinite(e))return 0;const t=e%Gn;return t<0?t+Gn:t},ou=(e,t)=>{const n=pt(e);if(n)return[n[0],n[1],n[2],fs(n[3])];const i=pt(t);return i?[i[0],i[1],i[2],fs(i[3])]:[0,0,0,1]},si=(e,t)=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;const n=e.trim();if(n.length===0)return null;if(n.endsWith("%")){const r=Number.parseFloat(n.slice(0,-1));return Number.isFinite(r)?r/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},su=(e,t,n)=>{const i=(e==null?void 0:e[0])??"50%",r=(e==null?void 0:e[1])??"50%",o=si(i,t),s=si(r,n);return{x:Number.isFinite(o)?o:t*.5,y:Number.isFinite(s)?s:n*.5}},au=e=>Array.isArray(e),cu=(e,t)=>{if(e==null)return{inner:0,outer:t*.7};if(au(e)){const r=si(e[0],t),o=si(e[1],t),s=Math.max(0,Number.isFinite(r)?r:0),a=Math.max(s,Number.isFinite(o)?o:t*.7);return{inner:s,outer:Math.min(t,a)}}const n=si(e,t),i=Math.max(0,Number.isFinite(n)?n:t*.7);return{inner:0,outer:Math.min(t,i)}},lu=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=Si(Math.floor(r),0,Math.max(0,t)),u=Si(Math.floor(s),0,Math.max(0,n)),p=Si(Math.ceil(o),0,Math.max(0,t)),h=Si(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},uu=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);function fu(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??ru,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),o=nt(e,80,{label:"pieRenderer/vsUniforms"}),s=new ArrayBuffer(80),a=new Float32Array(s),c=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}}]}),u=Tt(e,{label:"pieRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:us,label:"pie.wgsl",buffers:[{arrayStride:Gi,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32",offset:8},{shaderLocation:2,format:"float32",offset:12},{shaderLocation:3,format:"float32x2",offset:16},{shaderLocation:4,format:"float32x4",offset:24}]}]},fragment:{code:us,label:"pie.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let p=null,h=0,l=new ArrayBuffer(0),m=new Float32Array(l),C=0,F=0,R=null;const S=()=>{if(n)throw new Error("PieRenderer is disposed.")},y=v=>{if(v<=m.length)return;const M=Math.max(8,ds(v));l=new ArrayBuffer(M*4),m=new Float32Array(l)},b=(v,M)=>{const I=Number.isFinite(v)&&v>0?v:1,T=Number.isFinite(M)&&M>0?M:1;a.set(uu,0),a[16]=I,a[17]=T,a[18]=0,a[19]=0,Qe(e,o,s)};return{prepare:(v,M)=>{S();const I=M.devicePixelRatio,T=I>0&&Number.isFinite(I)?I:1;C=M.canvasWidth,F=M.canvasHeight,b(M.canvasWidth,M.canvasHeight),R=lu(M);const E=M.canvasWidth/T,f=M.canvasHeight/T;if(!(E>0)||!(f>0)){h=0;return}const x=E-M.left-M.right,N=f-M.top-M.bottom;if(!(x>0)||!(N>0)){h=0;return}const A=.5*Math.min(x,N);if(!(A>0)){h=0;return}const P=su(v.center,x,N),L=M.left+P.x,B=M.top+P.y,V=L/E*2-1,_=1-B/f*2;if(!Number.isFinite(V)||!Number.isFinite(_)){h=0;return}const re=cu(v.radius,A),Y=Math.max(0,Math.min(re.inner,re.outer)),W=Math.max(Y,re.outer),Z=Y*T,oe=W*T;if(!(oe>0)){h=0;return}let ee=0,q=0;for(let O=0;O<v.data.length;O++){const se=v.data[O],ce=se==null?void 0:se.value;typeof ce=="number"&&Number.isFinite(ce)&&ce>0&&se.visible!==!1&&(ee+=ce,q++)}if(!(ee>0)||q===0){h=0;return}y(q*Er);const de=m,G=typeof v.startAngle=="number"&&Number.isFinite(v.startAngle)?v.startAngle:90;let te=Dr(G*Math.PI/180),X=0,Q=0,ne=0;for(let O=0;O<v.data.length;O++){const se=v.data[O],ce=se==null?void 0:se.value;if(typeof ce!="number"||!Number.isFinite(ce)||ce<=0||se.visible===!1)continue;ne++;const le=ne===q;let ge=ce/ee*Gn;if(le?ge=Math.max(0,Gn-X):ge=Math.max(0,Math.min(Gn,ge)),X+=ge,!(ge>0))continue;const we=te,it=q===1?te+Gn:Dr(te+ge);te=Dr(te+ge);const[Ke,et,ke,he]=ou(se.color,v.color);de[Q+0]=V,de[Q+1]=_,de[Q+2]=we,de[Q+3]=it,de[Q+4]=Z,de[Q+5]=oe,de[Q+6]=Ke,de[Q+7]=et,de[Q+8]=ke,de[Q+9]=he,Q+=Er}h=Q/Er;const H=Math.max(4,h*Gi);if(!p||p.size<H){const O=Math.max(Math.max(4,ds(H)),p?p.size:0);if(p)try{p.destroy()}catch{}p=e.createBuffer({label:"pieRenderer/instanceBuffer",size:O,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}p&&h>0&&e.queue.writeBuffer(p,0,l,0,h*Gi)},render:v=>{S(),!(!p||h===0)&&(R&&C>0&&F>0&&v.setScissorRect(R.x,R.y,R.w,R.h),v.setPipeline(u),v.setBindGroup(0,c),v.setVertexBuffer(0,p),v.draw(6,h),R&&C>0&&F>0&&v.setScissorRect(0,0,C,F))},dispose:()=>{if(!n){if(n=!0,p)try{p.destroy()}catch{}p=null,h=0;try{o.destroy()}catch{}C=0,F=0,R=null}}}}const ms=`// candlestick.wgsl
|
|
570
|
+
// Instanced candlestick shader (bodies + wicks):
|
|
571
|
+
// - Per-instance vertex input:
|
|
572
|
+
// - xClip, openClip, closeClip, lowClip, highClip, bodyWidthClip (6 floats)
|
|
573
|
+
// - bodyColor rgba (4 floats)
|
|
574
|
+
// - Draw call: draw(18, instanceCount) using triangle-list expansion in VS
|
|
575
|
+
// - vertices 0-5: body quad (2 triangles)
|
|
576
|
+
// - vertices 6-11: upper wick (2 triangles)
|
|
577
|
+
// - vertices 12-17: lower wick (2 triangles)
|
|
578
|
+
// - Uniforms:
|
|
579
|
+
// - @group(0) @binding(0): VSUniforms { transform, wickWidthClip }
|
|
580
|
+
|
|
581
|
+
struct VSUniforms {
|
|
582
|
+
transform: mat4x4<f32>,
|
|
583
|
+
wickWidthClip: f32,
|
|
584
|
+
_pad0: f32,
|
|
585
|
+
_pad1: f32,
|
|
586
|
+
_pad2: f32,
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
590
|
+
|
|
591
|
+
struct VSIn {
|
|
592
|
+
@location(0) xClip: f32,
|
|
593
|
+
@location(1) openClip: f32,
|
|
594
|
+
@location(2) closeClip: f32,
|
|
595
|
+
@location(3) lowClip: f32,
|
|
596
|
+
@location(4) highClip: f32,
|
|
597
|
+
@location(5) bodyWidthClip: f32,
|
|
598
|
+
@location(6) bodyColor: vec4<f32>,
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
struct VSOut {
|
|
602
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
603
|
+
@location(0) color: vec4<f32>,
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
@vertex
|
|
607
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
608
|
+
// Compute body bounds
|
|
609
|
+
let bodyTop = max(in.openClip, in.closeClip);
|
|
610
|
+
let bodyBottom = min(in.openClip, in.closeClip);
|
|
611
|
+
let bodyLeft = in.xClip - in.bodyWidthClip * 0.5;
|
|
612
|
+
let bodyRight = in.xClip + in.bodyWidthClip * 0.5;
|
|
613
|
+
|
|
614
|
+
// Wick bounds
|
|
615
|
+
let wickLeft = in.xClip - vsUniforms.wickWidthClip * 0.5;
|
|
616
|
+
let wickRight = in.xClip + vsUniforms.wickWidthClip * 0.5;
|
|
617
|
+
|
|
618
|
+
var pos: vec2<f32>;
|
|
619
|
+
|
|
620
|
+
if (vertexIndex < 6u) {
|
|
621
|
+
// Body quad (vertices 0-5)
|
|
622
|
+
let corners = array<vec2<f32>, 6>(
|
|
623
|
+
vec2<f32>(0.0, 0.0),
|
|
624
|
+
vec2<f32>(1.0, 0.0),
|
|
625
|
+
vec2<f32>(0.0, 1.0),
|
|
626
|
+
vec2<f32>(0.0, 1.0),
|
|
627
|
+
vec2<f32>(1.0, 0.0),
|
|
628
|
+
vec2<f32>(1.0, 1.0)
|
|
629
|
+
);
|
|
630
|
+
let corner = corners[vertexIndex];
|
|
631
|
+
let bodyMin = vec2<f32>(bodyLeft, bodyBottom);
|
|
632
|
+
let bodyMax = vec2<f32>(bodyRight, bodyTop);
|
|
633
|
+
pos = bodyMin + corner * (bodyMax - bodyMin);
|
|
634
|
+
} else if (vertexIndex < 12u) {
|
|
635
|
+
// Upper wick (vertices 6-11): from bodyTop to highClip
|
|
636
|
+
let idx = vertexIndex - 6u;
|
|
637
|
+
let corners = array<vec2<f32>, 6>(
|
|
638
|
+
vec2<f32>(0.0, 0.0),
|
|
639
|
+
vec2<f32>(1.0, 0.0),
|
|
640
|
+
vec2<f32>(0.0, 1.0),
|
|
641
|
+
vec2<f32>(0.0, 1.0),
|
|
642
|
+
vec2<f32>(1.0, 0.0),
|
|
643
|
+
vec2<f32>(1.0, 1.0)
|
|
644
|
+
);
|
|
645
|
+
let corner = corners[idx];
|
|
646
|
+
let wickMin = vec2<f32>(wickLeft, bodyTop);
|
|
647
|
+
let wickMax = vec2<f32>(wickRight, in.highClip);
|
|
648
|
+
pos = wickMin + corner * (wickMax - wickMin);
|
|
649
|
+
} else {
|
|
650
|
+
// Lower wick (vertices 12-17): from lowClip to bodyBottom
|
|
651
|
+
let idx = vertexIndex - 12u;
|
|
652
|
+
let corners = array<vec2<f32>, 6>(
|
|
653
|
+
vec2<f32>(0.0, 0.0),
|
|
654
|
+
vec2<f32>(1.0, 0.0),
|
|
655
|
+
vec2<f32>(0.0, 1.0),
|
|
656
|
+
vec2<f32>(0.0, 1.0),
|
|
657
|
+
vec2<f32>(1.0, 0.0),
|
|
658
|
+
vec2<f32>(1.0, 1.0)
|
|
659
|
+
);
|
|
660
|
+
let corner = corners[idx];
|
|
661
|
+
let wickMin = vec2<f32>(wickLeft, in.lowClip);
|
|
662
|
+
let wickMax = vec2<f32>(wickRight, bodyBottom);
|
|
663
|
+
pos = wickMin + corner * (wickMax - wickMin);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
var out: VSOut;
|
|
667
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(pos, 0.0, 1.0);
|
|
668
|
+
out.color = in.bodyColor;
|
|
669
|
+
return out;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
@fragment
|
|
673
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
674
|
+
return in.color;
|
|
675
|
+
}
|
|
676
|
+
`,du="bgra8unorm",mu=1,kn=40,Sn=kn/4,pu=e=>Math.min(1,Math.max(0,e)),Ni=(e,t,n)=>Math.min(n,Math.max(t,e|0)),ti=e=>pt(e)??[0,0,0,1],Ti=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},hu=e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null},yu=e=>Array.isArray(e),aa=e=>yu(e)?{timestamp:e[0],open:e[1],close:e[2],low:e[3],high:e[4]}:{timestamp:e.timestamp,open:e.open,close:e.close,low:e.low,high:e.high},gu=e=>{const t=e.devicePixelRatio;if(!(t>0))return null;const n=e.canvasWidth/t,i=e.canvasHeight/t,r=n-e.left-e.right,o=i-e.top-e.bottom;return!(r>0)||!(o>0)?null:{plotWidthCss:r,plotHeightCss:o}},xu=e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:s,devicePixelRatio:a}=e,c=t*a,u=o-n*a,p=i*a,h=s-r*a,l=c/o*2-1,m=u/o*2-1,C=1-p/s*2,F=1-h/s*2;return{left:l,right:m,top:C,bottom:F,width:m-l,height:C-F}},bu=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=Ni(Math.floor(r),0,Math.max(0,t)),u=Ni(Math.floor(s),0,Math.max(0,n)),p=Ni(Math.ceil(o),0,Math.max(0,t)),h=Ni(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},vu=e=>{const t=[];for(let i=0;i<e.length;i++){const{timestamp:r}=aa(e[i]);Number.isFinite(r)&&t.push(r)}if(t.length<2)return 1;t.sort((i,r)=>i-r);let n=Number.POSITIVE_INFINITY;for(let i=1;i<t.length;i++){const r=t[i]-t[i-1];r>0&&r<n&&(n=r)}return Number.isFinite(n)&&n>0?n:1},wu=(e,t,n,i)=>{if(Number.isFinite(t)&&t>0){const a=e.scale(0),c=e.scale(0+t),u=Math.abs(c-a);if(Number.isFinite(u)&&u>0)return u}const r=Math.abs(n.width);if(!(r>0))return 0;const o=Math.max(1,Math.floor(i));return r/o},Cu=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e};function Mu(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??du,r=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),o=nt(e,80,{label:"candlestickRenderer/vsUniforms"});Qe(e,o,Cu());const s=new ArrayBuffer(80),a=new Float32Array(s),c=e.createBindGroup({layout:r,entries:[{binding:0,resource:{buffer:o}}]}),u=Tt(e,{label:"candlestickRenderer/pipeline",bindGroupLayouts:[r],vertex:{code:ms,label:"candlestick.wgsl",buffers:[{arrayStride:kn,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32",offset:0},{shaderLocation:1,format:"float32",offset:4},{shaderLocation:2,format:"float32",offset:8},{shaderLocation:3,format:"float32",offset:12},{shaderLocation:4,format:"float32",offset:16},{shaderLocation:5,format:"float32",offset:20},{shaderLocation:6,format:"float32x4",offset:24}]}]},fragment:{code:ms,label:"candlestick.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let p=null,h=0,l=new ArrayBuffer(0),m=new Float32Array(l),C=0,F=0,R=null,S=!1,y=null,b=0,w=new ArrayBuffer(0),d=new Float32Array(w);const g=()=>{if(n)throw new Error("CandlestickRenderer is disposed.")},v=f=>{if(f<=m.length)return;const x=Math.max(8,Ti(f));l=new ArrayBuffer(x*4),m=new Float32Array(l)},M=f=>{if(f<=d.length)return;const x=Math.max(8,Ti(f));w=new ArrayBuffer(x*4),d=new Float32Array(w)};return{prepare:(f,x,N,A,P,L)=>{if(g(),x.length===0){h=0,b=0;return}const B=gu(P);if(!B){h=0,b=0;return}const V=xu(P),_=B.plotWidthCss>0?V.width/B.plotWidthCss:0;C=P.canvasWidth,F=P.canvasHeight,R=bu(P);const re=vu(x),Y=wu(N,re,V,x.length);let W=0;const Z=f.barWidth;if(typeof Z=="number")W=Math.max(0,Z)*_;else if(typeof Z=="string"){const me=hu(Z);W=me==null?0:Y*pu(me)}const oe=f.barMinWidth*_,ee=f.barMaxWidth*_;W=Math.min(Math.max(W,oe),ee);const q=f.itemStyle.borderWidth??mu,de=Math.max(0,q)*_;a.set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,de,0,0,0]),Qe(e,o,s);const G=ti(f.itemStyle.upColor),te=ti(f.itemStyle.downColor),X=ti(f.itemStyle.upBorderColor),Q=ti(f.itemStyle.downBorderColor),ne=L?ti(L):[0,0,0,1];S=f.style==="hollow",v(x.length*Sn);const H=m;let O=0;S&&M(x.length*Sn);const se=d;let ce=0;for(let me=0;me<x.length;me++){const{timestamp:ge,open:we,close:it,low:Ke,high:et}=aa(x[me]);if(!Number.isFinite(ge)||!Number.isFinite(we)||!Number.isFinite(it)||!Number.isFinite(Ke)||!Number.isFinite(et))continue;const ke=N.scale(ge),he=A.scale(we),be=A.scale(it),Ge=A.scale(Ke),ze=A.scale(et);if(!Number.isFinite(ke)||!Number.isFinite(he)||!Number.isFinite(be)||!Number.isFinite(Ge)||!Number.isFinite(ze))continue;const rt=it>we;if(S){const Ze=rt?X:Q;if(H[O+0]=ke,H[O+1]=he,H[O+2]=be,H[O+3]=Ge,H[O+4]=ze,H[O+5]=W,H[O+6]=Ze[0],H[O+7]=Ze[1],H[O+8]=Ze[2],H[O+9]=Ze[3],O+=Sn,rt){const ht=f.itemStyle.borderWidth*_,gt=Math.max(0,W-2*ht);se[ce+0]=ke,se[ce+1]=he,se[ce+2]=be,se[ce+3]=Ge,se[ce+4]=ze,se[ce+5]=gt,se[ce+6]=ne[0],se[ce+7]=ne[1],se[ce+8]=ne[2],se[ce+9]=ne[3],ce+=Sn}}else{const Ze=rt?G:te;H[O+0]=ke,H[O+1]=he,H[O+2]=be,H[O+3]=Ge,H[O+4]=ze,H[O+5]=W,H[O+6]=Ze[0],H[O+7]=Ze[1],H[O+8]=Ze[2],H[O+9]=Ze[3],O+=Sn}}h=O/Sn,b=ce/Sn;const le=Math.max(4,h*kn);if(!p||p.size<le){const me=Math.max(Math.max(4,Ti(le)),p?p.size:0);if(p)try{p.destroy()}catch{}p=e.createBuffer({label:"candlestickRenderer/instanceBuffer",size:me,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}if(h>0&&e.queue.writeBuffer(p,0,l,0,h*kn),S&&b>0){const me=Math.max(4,b*kn);if(!y||y.size<me){const ge=Math.max(Math.max(4,Ti(me)),y?y.size:0);if(y)try{y.destroy()}catch{}y=e.createBuffer({label:"candlestickRenderer/hollowInstanceBuffer",size:ge,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}e.queue.writeBuffer(y,0,w,0,b*kn)}},render:f=>{g(),!(!p||h===0)&&(R&&C>0&&F>0&&f.setScissorRect(R.x,R.y,R.w,R.h),f.setPipeline(u),f.setBindGroup(0,c),f.setVertexBuffer(0,p),f.draw(18,h),S&&y&&b>0&&(f.setVertexBuffer(0,y),f.draw(6,b)),R&&C>0&&F>0&&f.setScissorRect(0,0,C,F))},dispose:()=>{if(!n){if(n=!0,p)try{p.destroy()}catch{}if(p=null,h=0,y)try{y.destroy()}catch{}y=null,b=0;try{o.destroy()}catch{}C=0,F=0,R=null}}}}const ps=`// crosshair.wgsl
|
|
677
|
+
// Minimal crosshair line shader:
|
|
678
|
+
// - Vertex input: vec2<f32> position in clip-space coordinates
|
|
679
|
+
// - VS uniform: transform mat4 (identity)
|
|
680
|
+
// - FS uniform: solid RGBA color
|
|
681
|
+
|
|
682
|
+
struct VSUniforms {
|
|
683
|
+
transform: mat4x4<f32>,
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
687
|
+
|
|
688
|
+
struct FSUniforms {
|
|
689
|
+
color: vec4<f32>,
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
693
|
+
|
|
694
|
+
struct VSIn {
|
|
695
|
+
@location(0) position: vec2<f32>,
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
struct VSOut {
|
|
699
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
@vertex
|
|
703
|
+
fn vsMain(in: VSIn) -> VSOut {
|
|
704
|
+
var out: VSOut;
|
|
705
|
+
out.clipPosition = vsUniforms.transform * vec4<f32>(in.position, 0.0, 1.0);
|
|
706
|
+
return out;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
@fragment
|
|
710
|
+
fn fsMain() -> @location(0) vec4<f32> {
|
|
711
|
+
return fsUniforms.color;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
`,Fu=e=>e+3&-4,Su=1024,Nu=128,Tu=16384,Iu=e=>{if(e.byteOffset&3)throw new Error("createStreamBuffer.write: data.byteOffset must be 4-byte aligned.");return new Uint32Array(e.buffer,e.byteOffset,e.byteLength>>>2)};function Pu(e,t){if(!Number.isFinite(t)||t<=0)throw new Error(`createStreamBuffer(maxSize): maxSize (bytes) must be a positive number. Received: ${String(t)}`);const n=Math.max(4,Math.floor(t)),i=Fu(n),r=e.limits.maxBufferSize;if(i>r)throw new Error(`createStreamBuffer(maxSize): requested size ${i} bytes exceeds device.limits.maxBufferSize (${r}).`);const o=i>>>2,s=y=>({buffer:e.createBuffer({label:y,size:i,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),mirror:new Uint32Array(o)}),a=[s("streamBuffer/a"),s("streamBuffer/b")];let c=!1,u=0,p=0;const h=()=>{if(c)throw new Error("createStreamBuffer: StreamBuffer is disposed.")},l=(y,b,w)=>{const d=a[y],g=d.mirror;if(w<0||w>b.length)throw new Error("createStreamBuffer.write: internal error (invalid usedWords).");if(w===0)return;const v=w<<2;e.queue.writeBuffer(d.buffer,0,b.buffer,b.byteOffset,v),g.set(b.subarray(0,w),0)},m=(y,b,w)=>{const d=a[y],g=d.mirror;if(w<0||w>b.length)throw new Error("createStreamBuffer.write: internal error (invalid usedWords).");const v=w<<2;if(v>0&&v<=Su){l(y,b,w);return}const M=[];let I=0,T=0,E=0;for(;E<w;){for(;E<w&&g[E]===b[E];)E++;if(E>=w)break;const f=E;for(E++;E<w&&g[E]!==b[E];)E++;const x=E;if(M.push([f,x]),I++,T+=x-f,I>Nu||T>Tu){l(y,b,w);return}}for(let f=0;f<M.length;f++){const[x,N]=M[f],A=x<<2,P=N-x<<2;e.queue.writeBuffer(d.buffer,A,b.buffer,b.byteOffset+A,P),g.set(b.subarray(x,N),x)}};return{write:y=>{if(h(),y.length&1)throw new Error("createStreamBuffer.write: data length must be even (vec2<f32> vertices).");const b=y.byteLength;if(b>i)throw new Error(`createStreamBuffer.write: data.byteLength (${b}) exceeds capacity (${i}). Increase maxSize.`);const w=y.length>>>1;if(b===0){p=w;return}const d=Iu(y),g=1-u;m(g,d,d.length),u=g,p=w},getBuffer:()=>(h(),a[u].buffer),getVertexCount:()=>(h(),p),dispose:()=>{if(!c){c=!0,p=0;for(const y of a)try{y.buffer.destroy()}catch{}}}}}const Au="bgra8unorm",Ru=[1,1,1,.8],Eu=8,Du=6,Bu=4,ca=8192,Lu=()=>{const e=new ArrayBuffer(64);return new Float32Array(e).set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),e},ku=e=>Number.isFinite(e.left)&&Number.isFinite(e.right)&&Number.isFinite(e.top)&&Number.isFinite(e.bottom)&&Number.isFinite(e.canvasWidth)&&Number.isFinite(e.canvasHeight),Ii=(e,t,n)=>Math.min(n,Math.max(t,e|0)),Uu=(e,t)=>{if(!Number.isFinite(e)||e<0)throw new Error("CrosshairRenderer.prepare: lineWidth must be a finite non-negative number.");if(e===0)return[];const n=e*t,i=Math.max(1,Math.min(Eu,Math.round(n))),r=(i-1)/2,o=[];for(let s=0;s<i;s++)o.push(s-r);return o},Dn=(e,t)=>e/t*2-1,Bn=(e,t)=>1-e/t*2,Pi=(e,t)=>{e.push(t[0],t[1],t[2],t[3])},hs=(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t))return[];const n=Math.min(e,t),i=Math.max(e,t);if(i<=n)return[];const r=Du,s=r+Bu;if(!Number.isFinite(s))return[];const a=Math.ceil((i-n)/s);if(!Number.isFinite(a)||a<=0)return[];const c=[];let u=n;for(;u<i;){const p=u,h=Math.min(u+r,i);h>p&&c.push([p,h]),u+=s}return c},_u=(e,t,n,i)=>{if(!Number.isFinite(e)||!Number.isFinite(t))throw new Error("CrosshairRenderer.prepare: x and y must be finite numbers.");if(!ku(n))throw new Error("CrosshairRenderer.prepare: gridArea dimensions must be finite numbers.");if(n.canvasWidth<=0||n.canvasHeight<=0)throw new Error("CrosshairRenderer.prepare: canvas dimensions must be positive.");if(n.left<0||n.right<0||n.top<0||n.bottom<0)throw new Error("CrosshairRenderer.prepare: gridArea margins must be non-negative.");const{canvasWidth:r,canvasHeight:o}=n,s=Number.isFinite(n.devicePixelRatio)&&n.devicePixelRatio>0?n.devicePixelRatio:1,a=n.left*s,c=r-n.right*s,u=n.top*s,p=o-n.bottom*s,h=Ii(Math.floor(a),0,Math.max(0,r)),l=Ii(Math.floor(u),0,Math.max(0,o)),m=Ii(Math.ceil(c),0,Math.max(0,r)),C=Ii(Math.ceil(p),0,Math.max(0,o)),F=Math.max(0,m-h),R=Math.max(0,C-l),S=e*s,y=t*s,b=Uu(i.lineWidth,s);if(b.length===0||!i.showX&&!i.showY)return{vertices:new Float32Array(0),scissor:{x:h,y:l,w:F,h:R}};const w=[],d=i.showX?hs(u,p):[],g=i.showY?hs(a,c):[],M=((i.showX?d.length:0)+(i.showY?g.length:0))*b.length*2,I=M>0&&M<=ca,T=x=>{const N=Dn(x,r),A=Bn(u,o),P=Bn(p,o);Pi(w,[N,A,N,P])},E=x=>{const N=Bn(x,o),A=Dn(a,r),P=Dn(c,r);Pi(w,[A,N,P,N])};if(i.showX)for(let x=0;x<b.length;x++){const N=S+b[x];if(!I){T(N);continue}const A=Dn(N,r);for(let P=0;P<d.length;P++){const[L,B]=d[P],V=Bn(L,o),_=Bn(B,o);Pi(w,[A,V,A,_])}}if(i.showY)for(let x=0;x<b.length;x++){const N=y+b[x];if(!I){E(N);continue}const A=Bn(N,o);for(let P=0;P<g.length;P++){const[L,B]=g[P],V=Dn(L,r),_=Dn(B,r);Pi(w,[V,A,_,A])}}return{vertices:new Float32Array(w),scissor:{x:h,y:l,w:F,h:R}}};function Gu(e,t){let n=!1,i=!0;const r=(t==null?void 0:t.targetFormat)??Au,o=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),s=nt(e,64,{label:"crosshairRenderer/vsUniforms"}),a=nt(e,16,{label:"crosshairRenderer/fsUniforms"}),c=e.createBindGroup({layout:o,entries:[{binding:0,resource:{buffer:s}},{binding:1,resource:{buffer:a}}]}),u=Tt(e,{label:"crosshairRenderer/pipeline",bindGroupLayouts:[o],vertex:{code:ps,label:"crosshair.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:ps,label:"crosshair.wgsl",formats:r,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"line-list",cullMode:"none"},multisample:{count:1}}),p=Pu(e,ca*8);let h=0,l=0,m=0,C={x:0,y:0,w:0,h:0};const F=()=>{if(n)throw new Error("CrosshairRenderer is disposed.")};return{prepare:(w,d,g,v)=>{if(F(),typeof v.showX!="boolean"||typeof v.showY!="boolean")throw new Error("CrosshairRenderer.prepare: showX/showY must be boolean.");if(typeof v.color!="string")throw new Error("CrosshairRenderer.prepare: color must be a string.");if(!Number.isFinite(v.lineWidth)||v.lineWidth<0)throw new Error("CrosshairRenderer.prepare: lineWidth must be a finite non-negative number.");const{vertices:M,scissor:I}=_u(w,d,g,v);M.byteLength===0?h=0:(p.write(M),h=p.getVertexCount()),Qe(e,s,Lu());const T=pt(v.color)??Ru,E=new ArrayBuffer(4*4);new Float32Array(E).set([T[0],T[1],T[2],T[3]]),Qe(e,a,E),l=g.canvasWidth,m=g.canvasHeight,C=I},render:w=>{F(),i&&h!==0&&(l<=0||m<=0||(w.setScissorRect(C.x,C.y,C.w,C.h),w.setPipeline(u),w.setBindGroup(0,c),w.setVertexBuffer(0,p.getBuffer()),w.draw(h),w.setScissorRect(0,0,l,m)))},setVisible:w=>{F(),i=!!w},dispose:()=>{if(!n){n=!0;try{s.destroy()}catch{}try{a.destroy()}catch{}p.dispose(),h=0,l=0,m=0,C={x:0,y:0,w:0,h:0}}}}}const ys=`// highlight.wgsl
|
|
715
|
+
// Draws an anti-aliased ring highlight around a point.
|
|
716
|
+
//
|
|
717
|
+
// Contract:
|
|
718
|
+
// - \`@builtin(position)\` in the fragment stage is framebuffer-space pixels.
|
|
719
|
+
// - The renderer supplies \`center\` and ring sizes in *device pixels*.
|
|
720
|
+
|
|
721
|
+
struct Uniforms {
|
|
722
|
+
center: vec2<f32>,
|
|
723
|
+
radius: f32,
|
|
724
|
+
thickness: f32,
|
|
725
|
+
color: vec4<f32>,
|
|
726
|
+
outlineColor: vec4<f32>,
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
730
|
+
|
|
731
|
+
struct VSOut {
|
|
732
|
+
@builtin(position) position: vec4<f32>,
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
@vertex
|
|
736
|
+
fn vsMain(@builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
737
|
+
// Fullscreen triangle.
|
|
738
|
+
// Covers clip-space [-1,1] with 3 verts: (-1,-1), (3,-1), (-1,3)
|
|
739
|
+
let positions = array<vec2<f32>, 3>(
|
|
740
|
+
vec2<f32>(-1.0, -1.0),
|
|
741
|
+
vec2<f32>(3.0, -1.0),
|
|
742
|
+
vec2<f32>(-1.0, 3.0)
|
|
743
|
+
);
|
|
744
|
+
|
|
745
|
+
var out: VSOut;
|
|
746
|
+
out.position = vec4<f32>(positions[vertexIndex], 0.0, 1.0);
|
|
747
|
+
return out;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
fn ringCoverage(distancePx: f32, radiusPx: f32, thicknessPx: f32) -> f32 {
|
|
751
|
+
let aa = 1.0; // ~1px antialias band (device pixels)
|
|
752
|
+
let halfT = max(0.5, thicknessPx * 0.5);
|
|
753
|
+
let a0 = smoothstep(radiusPx - halfT - aa, radiusPx - halfT + aa, distancePx);
|
|
754
|
+
let a1 = smoothstep(radiusPx + halfT - aa, radiusPx + halfT + aa, distancePx);
|
|
755
|
+
return clamp(a0 - a1, 0.0, 1.0);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
@fragment
|
|
759
|
+
fn fsMain(@builtin(position) fragPos: vec4<f32>) -> @location(0) vec4<f32> {
|
|
760
|
+
let d = distance(fragPos.xy, u.center);
|
|
761
|
+
|
|
762
|
+
let ring = ringCoverage(d, u.radius, u.thickness);
|
|
763
|
+
let outline = ringCoverage(d, u.radius, u.thickness + 2.0);
|
|
764
|
+
|
|
765
|
+
let cover = max(ring, outline);
|
|
766
|
+
if (cover <= 0.0) {
|
|
767
|
+
discard;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// Blend between outline and ring color based on relative coverage,
|
|
771
|
+
// then apply total coverage as alpha.
|
|
772
|
+
let t = clamp(select(0.0, ring / cover, cover > 0.0), 0.0, 1.0);
|
|
773
|
+
let rgb = mix(u.outlineColor.rgb, u.color.rgb, t);
|
|
774
|
+
let a = mix(u.outlineColor.a, u.color.a, t) * cover;
|
|
775
|
+
return vec4<f32>(rgb, a);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
`,zu="bgra8unorm",Vu=[1,1,1,1],Ai=e=>Math.min(1,Math.max(0,e)),Ri=(e,t,n)=>Math.min(n,Math.max(t,e|0)),Ou=e=>Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&Number.isFinite(e.h),$u=(e,t)=>{const n=Number.isFinite(t)?t:1;return[Ai(e[0]*n),Ai(e[1]*n),Ai(e[2]*n),Ai(e[3])]},Wu=e=>.2126*e[0]+.7152*e[1]+.0722*e[2];function Xu(e,t){let n=!1,i=!0;const r=(t==null?void 0:t.targetFormat)??zu,o=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),s=nt(e,48,{label:"highlightRenderer/uniforms"}),a=e.createBindGroup({layout:o,entries:[{binding:0,resource:{buffer:s}}]}),c=Tt(e,{label:"highlightRenderer/pipeline",bindGroupLayouts:[o],vertex:{code:ys,label:"highlight.wgsl"},fragment:{code:ys,label:"highlight.wgsl",formats:r,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:1}});let u=0,p=0,h={x:0,y:0,w:0,h:0},l=!1;const m=()=>{if(n)throw new Error("HighlightRenderer is disposed.")};return{prepare:(y,b,w)=>{if(m(),!Number.isFinite(y.centerDeviceX)||!Number.isFinite(y.centerDeviceY))throw new Error("HighlightRenderer.prepare: point center must be finite.");if(!Number.isFinite(y.canvasWidth)||!Number.isFinite(y.canvasHeight)||y.canvasWidth<=0||y.canvasHeight<=0)throw new Error("HighlightRenderer.prepare: canvasWidth/canvasHeight must be positive finite numbers.");if(!Ou(y.scissor))throw new Error("HighlightRenderer.prepare: scissor must be finite.");if(!Number.isFinite(w)||w<0)throw new Error("HighlightRenderer.prepare: size must be a finite non-negative number.");const d=y.devicePixelRatio,g=Number.isFinite(d)&&d>0?d:1,v=w*g,M=Math.max(1,v*1.5),I=Math.max(1,Math.round(Math.max(2,M*.25))),T=pt(b)??Vu,E=$u(T,1.25),x=Wu(T)>.7?[0,0,0,.9]:[1,1,1,.9],N=new ArrayBuffer(12*4);new Float32Array(N).set([y.centerDeviceX,y.centerDeviceY,M,I,E[0],E[1],E[2],1,x[0],x[1],x[2],x[3]]),Qe(e,s,N),u=y.canvasWidth,p=y.canvasHeight;const A=Ri(Math.floor(y.scissor.x),0,Math.max(0,y.canvasWidth)),P=Ri(Math.floor(y.scissor.y),0,Math.max(0,y.canvasHeight)),L=Ri(Math.ceil(y.scissor.x+y.scissor.w),0,Math.max(0,y.canvasWidth)),B=Ri(Math.ceil(y.scissor.y+y.scissor.h),0,Math.max(0,y.canvasHeight));h={x:A,y:P,w:Math.max(0,L-A),h:Math.max(0,B-P)},l=!0},render:y=>{m(),i&&l&&(u<=0||p<=0||h.w===0||h.h===0||(y.setScissorRect(h.x,h.y,h.w,h.h),y.setPipeline(c),y.setBindGroup(0,a),y.draw(3),y.setScissorRect(0,0,u,p)))},setVisible:y=>{m(),i=!!y},dispose:()=>{if(!n){n=!0;try{s.destroy()}catch{}u=0,p=0,h={x:0,y:0,w:0,h:0},l=!1}}}}const gs=`// Reference line renderer (axis-aligned, instanced quads).
|
|
779
|
+
//
|
|
780
|
+
// Coordinate conventions:
|
|
781
|
+
// - Instance position is provided in CANVAS-LOCAL CSS pixels (same coordinate space as pointer events).
|
|
782
|
+
// - Plot rect is provided in DEVICE pixels (computed from grid margins + DPR).
|
|
783
|
+
// - Line width and dash lengths are provided in CSS pixels and converted in-shader using DPR.
|
|
784
|
+
//
|
|
785
|
+
// Scissoring/clipping:
|
|
786
|
+
// - The render coordinator is expected to set a scissor rect for the plot area before drawing.
|
|
787
|
+
// - This shader simply draws full-height/full-width quads; clipping is handled by scissor.
|
|
788
|
+
//
|
|
789
|
+
// Dash semantics:
|
|
790
|
+
// - lineDash is a repeating on/off sequence in CSS pixels, starting with "on" at t=0.
|
|
791
|
+
// - Up to 8 dash entries are supported per line (truncated on CPU).
|
|
792
|
+
//
|
|
793
|
+
// Performance:
|
|
794
|
+
// - Vertex stage expands each instance into a quad (2 triangles, 6 vertices).
|
|
795
|
+
// - We intentionally avoid snapping to integer device pixels to prevent visible stepping/jiggle
|
|
796
|
+
// while zooming; edge AA is handled in the fragment stage.
|
|
797
|
+
|
|
798
|
+
struct VSUniforms {
|
|
799
|
+
canvasSize : vec2<f32>, // device pixels (canvas.width, canvas.height)
|
|
800
|
+
plotOrigin : vec2<f32>, // device pixels (plotLeft, plotTop)
|
|
801
|
+
plotSize : vec2<f32>, // device pixels (plotWidth, plotHeight)
|
|
802
|
+
devicePixelRatio : f32,
|
|
803
|
+
_pad0 : f32,
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
@group(0) @binding(0) var<uniform> u : VSUniforms;
|
|
807
|
+
|
|
808
|
+
struct VSIn {
|
|
809
|
+
// axisPos.x = axis (0 = vertical, 1 = horizontal)
|
|
810
|
+
// axisPos.y = position in CANVAS-LOCAL CSS pixels (x for vertical, y for horizontal)
|
|
811
|
+
@location(0) axisPos : vec2<f32>,
|
|
812
|
+
|
|
813
|
+
// widthDashCount.x = lineWidth in CSS px
|
|
814
|
+
// widthDashCount.y = dashCount (float, cast to u32)
|
|
815
|
+
@location(1) widthDashCount : vec2<f32>,
|
|
816
|
+
|
|
817
|
+
// dashMeta.x = dashTotal (CSS px)
|
|
818
|
+
// dashMeta.y = reserved (unused)
|
|
819
|
+
@location(2) dashMeta : vec2<f32>,
|
|
820
|
+
|
|
821
|
+
@location(3) dash0_3 : vec4<f32>,
|
|
822
|
+
@location(4) dash4_7 : vec4<f32>,
|
|
823
|
+
|
|
824
|
+
// Premultiplied or straight alpha is fine; blending is handled by pipeline state.
|
|
825
|
+
@location(5) color : vec4<f32>,
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
struct VSOut {
|
|
829
|
+
@builtin(position) position : vec4<f32>,
|
|
830
|
+
|
|
831
|
+
// Distance along the line in CSS pixels (0..plotLengthCss).
|
|
832
|
+
@location(0) alongCss : f32,
|
|
833
|
+
|
|
834
|
+
// Packed dash metadata to avoid extra varyings.
|
|
835
|
+
// dashInfo.x = dashCount (float, cast to u32)
|
|
836
|
+
// dashInfo.y = dashTotal (CSS px)
|
|
837
|
+
@location(1) @interpolate(flat) dashInfo : vec2<f32>,
|
|
838
|
+
|
|
839
|
+
@location(2) @interpolate(flat) dash0_3 : vec4<f32>,
|
|
840
|
+
@location(3) @interpolate(flat) dash4_7 : vec4<f32>,
|
|
841
|
+
@location(4) @interpolate(flat) color : vec4<f32>,
|
|
842
|
+
|
|
843
|
+
// Axis-aligned quad anti-aliasing (device pixels).
|
|
844
|
+
// acrossDevice ranges [0..widthDevice] across the stroke thickness.
|
|
845
|
+
@location(5) acrossDevice : f32,
|
|
846
|
+
@location(6) @interpolate(flat) widthDevice : f32,
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
fn quadUv(vid : u32) -> vec2<f32> {
|
|
850
|
+
// Two triangles covering [0,1]x[0,1].
|
|
851
|
+
// 0: (0,0) 1:(1,0) 2:(0,1) 3:(0,1) 4:(1,0) 5:(1,1)
|
|
852
|
+
switch (vid) {
|
|
853
|
+
case 0u: { return vec2<f32>(0.0, 0.0); }
|
|
854
|
+
case 1u: { return vec2<f32>(1.0, 0.0); }
|
|
855
|
+
case 2u: { return vec2<f32>(0.0, 1.0); }
|
|
856
|
+
case 3u: { return vec2<f32>(0.0, 1.0); }
|
|
857
|
+
case 4u: { return vec2<f32>(1.0, 0.0); }
|
|
858
|
+
default: { return vec2<f32>(1.0, 1.0); }
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
@vertex
|
|
863
|
+
fn vsMain(in : VSIn, @builtin(vertex_index) vid : u32) -> VSOut {
|
|
864
|
+
let uv = quadUv(vid);
|
|
865
|
+
let dpr = max(1e-6, u.devicePixelRatio);
|
|
866
|
+
// IMPORTANT: Do NOT snap reference lines to integer device pixels.
|
|
867
|
+
// Snapping looks crisp at rest but causes visible "jiggle" / stepping while zooming because
|
|
868
|
+
// the line position is continuously changing (data-space → screen-space), and rounding
|
|
869
|
+
// quantizes that motion to adjacent pixels. We rely on analytic AA in the fragment stage
|
|
870
|
+
// to keep strokes stable and reasonably crisp across DPRs.
|
|
871
|
+
|
|
872
|
+
let axis = in.axisPos.x;
|
|
873
|
+
let posCss = in.axisPos.y;
|
|
874
|
+
let widthCss = max(0.0, in.widthDashCount.x);
|
|
875
|
+
let widthDevice = max(1.0, widthCss * dpr);
|
|
876
|
+
|
|
877
|
+
var xDevice : f32;
|
|
878
|
+
var yDevice : f32;
|
|
879
|
+
var alongCss : f32;
|
|
880
|
+
var acrossDevice : f32;
|
|
881
|
+
|
|
882
|
+
if (axis < 0.5) {
|
|
883
|
+
// Vertical line at x = posCss (canvas-local CSS px), spanning plot height.
|
|
884
|
+
let centerX = posCss * dpr;
|
|
885
|
+
let startX = centerX - 0.5 * widthDevice;
|
|
886
|
+
xDevice = startX + uv.x * widthDevice;
|
|
887
|
+
yDevice = u.plotOrigin.y + uv.y * u.plotSize.y;
|
|
888
|
+
alongCss = (uv.y * u.plotSize.y) / dpr;
|
|
889
|
+
acrossDevice = uv.x * widthDevice;
|
|
890
|
+
} else {
|
|
891
|
+
// Horizontal line at y = posCss (canvas-local CSS px), spanning plot width.
|
|
892
|
+
let centerY = posCss * dpr;
|
|
893
|
+
let startY = centerY - 0.5 * widthDevice;
|
|
894
|
+
xDevice = u.plotOrigin.x + uv.x * u.plotSize.x;
|
|
895
|
+
yDevice = startY + uv.y * widthDevice;
|
|
896
|
+
alongCss = (uv.x * u.plotSize.x) / dpr;
|
|
897
|
+
acrossDevice = uv.y * widthDevice;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
let clipX = (xDevice / u.canvasSize.x) * 2.0 - 1.0;
|
|
901
|
+
let clipY = 1.0 - (yDevice / u.canvasSize.y) * 2.0;
|
|
902
|
+
|
|
903
|
+
var out : VSOut;
|
|
904
|
+
out.position = vec4<f32>(clipX, clipY, 0.0, 1.0);
|
|
905
|
+
out.alongCss = alongCss;
|
|
906
|
+
out.dashInfo = vec2<f32>(in.widthDashCount.y, in.dashMeta.x);
|
|
907
|
+
out.dash0_3 = in.dash0_3;
|
|
908
|
+
out.dash4_7 = in.dash4_7;
|
|
909
|
+
out.color = in.color;
|
|
910
|
+
out.acrossDevice = acrossDevice;
|
|
911
|
+
out.widthDevice = widthDevice;
|
|
912
|
+
return out;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
fn dashValue(i : u32, d0 : vec4<f32>, d1 : vec4<f32>) -> f32 {
|
|
916
|
+
switch (i) {
|
|
917
|
+
case 0u: { return d0.x; }
|
|
918
|
+
case 1u: { return d0.y; }
|
|
919
|
+
case 2u: { return d0.z; }
|
|
920
|
+
case 3u: { return d0.w; }
|
|
921
|
+
case 4u: { return d1.x; }
|
|
922
|
+
case 5u: { return d1.y; }
|
|
923
|
+
case 6u: { return d1.z; }
|
|
924
|
+
default: { return d1.w; }
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
@fragment
|
|
929
|
+
fn fsMain(in : VSOut) -> @location(0) vec4<f32> {
|
|
930
|
+
// Analytic edge anti-aliasing for axis-aligned quads (reduces shimmering during zoom).
|
|
931
|
+
// This is a lightweight alternative to full MSAA for thin strokes.
|
|
932
|
+
let edgeDist = min(in.acrossDevice, in.widthDevice - in.acrossDevice);
|
|
933
|
+
// Slightly widen AA to reduce temporal shimmer on moving 1-2px strokes.
|
|
934
|
+
// Keep conservative so lines remain reasonably crisp.
|
|
935
|
+
let aa = max(fwidth(in.acrossDevice), 1e-3) * 1.25;
|
|
936
|
+
let edgeCoverage = smoothstep(0.0, aa, edgeDist);
|
|
937
|
+
var color = in.color;
|
|
938
|
+
color.a = color.a * edgeCoverage;
|
|
939
|
+
|
|
940
|
+
let dashCount = u32(round(in.dashInfo.x));
|
|
941
|
+
let dashTotal = in.dashInfo.y;
|
|
942
|
+
|
|
943
|
+
// IMPORTANT: derivative ops (fwidth) must execute in uniform control flow.
|
|
944
|
+
// So compute the dash parameterization unconditionally (using a safe total) BEFORE any early-return.
|
|
945
|
+
let dashTotalSafe = max(dashTotal, 1.0);
|
|
946
|
+
let t = in.alongCss - floor(in.alongCss / dashTotalSafe) * dashTotalSafe;
|
|
947
|
+
// Anti-alias dash edges along the line axis (CSS pixels).
|
|
948
|
+
// This reduces shimmer during zoom for dashed reference lines without requiring MSAA.
|
|
949
|
+
let dashAa = max(fwidth(t), 1e-3);
|
|
950
|
+
|
|
951
|
+
// Solid line (no dash pattern).
|
|
952
|
+
if (dashCount == 0u || dashTotal <= 0.0) {
|
|
953
|
+
return color;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
var acc = 0.0;
|
|
957
|
+
var on = true;
|
|
958
|
+
|
|
959
|
+
for (var i : u32 = 0u; i < 8u; i = i + 1u) {
|
|
960
|
+
if (i >= dashCount) { break; }
|
|
961
|
+
let seg = dashValue(i, in.dash0_3, in.dash4_7);
|
|
962
|
+
if (seg <= 0.0) { continue; }
|
|
963
|
+
|
|
964
|
+
if (t < acc + seg) {
|
|
965
|
+
// IMPORTANT: Avoid \`discard\` for off segments.
|
|
966
|
+
// Discard can cause temporal popping on moving dashed edges; prefer a smooth alpha mask.
|
|
967
|
+
//
|
|
968
|
+
// Fade in/out near dash boundaries for smooth edges. This produces coverage in [0..1]
|
|
969
|
+
// within the current segment, going to 0 at segment boundaries.
|
|
970
|
+
let inFromStart = smoothstep(0.0, dashAa, t - acc);
|
|
971
|
+
let inFromEnd = smoothstep(0.0, dashAa, (acc + seg) - t);
|
|
972
|
+
let segCoverage = min(inFromStart, inFromEnd);
|
|
973
|
+
|
|
974
|
+
// On segments contribute alpha; off segments contribute 0 alpha (no discard).
|
|
975
|
+
let dashMask = select(0.0, segCoverage, on);
|
|
976
|
+
color.a = color.a * dashMask;
|
|
977
|
+
return color;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
acc = acc + seg;
|
|
981
|
+
on = !on;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// Defensive fallback if the dash list is degenerate.
|
|
985
|
+
// If we didn't find a segment (shouldn't happen), default to transparent (safer than solid).
|
|
986
|
+
color.a = 0.0;
|
|
987
|
+
return color;
|
|
988
|
+
}
|
|
989
|
+
`,Un=8,Yu="bgra8unorm",Hu=e=>Number.isFinite(e.left)&&Number.isFinite(e.right)&&Number.isFinite(e.top)&&Number.isFinite(e.bottom)&&Number.isFinite(e.canvasWidth)&&Number.isFinite(e.canvasHeight),qu=e=>{if(!e||e.length===0)return{dashCount:0,dashTotal:0,values:new Array(Un).fill(0)};const t=[];for(let s=0;s<e.length;s++){const a=e[s];typeof a=="number"&&Number.isFinite(a)&&a>0&&t.push(a)}if(t.length===0)return{dashCount:0,dashTotal:0,values:new Array(Un).fill(0)};const n=t.length%2===1?t.concat(t):t,i=Math.min(Un,n.length),r=new Array(Un).fill(0);let o=0;for(let s=0;s<i;s++)r[s]=n[s],o+=n[s];return!Number.isFinite(o)||o<=0?{dashCount:0,dashTotal:0,values:new Array(Un).fill(0)}:{dashCount:i,dashTotal:o,values:r}};function xs(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??Yu,r=(t==null?void 0:t.sampleCount)??1,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),a=nt(e,32,{label:"referenceLineRenderer/vsUniforms"}),c=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:a}}]}),u=72,p=u/4,h=Tt(e,{label:"referenceLineRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:gs,label:"referenceLine.wgsl",buffers:[{arrayStride:u,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32x2",offset:8},{shaderLocation:2,format:"float32x2",offset:16},{shaderLocation:3,format:"float32x4",offset:24},{shaderLocation:4,format:"float32x4",offset:40},{shaderLocation:5,format:"float32x4",offset:56}]}]},fragment:{code:gs,label:"referenceLine.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:o}});let l=null,m=0,C=0;const F=()=>{if(n)throw new Error("ReferenceLineRenderer is disposed.")};return{prepare:(b,w)=>{if(F(),!Array.isArray(w))throw new Error("ReferenceLineRenderer.prepare: lines must be an array.");if(!Hu(b))throw new Error("ReferenceLineRenderer.prepare: gridArea dimensions must be finite numbers.");if(b.canvasWidth<=0||b.canvasHeight<=0)throw new Error("ReferenceLineRenderer.prepare: canvas dimensions must be positive.");if(b.left<0||b.right<0||b.top<0||b.bottom<0)throw new Error("ReferenceLineRenderer.prepare: gridArea margins must be non-negative.");const d=Number.isFinite(b.devicePixelRatio)&&b.devicePixelRatio>0?b.devicePixelRatio:1,g=b.left*d,v=b.top*d,M=b.canvasWidth-b.right*d,I=b.canvasHeight-b.bottom*d,T=M-g,E=I-v;if(!(T>0)||!(E>0)){C=0;return}const f=new Float32Array(8);if(f[0]=b.canvasWidth,f[1]=b.canvasHeight,f[2]=g,f[3]=v,f[4]=T,f[5]=E,f[6]=d,f[7]=0,Qe(e,a,f),w.length===0){C=0;return}if(!l||m<w.length){const N=Math.max(1,Math.ceil(w.length*1.5)),A=Math.max(4,N*u);if(l)try{l.destroy()}catch{}l=e.createBuffer({label:"referenceLineRenderer/instanceBuffer",size:A,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),m=N}const x=new Float32Array(w.length*p);for(let N=0;N<w.length;N++){const A=w[N],P=N*p;if(A.axis!=="vertical"&&A.axis!=="horizontal")throw new Error("ReferenceLineRenderer.prepare: line.axis must be 'vertical' or 'horizontal'.");if(!Number.isFinite(A.positionCssPx))throw new Error("ReferenceLineRenderer.prepare: line.positionCssPx must be a finite number.");if(!Number.isFinite(A.lineWidth)||A.lineWidth<0)throw new Error("ReferenceLineRenderer.prepare: line.lineWidth must be a finite non-negative number.");const L=A.rgba;if(!Array.isArray(L)||L.length!==4)throw new Error("ReferenceLineRenderer.prepare: line.rgba must be a tuple [r,g,b,a].");const B=qu(A.lineDash);x[P+0]=A.axis==="vertical"?0:1,x[P+1]=A.positionCssPx,x[P+2]=A.lineWidth,x[P+3]=B.dashCount,x[P+4]=B.dashTotal,x[P+5]=0;for(let V=0;V<Un;V++)x[P+6+V]=B.values[V];x[P+14]=L[0],x[P+15]=L[1],x[P+16]=L[2],x[P+17]=L[3]}e.queue.writeBuffer(l,0,x.buffer,x.byteOffset,x.byteLength),C=w.length},render:(b,w=0,d)=>{if(F(),C===0||!l)return;const g=Number.isFinite(w)?Math.max(0,Math.floor(w)):0,v=Math.max(0,C-g),M=d==null?v:Number.isFinite(d)?Math.max(0,Math.min(v,Math.floor(d))):v;M!==0&&(b.setPipeline(h),b.setBindGroup(0,c),b.setVertexBuffer(0,l),b.draw(6,M,0,g))},dispose:()=>{if(!n){n=!0;try{a.destroy()}catch{}if(l)try{l.destroy()}catch{}l=null,m=0,C=0}}}}const bs=`// annotationMarker.wgsl
|
|
990
|
+
// Instanced annotation marker shader (circle SDF with optional stroke).
|
|
991
|
+
//
|
|
992
|
+
// Coordinate contract:
|
|
993
|
+
// - Instance center is CANVAS-LOCAL CSS pixels (xCssPx, yCssPx)
|
|
994
|
+
// - Instance size is diameter in CSS pixels (sizeCssPx)
|
|
995
|
+
// - Uniform provides render target size in *device* pixels and DPR for CSS→device conversion.
|
|
996
|
+
//
|
|
997
|
+
// Draw call: draw(6, instanceCount) using triangle-list quad expansion in VS.
|
|
998
|
+
|
|
999
|
+
struct VSUniforms {
|
|
1000
|
+
viewportPx: vec2<f32>, // render target size in device pixels (width, height)
|
|
1001
|
+
dpr: f32, // device pixel ratio (CSS px -> device px)
|
|
1002
|
+
_pad0: f32,
|
|
1003
|
+
};
|
|
1004
|
+
|
|
1005
|
+
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
1006
|
+
|
|
1007
|
+
struct VSIn {
|
|
1008
|
+
// Center in CANVAS-LOCAL CSS pixels.
|
|
1009
|
+
@location(0) centerCssPx: vec2<f32>,
|
|
1010
|
+
// Marker diameter in CSS pixels.
|
|
1011
|
+
@location(1) sizeCssPx: f32,
|
|
1012
|
+
// Stroke width in CSS pixels (0 disables stroke).
|
|
1013
|
+
@location(2) strokeWidthCssPx: f32,
|
|
1014
|
+
// Colors are straight-alpha RGBA in 0..1.
|
|
1015
|
+
@location(3) fillRgba: vec4<f32>,
|
|
1016
|
+
@location(4) strokeRgba: vec4<f32>,
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
struct VSOut {
|
|
1020
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
1021
|
+
// Local quad coordinates in [-1, 1]^2 (used for circle SDF).
|
|
1022
|
+
@location(0) local: vec2<f32>,
|
|
1023
|
+
// Half-size in device pixels (radius in screen space).
|
|
1024
|
+
@location(1) halfSizePx: f32,
|
|
1025
|
+
@location(2) strokeWidthPx: f32,
|
|
1026
|
+
@location(3) fillRgba: vec4<f32>,
|
|
1027
|
+
@location(4) strokeRgba: vec4<f32>,
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
@vertex
|
|
1031
|
+
fn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {
|
|
1032
|
+
// Fixed local corners for 2 triangles (triangle-list).
|
|
1033
|
+
let localCorners = array<vec2<f32>, 6>(
|
|
1034
|
+
vec2<f32>(-1.0, -1.0),
|
|
1035
|
+
vec2<f32>( 1.0, -1.0),
|
|
1036
|
+
vec2<f32>(-1.0, 1.0),
|
|
1037
|
+
vec2<f32>(-1.0, 1.0),
|
|
1038
|
+
vec2<f32>( 1.0, -1.0),
|
|
1039
|
+
vec2<f32>( 1.0, 1.0)
|
|
1040
|
+
);
|
|
1041
|
+
|
|
1042
|
+
let corner = localCorners[vertexIndex];
|
|
1043
|
+
|
|
1044
|
+
let dpr = select(1.0, vsUniforms.dpr, vsUniforms.dpr > 0.0);
|
|
1045
|
+
let centerPx = in.centerCssPx * dpr;
|
|
1046
|
+
let halfSizePx = 0.5 * max(0.0, in.sizeCssPx) * dpr;
|
|
1047
|
+
let strokeWidthPx = max(0.0, in.strokeWidthCssPx) * dpr;
|
|
1048
|
+
|
|
1049
|
+
let posPx = centerPx + corner * halfSizePx;
|
|
1050
|
+
|
|
1051
|
+
// Convert device pixels to clip-space with origin at top-left:
|
|
1052
|
+
// x: [0..w] -> [-1..1], y: [0..h] -> [1..-1]
|
|
1053
|
+
let clipX = (posPx.x / vsUniforms.viewportPx.x) * 2.0 - 1.0;
|
|
1054
|
+
let clipY = 1.0 - (posPx.y / vsUniforms.viewportPx.y) * 2.0;
|
|
1055
|
+
|
|
1056
|
+
var out: VSOut;
|
|
1057
|
+
out.clipPosition = vec4<f32>(clipX, clipY, 0.0, 1.0);
|
|
1058
|
+
out.local = corner;
|
|
1059
|
+
out.halfSizePx = halfSizePx;
|
|
1060
|
+
out.strokeWidthPx = strokeWidthPx;
|
|
1061
|
+
out.fillRgba = in.fillRgba;
|
|
1062
|
+
out.strokeRgba = in.strokeRgba;
|
|
1063
|
+
return out;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
@fragment
|
|
1067
|
+
fn fsMain(in: VSOut) -> @location(0) vec4<f32> {
|
|
1068
|
+
if (in.halfSizePx <= 0.0) {
|
|
1069
|
+
discard;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// Circle SDF in normalized space: dist == 1 at the circle boundary.
|
|
1073
|
+
let dist = length(in.local);
|
|
1074
|
+
let aa = max(1e-6, fwidth(dist));
|
|
1075
|
+
|
|
1076
|
+
// Coverage inside the circle.
|
|
1077
|
+
let outerCoverage = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, dist);
|
|
1078
|
+
if (outerCoverage <= 0.0) {
|
|
1079
|
+
discard;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
// Optional stroke: compute inner radius in normalized units.
|
|
1083
|
+
let strokeNorm = clamp(in.strokeWidthPx / max(1e-6, in.halfSizePx), 0.0, 1.0);
|
|
1084
|
+
let inner = max(0.0, 1.0 - strokeNorm);
|
|
1085
|
+
let innerCoverage = 1.0 - smoothstep(inner - aa, inner + aa, dist);
|
|
1086
|
+
|
|
1087
|
+
let fillCoverage = clamp(innerCoverage, 0.0, 1.0);
|
|
1088
|
+
let strokeCoverage = clamp(outerCoverage - innerCoverage, 0.0, 1.0);
|
|
1089
|
+
|
|
1090
|
+
let fillA = clamp(in.fillRgba.a, 0.0, 1.0) * fillCoverage;
|
|
1091
|
+
let strokeA = clamp(in.strokeRgba.a, 0.0, 1.0) * strokeCoverage;
|
|
1092
|
+
let outA = fillA + strokeA;
|
|
1093
|
+
if (outA <= 0.0) {
|
|
1094
|
+
discard;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// Straight-alpha output: compute a weighted average RGB for correct blending.
|
|
1098
|
+
let rgb = (in.fillRgba.rgb * fillA + in.strokeRgba.rgb * strokeA) / outA;
|
|
1099
|
+
return vec4<f32>(rgb, outA);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
`,Zu="bgra8unorm",zi=12,Br=zi*4,dn=e=>Math.min(1,Math.max(0,e)),vs=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))};function ws(e,t){let n=!1;const i=(t==null?void 0:t.targetFormat)??Zu,r=(t==null?void 0:t.sampleCount)??1,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),a=nt(e,16,{label:"annotationMarkerRenderer/vsUniforms"}),c=new Float32Array(4),u=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:a}}]}),p=Tt(e,{label:"annotationMarkerRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:bs,label:"annotationMarker.wgsl",buffers:[{arrayStride:Br,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32",offset:8},{shaderLocation:2,format:"float32",offset:12},{shaderLocation:3,format:"float32x4",offset:16},{shaderLocation:4,format:"float32x4",offset:32}]}]},fragment:{code:bs,label:"annotationMarker.wgsl",formats:i,blend:{color:{operation:"add",srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one-minus-src-alpha"}}},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:o}});let h=null,l=0,m=new ArrayBuffer(0),C=new Float32Array(m);const F=()=>{if(n)throw new Error("AnnotationMarkerRenderer is disposed.")},R=d=>{if(d<=C.length)return;const g=Math.max(32,vs(d));m=new ArrayBuffer(g*4),C=new Float32Array(m)},S=(d,g,v)=>{const M=Number.isFinite(d)&&d>0?d:1,I=Number.isFinite(g)&&g>0?g:1,T=Number.isFinite(v)&&v>0?v:1;c[0]=M,c[1]=I,c[2]=T,c[3]=0,Qe(e,a,c)};return{prepare:({canvasWidth:d,canvasHeight:g,devicePixelRatio:v,instances:M})=>{if(F(),!Number.isFinite(d)||!Number.isFinite(g)||d<=0||g<=0)throw new Error("AnnotationMarkerRenderer.prepare: canvasWidth/canvasHeight must be positive finite numbers.");if(!Array.isArray(M))throw new Error("AnnotationMarkerRenderer.prepare: instances must be an array.");S(d,g,v),R(M.length*zi);const I=C;let T=0;for(let f=0;f<M.length;f++){const x=M[f];if(!Number.isFinite(x.xCssPx)||!Number.isFinite(x.yCssPx)||!Number.isFinite(x.sizeCssPx)||x.sizeCssPx<=0)continue;const N=x.strokeWidthCssPx??0,A=x.strokeRgba??[0,0,0,0],P=dn(x.fillRgba[0]),L=dn(x.fillRgba[1]),B=dn(x.fillRgba[2]),V=dn(x.fillRgba[3]),_=dn(A[0]),re=dn(A[1]),Y=dn(A[2]),W=dn(A[3]);I[T+0]=x.xCssPx,I[T+1]=x.yCssPx,I[T+2]=x.sizeCssPx,I[T+3]=Number.isFinite(N)?Math.max(0,N):0,I[T+4]=P,I[T+5]=L,I[T+6]=B,I[T+7]=V,I[T+8]=_,I[T+9]=re,I[T+10]=Y,I[T+11]=W,T+=zi}if(l=T/zi,l===0)return;const E=Math.max(4,l*Br);if(!h||h.size<E){const f=Math.max(Math.max(4,vs(E)),h?h.size:0);if(h)try{h.destroy()}catch{}h=e.createBuffer({label:"annotationMarkerRenderer/instanceBuffer",size:f,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}e.queue.writeBuffer(h,0,m,0,l*Br)},render:(d,g=0,v)=>{if(F(),!h||l===0)return;const M=Number.isFinite(g)?Math.max(0,Math.floor(g)):0,I=Math.max(0,l-M),T=v==null?I:Number.isFinite(v)?Math.max(0,Math.min(I,Math.floor(v))):I;T!==0&&(d.setPipeline(p),d.setBindGroup(0,u),d.setVertexBuffer(0,h),d.draw(6,T,0,M))},dispose:()=>{if(!n){if(n=!0,h)try{h.destroy()}catch{}h=null,l=0;try{a.destroy()}catch{}}}}}const ju=6,Ku=500;function Ju(e,t){let n=!1,i=t;const r={mousemove:new Set,click:new Set,mouseleave:new Set};let o=null,s=null;const a=w=>{const d=e.getBoundingClientRect();if(d.width===0||d.height===0)return null;const g=w.clientX-d.left,v=w.clientY-d.top,M=i.left,I=i.top,T=d.width-i.left-i.right,E=d.height-i.top-i.bottom,f=g-M,x=v-I,N=f>=0&&f<=T&&x>=0&&x<=E;return{x:g,y:v,gridX:f,gridY:x,plotWidthCss:T,plotHeightCss:E,isInGrid:N,originalEvent:w}},c=(w,d)=>{const g=a(d);if(g)for(const v of r[w])v(g)},u=w=>{o&&w.isPrimary&&w.pointerId===o.pointerId&&(o=null)},p=w=>{n||c("mousemove",w)},h=w=>{n||(u(w),c("mouseleave",w))},l=w=>{n||(u(w),c("mouseleave",w))},m=w=>{if(!n){if(s===w.pointerId){s=null;return}u(w),c("mouseleave",w)}},C=w=>{if(n||!w.isPrimary||w.pointerType==="mouse"&&w.button!==0)return;const d=e.getBoundingClientRect();if(!(d.width===0||d.height===0)){o={pointerId:w.pointerId,startClientX:w.clientX,startClientY:w.clientY,startTimeMs:w.timeStamp};try{e.setPointerCapture(w.pointerId)}catch{}}},F=w=>{if(n||!w.isPrimary||!o||w.pointerId!==o.pointerId)return;const d=w.timeStamp-o.startTimeMs,g=w.clientX-o.startClientX,v=w.clientY-o.startClientY,M=g*g+v*v;o=null;try{e.hasPointerCapture(w.pointerId)&&(s=w.pointerId,e.releasePointerCapture(w.pointerId))}catch{}const I=ju;d<=Ku&&M<=I*I&&c("click",w)};return e.addEventListener("pointermove",p,{passive:!0}),e.addEventListener("pointerleave",h,{passive:!0}),e.addEventListener("pointercancel",l,{passive:!0}),e.addEventListener("lostpointercapture",m,{passive:!0}),e.addEventListener("pointerdown",C,{passive:!0}),e.addEventListener("pointerup",F,{passive:!0}),{canvas:e,on:(w,d)=>{n||r[w].add(d)},off:(w,d)=>{r[w].delete(d)},updateGridArea:w=>{i=w},dispose:()=>{n||(n=!0,o=null,s=null,e.removeEventListener("pointermove",p),e.removeEventListener("pointerleave",h),e.removeEventListener("pointercancel",l),e.removeEventListener("lostpointercapture",m),e.removeEventListener("pointerdown",C),e.removeEventListener("pointerup",F),r.mousemove.clear(),r.click.clear(),r.mouseleave.clear())}}}const Cs=(e,t,n)=>Math.min(n,Math.max(t,e)),Qu=(e,t)=>{const n=e.deltaY;if(!Number.isFinite(n)||n===0)return 0;switch(e.deltaMode){case WheelEvent.DOM_DELTA_PIXEL:return n;case WheelEvent.DOM_DELTA_LINE:return n*16;case WheelEvent.DOM_DELTA_PAGE:return n*(Number.isFinite(t)&&t>0?t:800);default:return n}},ef=(e,t)=>{const n=e.deltaX;if(!Number.isFinite(n)||n===0)return 0;switch(e.deltaMode){case WheelEvent.DOM_DELTA_PIXEL:return n;case WheelEvent.DOM_DELTA_LINE:return n*16;case WheelEvent.DOM_DELTA_PAGE:return n*(Number.isFinite(t)&&t>0?t:800);default:return n}},tf=e=>{const t=Math.abs(e);if(!Number.isFinite(t)||t===0)return 1;const n=Math.min(t,200);return Math.exp(n*.002)},nf=e=>e.pointerType==="mouse"&&(e.buttons&4)!==0,rf=e=>e.pointerType==="mouse"&&e.shiftKey&&(e.buttons&1)!==0;function of(e,t){let n=!1,i=!1,r=null,o=!1,s=0;const a=()=>{o=!1,s=0},c=C=>{if(r=C,!i)return;const F=C.originalEvent;if(!(C.isInGrid&&(rf(F)||nf(F)))){a();return}const S=C.plotWidthCss;if(!(S>0)||!Number.isFinite(S)){a();return}if(!o){o=!0,s=C.gridX;return}const y=C.gridX-s;if(s=C.gridX,!Number.isFinite(y)||y===0)return;const{start:b,end:w}=t.getRange(),d=w-b;if(!Number.isFinite(d)||d===0)return;const g=-(y/S)*d;!Number.isFinite(g)||g===0||t.pan(g)},u=C=>{r=null,a()},p=C=>{if(!i||n)return;const F=r;if(!F||!F.isInGrid)return;const R=F.plotWidthCss,S=F.plotHeightCss;if(!(R>0)||!(S>0))return;const y=Qu(C,S),b=ef(C,R);if(Math.abs(b)>Math.abs(y)&&b!==0){const{start:T,end:E}=t.getRange(),f=E-T;if(!Number.isFinite(f)||f===0)return;const x=b/R*f;if(!Number.isFinite(x)||x===0)return;C.preventDefault(),t.pan(x);return}if(y===0)return;const w=tf(y);if(!(w>1))return;const{start:d,end:g}=t.getRange(),v=g-d;if(!Number.isFinite(v)||v===0)return;const M=Cs(F.gridX/R,0,1),I=Cs(d+M*v,0,100);C.preventDefault(),y<0?t.zoomIn(I,w):t.zoomOut(I,w)},h=()=>{n||i||(i=!0,e.on("mousemove",c),e.on("mouseleave",u),e.canvas.addEventListener("wheel",p,{passive:!1}))},l=()=>{n||!i||(i=!1,e.off("mousemove",c),e.off("mouseleave",u),e.canvas.removeEventListener("wheel",p),r=null,a())};return{enable:h,disable:l,dispose:()=>{n||(l(),n=!0)}}}const sf=.5,af=100,Vt=(e,t,n)=>Math.min(n,Math.max(t,e)),Lr=e=>Vt(e,0,1),Ms=e=>Object.is(e,-0)?0:e,cf=e=>({start:e.start,end:e.end});function lf(e,t,n){let i=0,r=100,o=null;const s=new Set;let a=(()=>{const g=Number.isFinite(n==null?void 0:n.minSpan)?n.minSpan:sf;return Vt(Number.isFinite(g)?g:0,0,100)})(),c=(()=>{const g=Number.isFinite(n==null?void 0:n.maxSpan)?n.maxSpan:af;return Vt(Number.isFinite(g)?g:100,0,100)})(),u=Math.min(a,c),p=Math.max(a,c);const h=()=>{const g={start:i,end:r};if(o!==null&&o.start===g.start&&o.end===g.end)return;o=cf(g);const v=Array.from(s);for(const M of v)M({start:i,end:r})},l=(g,v,M)=>{if(M){if(typeof M=="string")switch(M){case"start":return{center:g,ratio:0};case"end":return{center:v,ratio:1};case"center":return{center:(g+v)*.5,ratio:.5}}if(M&&Number.isFinite(M.center)&&Number.isFinite(M.ratio))return{center:M.center,ratio:M.ratio}}},m=(g,v,M)=>{if(!Number.isFinite(g)||!Number.isFinite(v))return;let I=g,T=v;if(I>T){const x=I;I=T,T=x}let E=T-I;if(!Number.isFinite(E)||E<0)return;const f=Vt(E,u,p);if(f!==E){const x=M!=null&&M.anchor&&Number.isFinite(M.anchor.center)?Vt(M.anchor.center,0,100):(I+T)*.5,N=M!=null&&M.anchor&&Number.isFinite(M.anchor.ratio)?Lr(M.anchor.ratio):.5;I=x-N*f,T=I+f,E=f}if(E>100&&(I=0,T=100,E=100),I<0){const x=-I;I+=x,T+=x}if(T>100){const x=T-100;I-=x,T-=x}I=Vt(I,0,100),T=Vt(T,0,100),I=Ms(I),T=Ms(T),!(I===i&&T===r)&&(i=I,r=T,(M==null?void 0:M.emit)!==!1&&h())};return m(e,t,{emit:!1}),{getRange:()=>({start:i,end:r}),setRange:(g,v)=>{m(g,v)},setRangeAnchored:(g,v,M)=>{m(g,v,{anchor:l(g,v,M)})},setSpanConstraints:(g,v)=>{const M=typeof g=="number"&&Number.isFinite(g)?Vt(g,0,100):a,I=typeof v=="number"&&Number.isFinite(v)?Vt(v,0,100):c;if(M===a&&I===c)return;a=M,c=I,u=Math.min(a,c),p=Math.max(a,c);const T=i,E=r,f=1e-6,x=E>=100-f?"end":T<=0+f?"start":"center";m(T,E,{anchor:l(T,E,x)})},zoomIn:(g,v)=>{if(!Number.isFinite(g)||!Number.isFinite(v)||v<=1)return;const M=Vt(g,0,100),I=r-i,T=I===0?.5:Lr((M-i)/I),E=I/v,f=M-T*E,x=f+E;m(f,x,{anchor:{center:M,ratio:T}})},zoomOut:(g,v)=>{if(!Number.isFinite(g)||!Number.isFinite(v)||v<=1)return;const M=Vt(g,0,100),I=r-i,T=I===0?.5:Lr((M-i)/I),E=I*v,f=M-T*E,x=f+E;m(f,x,{anchor:{center:M,ratio:T}})},pan:g=>{Number.isFinite(g)&&m(i+g,r+g)},onChange:g=>(s.add(g),()=>{s.delete(g)})}}const kr=new WeakMap,Fs=e=>{const t=typeof e=="object"&&e!==null?e:null;if(t&&kr.has(t))return kr.get(t);let n=!1;const i=Xe(e);for(let r=0;r<i;r++){const o=Ee(e,r);if(Number.isNaN(o)){n=!0;break}}return t&&kr.set(t,n),n},uf=(e,t)=>{const n=[];for(let c=0;c<e.length;c++){const u=e[c];(u==null?void 0:u.type)==="bar"&&n.push({globalSeriesIndex:c,s:u})}if(n.length===0)return null;const i=na(n.map(c=>c.s),t),r=i.barWidthPx,o=i.gapPx,s=i.clusterWidthPx;if(!Number.isFinite(r)||!(r>0))return null;const a=new Map;for(let c=0;c<n.length;c++){const u=n[c].globalSeriesIndex,p=i.clusterSlots.clusterIndexBySeries[c]??0;a.set(u,p)}return{barWidth:r,gap:o,clusterWidth:s,clusterIndexByGlobalSeriesIndex:a}},Ss=(e,t)=>{let n=0,i=Xe(e);for(;n<i;){const r=n+i>>>1;Ee(e,r)<t?n=r+1:i=r}return n};function Ns(e,t,n,i){if(!Number.isFinite(t))return[];const r=Number.POSITIVE_INFINITY,o=r*r,s=n.invert(t);if(!Number.isFinite(s))return[];const a=[],c=uf(e,n);for(let u=0;u<e.length;u++){const p=e[u];if(p.type==="pie"||p.type==="candlestick"||p.visible===!1)continue;const h=p.data,l=Xe(h);if(l===0)continue;if(p.type==="bar"&&c){const S=c.clusterIndexByGlobalSeriesIndex.get(u);if(S!==void 0){const{barWidth:y,gap:b,clusterWidth:w}=c,d=-w/2+S*(y+b),g=0;if(Number.isFinite(y)&&y>0&&Number.isFinite(d)){let v=-1;const M=I=>{if(!Number.isFinite(I))return!1;const T=I+d,E=T+y;return t>=T-g&&t<E+g};if(Fs(h))for(let I=0;I<l;I++){const T=Ee(h,I);if(!Number.isFinite(T))continue;const E=n.scale(T);M(E)&&(v=v<0?I:Math.min(v,I))}else{const I=n.invert(t-d);if(Number.isFinite(I)){const T=Ss(h,I),E=f=>{if(f<0||f>=l)return null;const x=Ee(h,f);if(!Number.isFinite(x))return null;const N=n.scale(x);return Number.isFinite(N)?N:null};for(let f=T-1;f>=0;f--){const x=E(f);if(x===null)continue;const N=x+d,A=N+y;if(A+g<=t)break;t>=N-g&&t<A+g&&(v=v<0?f:Math.min(v,f))}for(let f=T;f<l;f++){const x=E(f);if(x===null)continue;const N=x+d;if(N-g>t)break;const A=N+y;t<A+g&&(v=v<0?f:Math.min(v,f))}}}if(v>=0){const I=Ee(h,v),T=We(h,v),E=mt(h,v),f=E!==void 0?[I,T,E]:[I,T];a.push({seriesIndex:u,dataIndex:v,point:f});continue}}}}let m=-1,C=null,F=o;const R=(S,y)=>{if(!Number.isFinite(y)||!(y<F||y===F&&(m<0||S<m)))return;F=y,m=S;const w=Ee(h,S),d=We(h,S),g=mt(h,S);C=g!==void 0?[w,d,g]:[w,d]};if(Fs(h))for(let S=0;S<l;S++){const y=Ee(h,S);if(!Number.isFinite(y))continue;const b=n.scale(y);if(!Number.isFinite(b))continue;const w=b-t;R(S,w*w)}else{const S=Ss(h,s);let y=S-1,b=S;const w=d=>{const g=Ee(h,d);if(!Number.isFinite(g))return null;const v=n.scale(g);if(!Number.isFinite(v))return null;const M=v-t;return M*M};for(;y>=0||b<l;){for(;y>=0&&w(y)===null;)y--;for(;b<l&&w(b)===null;)b++;if(y<0&&b>=l)break;const d=y>=0?w(y)??Number.POSITIVE_INFINITY:Number.POSITIVE_INFINITY,g=b<l?w(b)??Number.POSITIVE_INFINITY:Number.POSITIVE_INFINITY;if(d>F&&g>F)break;d<=g?(y>=0&&d<=F&&R(y,d),y--,b<l&&g<=F&&g===d&&(R(b,g),b++)):(b<l&&g<=F&&R(b,g),b++)}}C!==null&&a.push({seriesIndex:u,dataIndex:m,point:C})}return a}const ff=e=>Math.min(1,Math.max(0,e)),df=e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null},so=e=>Array.isArray(e),Pn=e=>so(e)?e[0]:e.timestamp,mf=e=>so(e)?e[1]:e.open,pf=e=>so(e)?e[2]:e.close,Ts=new WeakMap,hf=e=>{const t=Ts.get(e);if(t!==void 0)return t;const n=[];for(let o=0;o<e.length;o++){const s=Pn(e[o]);Number.isFinite(s)&&n.push(s)}if(n.length<2)return 1;n.sort((o,s)=>o-s);let i=Number.POSITIVE_INFINITY;for(let o=1;o<n.length;o++){const s=n[o]-n[o-1];s>0&&s<i&&(i=s)}const r=Number.isFinite(i)&&i>0?i:1;return Ts.set(e,r),r};function Yr(e,t,n,i){if(t.length===0)return 0;const r=hf(t);let o=0;if(Number.isFinite(r)&&r>0){let h=null;for(let l=0;l<t.length;l++){const m=Pn(t[l]);if(Number.isFinite(m)){h=m;break}}if(h!=null){const l=n.scale(h),m=n.scale(h+r),C=Math.abs(m-l);Number.isFinite(C)&&C>0&&(o=C)}}(!(o>0)||!Number.isFinite(o))&&(o=(Number.isFinite(i??Number.NaN)?i:0)/Math.max(1,t.length));let s=0;const a=e.barWidth;if(typeof a=="number")s=Number.isFinite(a)?Math.max(0,a):0;else if(typeof a=="string"){const h=df(a);s=h==null?0:o*ff(h)}const c=Number.isFinite(e.barMinWidth)?Math.max(0,e.barMinWidth):0,u=Number.isFinite(e.barMaxWidth)?Math.max(0,e.barMaxWidth):Number.POSITIVE_INFINITY,p=Math.max(c,u);return s=Math.min(Math.max(s,c),p),Number.isFinite(s)?s:0}const Ei=new WeakMap,yf=e=>{const t=Ei.get(e);if(t!==void 0)return t;let n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=Pn(e[i]);if(!Number.isFinite(r)||r<n)return Ei.set(e,!1),!1;n=r}return Ei.set(e,!0),!0},gf=(e,t)=>{let n=0,i=e.length;for(;n<i;){const r=n+i>>>1;Pn(e[r])<t?n=r+1:i=r}return n};function Hr(e,t,n,i,r,o){if(!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(o)||!(o>0))return null;const s=i.invert(t);if(!Number.isFinite(s))return null;const a=o/2;let c=null,u=Number.POSITIVE_INFINITY;const p=(l,m,C,F)=>{if(Number.isFinite(F)){if(F<u){u=F,c={seriesIndex:l,dataIndex:m,point:C};return}F===u&&c&&(m<c.dataIndex?c={seriesIndex:l,dataIndex:m,point:C}:m===c.dataIndex&&l<c.seriesIndex&&(c={seriesIndex:l,dataIndex:m,point:C}))}},h=l=>{const m=mf(l),C=pf(l);if(!Number.isFinite(m)||!Number.isFinite(C))return!1;const F=r.scale(m),R=r.scale(C);if(!Number.isFinite(F)||!Number.isFinite(R))return!1;const S=Math.min(F,R),y=Math.max(F,R);return n>=S&&n<=y};for(let l=0;l<e.length;l++){const C=e[l].data,F=C.length;if(F===0)continue;if(!yf(C)){for(let y=0;y<F;y++){const b=C[y],w=Pn(b);if(!Number.isFinite(w))continue;const d=i.scale(w);if(!Number.isFinite(d))continue;const g=Math.abs(t-d);g>a||h(b)&&p(l,y,b,g)}continue}const S=gf(C,s);for(let y=S-1;y>=0;y--){const b=C[y],w=Pn(b),d=i.scale(w);if(!Number.isFinite(d))continue;if(d<t-a)break;const g=Math.abs(t-d);g>a||h(b)&&p(l,y,b,g)}for(let y=S;y<F;y++){const b=C[y],w=Pn(b),d=i.scale(w);if(!Number.isFinite(d))continue;if(d>t+a)break;const g=Math.abs(t-d);g>a||h(b)&&p(l,y,b,g)}}return c}const mn=Math.PI*2,Di=e=>{if(!Number.isFinite(e))return 0;const t=e%mn;return t<0?t+mn:t};function qr(e,t,n,i,r){if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(i.x)||!Number.isFinite(i.y))return null;const o=Number.isFinite(r.inner)?Math.max(0,r.inner):0,s=Number.isFinite(r.outer)?Math.max(0,r.outer):0;if(!(s>0))return null;const a=e-i.x,c=i.y-t,u=Math.hypot(a,c);if(!Number.isFinite(u)||u<=o||u>s)return null;const p=Di(Math.atan2(c,a)),h=n.series,l=h.data;let m=0,C=0;for(let b=0;b<l.length;b++){const w=l[b],d=w==null?void 0:w.value;typeof d=="number"&&Number.isFinite(d)&&d>0&&w.visible!==!1&&(m+=d,C++)}if(!(m>0)||C===0)return null;const F=typeof h.startAngle=="number"&&Number.isFinite(h.startAngle)?h.startAngle:90;let R=Di(F*Math.PI/180),S=0,y=0;for(let b=0;b<l.length;b++){const w=l[b],d=w==null?void 0:w.value;if(typeof d!="number"||!Number.isFinite(d)||d<=0||(w==null?void 0:w.visible)===!1)continue;y++;const g=y===C;let M=d/m*mn;if(g?M=Math.max(0,mn-S):M=Math.max(0,Math.min(mn,M)),S+=M,!(M>0))continue;const I=R,T=C===1?R+mn:Di(R+M);R=Di(R+M);let E=T-I;E<0&&(E+=mn);let f=p-I;if(f<0&&(f+=mn),f<=E)return{seriesIndex:n.seriesIndex,dataIndex:b,slice:w}}return null}const zn=(e,t)=>{if(!Number.isFinite(t))throw new Error(`${e} must be a finite number. Received: ${String(t)}`)};function an(){let e=0,t=1,n=0,i=1;const r={domain(o,s){return zn("domain min",o),zn("domain max",s),e=o,t=s,r},range(o,s){return zn("range min",o),zn("range max",s),n=o,i=s,r},scale(o){if(!Number.isFinite(o))return Number.NaN;if(e===t)return(n+i)/2;const s=(o-e)/(t-e);return n+s*(i-n)},invert(o){if(!Number.isFinite(o))return Number.NaN;if(e===t)return e;if(n===i)return(e+t)/2;const s=(o-n)/(i-n);return e+s*(t-e)}};return r}function xf(){let e=[],t=new Map,n=0,i=1;const r=s=>{const a=new Map;for(let c=0;c<s.length;c++){const u=s[c];if(a.has(u))throw new Error(`Category domain must not contain duplicates. Duplicate: ${JSON.stringify(u)}`);a.set(u,c)}t=a},o={domain(s){return e=[...s],r(e),o},range(s,a){return zn("range min",s),zn("range max",a),n=s,i=a,o},categoryIndex(s){const a=t.get(s);return a===void 0?-1:a},bandwidth(){const s=e.length;return s===0?0:Math.abs((i-n)/s)},scale(s){const a=e.length;if(a===0)return(n+i)/2;const c=o.categoryIndex(s);if(c<0)return Number.NaN;const u=(i-n)/a;return n+(c+.5)*u}};return o}const bf=e=>{switch(e){case"start":return{translateX:"0%",originX:"0%"};case"middle":return{translateX:"-50%",originX:"50%"};case"end":return{translateX:"-100%",originX:"100%"}}};function Is(e){const t=getComputedStyle(e),n=t.position,i=t.overflow,r=n==="static",o=i==="hidden"||i==="scroll"||i==="auto",s=r?e.style.position:null,a=o?e.style.overflow:null;r&&(e.style.position="relative"),o&&(e.style.overflow="visible");const c=document.createElement("div");c.style.position="absolute",c.style.inset="0",c.style.pointerEvents="none",c.style.overflow="visible",c.style.zIndex="10",e.appendChild(c);let u=!1;return{clear:()=>{u||c.replaceChildren()},addLabel:(m,C,F,R)=>{if(u)return document.createElement("span");const S=document.createElement("span");S.textContent=m,S.style.position="absolute",S.style.left=`${C}px`,S.style.top=`${F}px`,S.style.pointerEvents="none",S.style.userSelect="none",S.style.whiteSpace="nowrap",S.style.lineHeight="1",(R==null?void 0:R.fontSize)!=null&&(S.style.fontSize=`${R.fontSize}px`),(R==null?void 0:R.color)!=null&&(S.style.color=R.color);const y=(R==null?void 0:R.rotation)??0,b=(R==null?void 0:R.anchor)??"start",{translateX:w,originX:d}=bf(b);return S.style.transformOrigin=`${d} 50%`,S.style.transform=`translateX(${w}) translateY(-50%) rotate(${y}deg)`,c.appendChild(S),S},dispose:()=>{if(!u){u=!0;try{c.remove()}finally{s!==null&&(e.style.position=s),a!==null&&(e.style.overflow=a)}}}}}const Ps=(e,t)=>{var i;const n=(i=e.name)==null?void 0:i.trim();return n||`Series ${t+1}`},vf=(e,t,n)=>{var o;const i=(o=e.color)==null?void 0:o.trim();if(i)return i;const r=n.colorPalette;return r.length>0?r[t%r.length]??"#000000":"#000000"},As=(e,t)=>{const n=e==null?void 0:e.trim();return n||`Slice ${t+1}`},wf=(e,t,n,i)=>{const r=e==null?void 0:e.trim();if(r)return r;const o=i.colorPalette,s=o.length;return s>0?o[(t+n)%s]??"#000000":"#000000"};function Cf(e,t="right",n){const r=getComputedStyle(e).position==="static",o=r?e.style.position:null;r&&(e.style.position="relative");const s=document.createElement("div");s.style.position="absolute",s.style.pointerEvents="auto",s.style.userSelect="none",s.style.boxSizing="border-box",s.style.padding="8px",s.style.borderRadius="8px",s.style.borderStyle="solid",s.style.borderWidth="1px",s.style.maxHeight="calc(100% - 16px)",s.style.overflow="auto";const a=document.createElement("div");a.style.display="flex",a.style.gap="8px",s.appendChild(a),n&&(a.addEventListener("click",l=>{const C=l.target.closest("[data-series-index]");if(C){const F=parseInt(C.dataset.seriesIndex,10);if(!isNaN(F)){const R=C.dataset.sliceIndex;if(R!==void 0){const S=parseInt(R,10);if(!isNaN(S)){n(F,S);return}}n(F)}}}),a.addEventListener("keydown",l=>{if(l.key==="Enter"||l.key===" "){const C=l.target.closest("[data-series-index]");if(C){l.preventDefault();const F=parseInt(C.dataset.seriesIndex,10);if(!isNaN(F)){const R=C.dataset.sliceIndex;if(R!==void 0){const S=parseInt(R,10);if(!isNaN(S)){n(F,S);return}}n(F)}}}})),(l=>{switch(s.style.top="",s.style.right="",s.style.bottom="",s.style.left="",s.style.maxWidth="",a.style.flexDirection="",a.style.flexWrap="",a.style.alignItems="",l){case"right":{s.style.top="8px",s.style.right="8px",s.style.maxWidth="40%",a.style.flexDirection="column",a.style.flexWrap="nowrap",a.style.alignItems="flex-start";return}case"left":{s.style.top="8px",s.style.left="8px",s.style.maxWidth="40%",a.style.flexDirection="column",a.style.flexWrap="nowrap",a.style.alignItems="flex-start";return}case"top":{s.style.top="8px",s.style.left="8px",s.style.right="8px",a.style.flexDirection="row",a.style.flexWrap="wrap",a.style.alignItems="center";return}case"bottom":{s.style.bottom="8px",s.style.left="8px",s.style.right="8px",a.style.flexDirection="row",a.style.flexWrap="wrap",a.style.alignItems="center";return}}})(t),e.appendChild(s);let u=!1;return{update:(l,m)=>{if(u)return;s.style.color=m.textColor,s.style.background=m.backgroundColor,s.style.borderColor=m.axisLineColor,s.style.fontFamily=m.fontFamily,s.style.fontSize=`${m.fontSize}px`;const C=[];for(let F=0;F<l.length;F++){const R=l[F];if(R.type==="pie")for(let S=0;S<R.data.length;S++){const y=R.data[S],b=(y==null?void 0:y.visible)!==!1,w=document.createElement("div");w.style.display="flex",w.style.alignItems="center",w.style.gap="6px",w.style.lineHeight="1.1",w.style.whiteSpace="nowrap",w.style.cursor=n?"pointer":"default",w.style.opacity=b?"1":"0.5",w.style.transition="opacity 0.2s",n&&(w.setAttribute("role","button"),w.setAttribute("aria-pressed",String(b)),w.setAttribute("aria-label",`Toggle ${As(y==null?void 0:y.name,S)} visibility`),w.tabIndex=0,w.dataset.seriesIndex=String(F),w.dataset.sliceIndex=String(S));const d=document.createElement("div");d.style.width="10px",d.style.height="10px",d.style.borderRadius="2px",d.style.flex="0 0 auto",d.style.background=wf(y==null?void 0:y.color,F,S,m),d.style.border=`1px solid ${m.axisLineColor}`;const g=document.createElement("span");g.textContent=As(y==null?void 0:y.name,S),g.style.textDecoration=b?"none":"line-through",w.appendChild(d),w.appendChild(g),C.push(w)}else{const S=R.visible!==!1,y=document.createElement("div");y.style.display="flex",y.style.alignItems="center",y.style.gap="6px",y.style.lineHeight="1.1",y.style.whiteSpace="nowrap",y.style.cursor=n?"pointer":"default",y.style.opacity=S?"1":"0.5",y.style.transition="opacity 0.2s",n&&(y.setAttribute("role","button"),y.setAttribute("aria-pressed",String(S)),y.setAttribute("aria-label",`Toggle ${Ps(R,F)} visibility`),y.tabIndex=0,y.dataset.seriesIndex=String(F));const b=document.createElement("div");b.style.width="10px",b.style.height="10px",b.style.borderRadius="2px",b.style.flex="0 0 auto",b.style.background=vf(R,F,m),b.style.border=`1px solid ${m.axisLineColor}`;const w=document.createElement("span");w.textContent=Ps(R,F),w.style.textDecoration=S?"none":"line-through",y.appendChild(b),y.appendChild(w),C.push(y)}}a.replaceChildren(...C)},dispose:()=>{if(!u){u=!0;try{s.remove()}finally{o!==null&&(e.style.position=o)}}}}}const Rs=(e,t,n)=>n<t||e<t?t:e>n?n:e;function Es(e){const n=getComputedStyle(e).position==="static",i=n?e.style.position:null;n&&(e.style.position="relative");const r=document.createElement("div");r.style.position="absolute",r.style.left="0",r.style.top="0",r.style.pointerEvents="none",r.style.userSelect="none",r.style.boxSizing="border-box",r.style.zIndex="var(--chartgpu-tooltip-z, 10)",r.style.padding="var(--chartgpu-tooltip-padding, 6px 8px)",r.style.borderRadius="var(--chartgpu-tooltip-radius, 8px)",r.style.borderStyle="solid",r.style.borderWidth="var(--chartgpu-tooltip-border-width, 1px)",r.style.borderColor="var(--chartgpu-tooltip-border, rgba(224,224,224,0.35))",r.style.boxShadow="var(--chartgpu-tooltip-shadow, 0 6px 18px rgba(0,0,0,0.35))",r.style.maxWidth="var(--chartgpu-tooltip-max-width, min(320px, 100%))",r.style.overflow="hidden",r.style.fontFamily='var(--chartgpu-tooltip-font-family, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji")',r.style.fontSize="var(--chartgpu-tooltip-font-size, 12px)",r.style.lineHeight="var(--chartgpu-tooltip-line-height, 1.2)",r.style.color="var(--chartgpu-tooltip-color, #e0e0e0)",r.style.background="var(--chartgpu-tooltip-bg, rgba(26,26,46,0.95))",r.style.whiteSpace="normal",r.style.opacity="0",r.style.transitionProperty="opacity";const o=140;r.style.transitionDuration=`${o}ms`,r.style.transitionTimingFunction="ease",r.style.willChange="opacity",r.style.display="none",r.style.visibility="hidden",r.setAttribute("role","tooltip"),e.appendChild(r);let s=!1,a=0,c=null,u=null;const p=()=>{c!=null&&(window.clearTimeout(c),c=null),u!=null&&(window.cancelAnimationFrame(u),u=null)},h=()=>r.style.display==="none"||r.style.visibility==="hidden",l=()=>{const R=r.style.visibility;r.style.visibility="hidden";const S=r.offsetWidth,y=r.offsetHeight;return r.style.visibility=R,{width:S,height:y}};return{show:(R,S,y)=>{if(s)return;a+=1,p();const b=h();r.innerHTML=y;const w=12,d=12,g=8;r.style.display="block",r.style.visibility="hidden";const{width:v,height:M}=l(),I=e.clientWidth,T=e.clientHeight;let E=R+w,f=S+d;if(E+v>I-g&&(E=R-w-v),f+M>T-g&&(f=S-d-M),E=Rs(E,g,I-g-v),f=Rs(f,g,T-g-M),r.style.left=`${E}px`,r.style.top=`${f}px`,r.style.visibility="visible",b){r.style.opacity="0";const x=a;u=window.requestAnimationFrame(()=>{u=null,!s&&x===a&&(r.style.opacity="1")})}else r.style.opacity="1"},hide:()=>{if(s)return;if(a+=1,p(),r.style.display==="none"||r.style.visibility==="hidden"){r.style.opacity="0",r.style.visibility="hidden",r.style.display="none";return}r.style.opacity="0";const R=a;c=window.setTimeout(()=>{c=null,!s&&R===a&&(r.style.visibility="hidden",r.style.display="none")},o+50)},dispose:()=>{if(!s){s=!0;try{p(),r.remove()}finally{i!==null&&(e.style.position=i)}}}}}const Vi="—";function Yt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function In(e){if(!Number.isFinite(e))return Vi;const i=(Object.is(e,-0)?0:e).toFixed(2).replace(/\.?0+$/,"");return i==="-0"?"0":i}function la(e){const t=e.seriesName.trim();return t.length>0?t:`Series ${e.seriesIndex+1}`}function ua(e){const t=e.trim();return t.length===0?"#888":/^#[0-9a-fA-F]{3}$/.test(t)||/^#[0-9a-fA-F]{6}$/.test(t)||/^#[0-9a-fA-F]{8}$/.test(t)||/^rgba?\(\s*\d{1,3}\s*(?:,\s*|\s+)\d{1,3}\s*(?:,\s*|\s+)\d{1,3}(?:\s*(?:,\s*|\/\s*)(?:0|1|0?\.\d+))?\s*\)$/.test(t)||/^[a-zA-Z]+$/.test(t)?t:"#888"}function fa(e){return e.length===5}function Mf(e,t){if(!Number.isFinite(e)||!Number.isFinite(t)||e===0)return Vi;const n=(t-e)/e*100;return Number.isFinite(n)?`${n>0?"+":""}${n.toFixed(2)}%`:Vi}function da(e,t){const n=Yt(la(e)),i=Yt(t);return['<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;">','<span style="display:flex;align-items:center;gap:8px;min-width:0;">',`<span style="width:8px;height:8px;border-radius:999px;flex:0 0 auto;background-color:${Yt(ua(e.color))};"></span>`,`<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${n}</span>`,"</span>",`<span style="font-variant-numeric:tabular-nums;white-space:nowrap;">${i}</span>`,"</div>"].join("")}function ma(e){const[,t,n,i,r]=e.value,o=Yt(la(e)),s=Yt(ua(e.color)),a=In(t),c=In(r),u=In(i),p=In(n),h=n>t,l=h?"▲":"▼",m=h?"#22c55e":"#ef4444",C=Mf(t,n),F=`O: ${a} H: ${c} L: ${u} C: ${p}`,R=Yt(F),S=Yt(l),y=Yt(C),b=Yt(m);return['<div style="display:flex;flex-direction:column;gap:4px;">','<div style="display:flex;align-items:center;gap:8px;">',`<span style="width:8px;height:8px;border-radius:999px;flex:0 0 auto;background-color:${s};"></span>`,`<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;">${o}</span>`,"</div>",`<div style="font-variant-numeric:tabular-nums;white-space:nowrap;font-size:0.9em;">${R}</div>`,'<div style="display:flex;align-items:center;gap:6px;font-variant-numeric:tabular-nums;">',`<span style="color:${b};font-weight:700;">${S}</span>`,`<span style="color:${b};font-weight:600;">${y}</span>`,"</div>","</div>"].join("")}function Ff(e){return ma(e)}function ni(e){return fa(e.value)?Ff(e):da(e,In(e.value[1]))}function Ur(e){if(e.length===0)return"";const t=`x: ${In(e[0].value[0])}`,n=`<div style="margin:0 0 6px 0;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap;">${Yt(t)}</div>`,i=e.map(r=>fa(r.value)?ma(r):da(r,In(r.value[1]))).join('<div style="height:4px;"></div>');return`${n}${i}`}const Sf=e=>Number.isFinite(e)?e:0,Nf=e=>Number.isFinite(e)?e:null;function Ds(){const e=new Map;function t(o,s,a,c,u,p){const h=Symbol("Animation");if(Array.isArray(o)||Array.isArray(s)){if(!Array.isArray(o)||!Array.isArray(s))throw new Error('Array animation requires both "from" and "to" to be arrays');if(o.length!==s.length)throw new Error(`Array animation length mismatch: from.length=${o.length}, to.length=${s.length}`);const l=new Array(o.length);return e.set(h,{kind:"array",from:o,to:s,duration:a,easing:c,onUpdate:u,onComplete:p,startTime:null,out:l}),h}return e.set(h,{kind:"scalar",from:o,to:s,duration:a,easing:c,onUpdate:u,onComplete:p,startTime:null}),h}function n(o){e.delete(o)}function i(){e.clear()}function r(o){var c;const s=Nf(o);if(s===null)return;const a=Array.from(e.keys());for(const u of a){const p=e.get(u);if(!p)continue;const h=p.startTime??s;p.startTime===null&&e.set(u,{...p,startTime:h});const l=Sf(p.duration),m=Math.max(0,s-h),C=l<=0||m>=l,F=l<=0?1:m/l,R=C?1:p.easing(F);if(p.kind==="scalar"){const S=p.from+(p.to-p.from)*R;if(p.onUpdate(S),!e.has(u))continue}else{const S=p.out.length;for(let y=0;y<S;y++){const b=p.from[y]??0,w=p.to[y]??0;p.out[y]=b+(w-b)*R}if(p.onUpdate(p.out),!e.has(u))continue}C&&((c=p.onComplete)==null||c.call(p),e.delete(u))}}return{animate:t,cancel:n,cancelAll:i,update:r}}const or=e=>Number.isNaN(e)||e<=0?0:e>=1?1:e;function Bs(e){return or(e)}function Tf(e){const n=1-or(e);return 1-n*n*n}function If(e){const t=or(e);if(t<.5)return 4*t*t*t;const n=-2*t+2;return 1-n*n*n/2}function Pf(e){const t=or(e),n=7.5625,i=2.75;if(t<1/i)return n*t*t;if(t<2/i){const o=t-1.5/i;return n*o*o+.75}if(t<2.5/i){const o=t-2.25/i;return n*o*o+.9375}const r=t-2.625/i;return n*r*r+.984375}function Af(e){switch(e){case"linear":return Bs;case"cubicOut":return Tf;case"cubicInOut":return If;case"bounceOut":return Pf;default:return Bs}}const Vn=Ea;function Rf(e){return e?e.clientWidth:0}function Ef(e){if(!e)return{width:0,height:0};const t=Number.isFinite(devicePixelRatio)&&devicePixelRatio>0?devicePixelRatio:1;return{width:e.width/t,height:e.height/t}}const Df="bgra8unorm",Zr=5,Ki=24*60*60*1e3,Bf=30*Ki,Lf=365*Ki,kf=9,_r=1,Uf=6,Ji=e=>typeof e=="number"&&Number.isFinite(e)?e:null,yn=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,_f=2e4,Gf=e=>{throw new Error(`RenderCoordinator: unreachable value: ${String(e)}`)},Oi=e=>Array.isArray(e),ri=e=>Oi(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},ii=e=>{if(Array.isArray(e))return e.length===0?[]:e.slice();const t=Xe(e),n=new Array(t);for(let i=0;i<t;i++){const r=Ee(e,i),o=We(e,i);n[i]=[r,o]}return n},zf=(e,t)=>{if(t.length===0)return e;let n=e;if(!n){const a=sn(t);if(!a)return e;n=a}let i=n.xMin,r=n.xMax,o=n.yMin,s=n.yMax;for(let a=0;a<t.length;a++){const{x:c,y:u}=ri(t[a]);!Number.isFinite(c)||!Number.isFinite(u)||(c<i&&(i=c),c>r&&(r=c),u<o&&(o=u),u>s&&(s=u))}return i===r&&(r=i+1),o===s&&(s=o+1),{xMin:i,xMax:r,yMin:o,yMax:s}},Vf=(e,t)=>{if(t.length===0)return e;let n=(e==null?void 0:e.xMin)??Number.POSITIVE_INFINITY,i=(e==null?void 0:e.xMax)??Number.NEGATIVE_INFINITY,r=(e==null?void 0:e.yMin)??Number.POSITIVE_INFINITY,o=(e==null?void 0:e.yMax)??Number.NEGATIVE_INFINITY;for(let s=0;s<t.length;s++){const a=t[s],c=Ht(a)?a[0]:a.timestamp,u=Ht(a)?a[3]:a.low,p=Ht(a)?a[4]:a.high;!Number.isFinite(c)||!Number.isFinite(u)||!Number.isFinite(p)||(c<n&&(n=c),c>i&&(i=c),u<r&&(r=u),p>o&&(o=p))}return!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(o)?e:(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o})},pa=(e,t)=>{let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(let s=0;s<e.length;s++){const a=e[s];if(a.type==="pie")continue;const c=(t==null?void 0:t[s])??null;if(c){const l=c;if(Number.isFinite(l.xMin)&&Number.isFinite(l.xMax)&&Number.isFinite(l.yMin)&&Number.isFinite(l.yMax)){l.xMin<n&&(n=l.xMin),l.xMax>i&&(i=l.xMax),l.yMin<r&&(r=l.yMin),l.yMax>o&&(o=l.yMax);continue}}const u=a.rawBounds;if(u){const l=u;if(Number.isFinite(l.xMin)&&Number.isFinite(l.xMax)&&Number.isFinite(l.yMin)&&Number.isFinite(l.yMax)){l.xMin<n&&(n=l.xMin),l.xMax>i&&(i=l.xMax),l.yMin<r&&(r=l.yMin),l.yMax>o&&(o=l.yMax);continue}}if(a.type==="candlestick"){const l=a.rawData??a.data;for(let m=0;m<l.length;m++){const C=l[m];if(Ht(C)){const F=C[0],R=C[3],S=C[4];if(!Number.isFinite(F)||!Number.isFinite(R)||!Number.isFinite(S))continue;const y=Math.min(R,S),b=Math.max(R,S);F<n&&(n=F),F>i&&(i=F),y<r&&(r=y),b>o&&(o=b)}else{const F=C.timestamp,R=C.low,S=C.high;if(!Number.isFinite(F)||!Number.isFinite(R)||!Number.isFinite(S))continue;const y=Math.min(R,S),b=Math.max(R,S);F<n&&(n=F),F>i&&(i=F),y<r&&(r=y),b>o&&(o=b)}}continue}const p=a.data,h=Xe(p);for(let l=0;l<h;l++){const m=Ee(p,l),C=We(p,l);!Number.isFinite(m)||!Number.isFinite(C)||(m<n&&(n=m),m>i&&(i=m),C<r&&(r=C),C>o&&(o=C))}}return!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(o)?{xMin:0,xMax:1,yMin:0,yMax:1}:(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o})},li=(e,t)=>{let n=e,i=t;if((!Number.isFinite(n)||!Number.isFinite(i))&&(n=0,i=1),n===i)i=n+1;else if(n>i){const r=n;n=i,i=r}return{min:n,max:i}},Ls=(e,t)=>{const n=e.canvas;if(!n)throw new Error("RenderCoordinator: gpuContext.canvas is required.");const i=e.devicePixelRatio??1,r=Number.isFinite(i)&&i>0?i:1,o=n.width,s=n.height;if(!Number.isFinite(o)||!Number.isFinite(s))throw new Error(`RenderCoordinator: Invalid canvas dimensions: width=${o}, height=${s}. Canvas must be initialized with finite dimensions before rendering.`);const a=Math.max(1,Math.floor(o)),c=Math.max(1,Math.floor(s)),u=Number.isFinite(t.grid.left)?t.grid.left:0,p=Number.isFinite(t.grid.right)?t.grid.right:0,h=Number.isFinite(t.grid.top)?t.grid.top:0,l=Number.isFinite(t.grid.bottom)?t.grid.bottom:0,m=Math.max(0,u),C=Math.max(0,p),F=Math.max(0,h),R=Math.max(0,l);return{left:m,right:C,top:F,bottom:R,canvasWidth:a,canvasHeight:c,devicePixelRatio:r}},Of=e=>{const t=Math.max(0,Math.min(255,Math.round(e[0]*255))),n=Math.max(0,Math.min(255,Math.round(e[1]*255))),i=Math.max(0,Math.min(255,Math.round(e[2]*255))),r=Math.max(0,Math.min(1,e[3]));return`rgba(${t},${n},${i},${r})`},ks=(e,t)=>{const n=pt(e);if(!n)return e;const i=Math.max(0,Math.min(1,n[3]*t));return Of([n[0],n[1],n[2],i])},$f=e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:s,devicePixelRatio:a}=e,c=t*a,u=o-n*a,p=i*a,h=s-r*a,l=c/o*2-1,m=u/o*2-1,C=1-p/s*2,F=1-h/s*2;return{left:l,right:m,top:C,bottom:F}},Xt=e=>Math.min(1,Math.max(0,e)),On=(e,t,n)=>Math.min(n,Math.max(t,e|0)),Qi=(e,t,n)=>e+(t-e)*Xt(n),Bi=(e,t,n)=>li(Qi(e.min,t.min,n),Qi(e.max,t.max,n)),Wf=e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,s=e.top*i,a=n-e.bottom*i,c=On(Math.floor(r),0,Math.max(0,t)),u=On(Math.floor(s),0,Math.max(0,n)),p=On(Math.ceil(o),0,Math.max(0,t)),h=On(Math.ceil(a),0,Math.max(0,n)),l=Math.max(0,p-c),m=Math.max(0,h-u);return{x:c,y:u,w:l,h:m}},jr=(e,t)=>(e+1)/2*t,Us=(e,t)=>(1-e)/2*t,Ht=Hi,ai=(e,t)=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;const n=e.trim();if(n.length===0)return null;if(n.endsWith("%")){const r=Number.parseFloat(n.slice(0,-1));return Number.isFinite(r)?r/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},Xf=(e,t,n)=>{const i=(e==null?void 0:e[0])??"50%",r=(e==null?void 0:e[1])??"50%",o=ai(i,t),s=ai(r,n);return{x:Number.isFinite(o)?o:t*.5,y:Number.isFinite(s)?s:n*.5}},Yf=e=>Array.isArray(e),Hf=(e,t)=>{if(e==null)return{inner:0,outer:t*.7};if(Yf(e)){const r=ai(e[0],t),o=ai(e[1],t),s=Math.max(0,Number.isFinite(r)?r:0),a=Math.max(s,Number.isFinite(o)?o:t*.7);return{inner:s,outer:Math.min(t,a)}}const n=ai(e,t),i=Math.max(0,Number.isFinite(n)?n:t*.7);return{inner:0,outer:Math.min(t,i)}},Gt=e=>String(Math.trunc(e)).padStart(2,"0"),qf=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Zf=(e,t)=>{if(!Number.isFinite(e))return null;(!Number.isFinite(t)||t<0)&&(t=0);const n=new Date(e);if(!Number.isFinite(n.getTime()))return null;const i=n.getFullYear(),r=n.getMonth()+1,o=n.getDate(),s=n.getHours(),a=n.getMinutes();return t<Ki?`${Gt(s)}:${Gt(a)}`:t<=7*Ki?`${Gt(r)}/${Gt(o)} ${Gt(s)}:${Gt(a)}`:t<3*Bf?`${Gt(r)}/${Gt(o)}`:t<=Lf?`${qf[n.getMonth()]??Gt(r)} ${Gt(o)}`:`${i}/${Gt(r)}`},$i=(e,t,n)=>{const i=Math.max(1,Math.floor(n)),r=new Array(i);for(let o=0;o<i;o++){const s=i===1?.5:o/(i-1);r[o]=e+s*(t-e)}return r},jf=e=>{const{axisMin:t,axisMax:n,xScale:i,plotClipLeft:r,plotClipRight:o,canvasCssWidth:s,visibleRangeMs:a,measureCtx:c,measureCache:u,fontSize:p,fontFamily:h}=e,l=Ji(t)??i.invert(r),m=Ji(n)??i.invert(o);if(!c||s<=0)return{tickCount:Zr,tickValues:$i(l,m,Zr)};c.font=`${p}px ${h}`,u&&u.size>2e3&&u.clear();const C=u?`${p}px ${h}@@`:null;for(let F=kf;F>=_r;F--){const R=$i(l,m,F);let S=Number.NEGATIVE_INFINITY,y=!0;for(let b=0;b<R.length;b++){const w=R[b],d=Zf(w,a);if(d==null)continue;const g=(()=>{if(!C)return c.measureText(d).width;const f=C+d,x=u.get(f);if(x!=null)return x;const N=c.measureText(d).width;return u.set(f,N),N})(),v=i.scale(w),M=jr(v,s),I=F===1?"middle":b===0?"start":b===R.length-1?"end":"middle",T=I==="start"?M:I==="end"?M-g:M-g*.5,E=I==="start"?M+g:I==="end"?M:M+g*.5;if(T<S+Uf){y=!1;break}S=E}if(y)return{tickCount:F,tickValues:R}}return{tickCount:_r,tickValues:$i(l,m,_r)}},Nn=(e,t)=>{const n=pa(e.series,t),i=yn(e.xAxis.min)??n.xMin,r=yn(e.xAxis.max)??n.xMax;return li(i,r)},Kf=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=e[i];if(r.type==="pie")continue;if(r.type==="candlestick"){const a=r.data;for(let c=0;c<a.length;c++){const u=a[c],p=Ht(u)?u[3]:u.low,h=Ht(u)?u[4]:u.high;if(!Number.isFinite(p)||!Number.isFinite(h))continue;const l=Math.min(p,h),m=Math.max(p,h);l<t&&(t=l),m>n&&(n=m)}continue}const o=r.data,s=Xe(o);for(let a=0;a<s;a++){const c=We(o,a);Number.isFinite(c)&&(c<t&&(t=c),c>n&&(n=c))}}return!Number.isFinite(t)||!Number.isFinite(n)?{xMin:0,xMax:1,yMin:0,yMax:1}:(t===n&&(n=t+1),{xMin:0,xMax:1,yMin:t,yMax:n})},Gr=(e,t,n)=>{const i=yn(e.yAxis.min),r=yn(e.yAxis.max);if(i!==void 0&&r!==void 0)return li(i,r);const o=e.yAxis.autoBounds??"visible";let s;o==="visible"&&n?s=n:s=pa(e.series,t);const a=i??s.yMin,c=r??s.yMax;return li(a,c)},Tn=(e,t)=>{if(!t)return{...e,spanFraction:1};const n=e.max-e.min;if(!Number.isFinite(n)||n===0)return{...e,spanFraction:1};const i=t.start,r=t.end,o=e.min+i/100*n,s=e.min+r/100*n,a=li(o,s),c=(r-i)/100,u=Number.isFinite(c)?Math.max(0,Math.min(1,c)):1;return{min:a.min,max:a.max,spanFraction:u}},ha=e=>{if(e===!1||e==null)return null;const t=e===!0?{}:e;if(!t)return null;const n=t.duration??300,i=t.delay??0,r=Number.isFinite(n)?Math.max(0,n):300,o=Number.isFinite(i)?Math.max(0,i):0;return{durationMs:r,delayMs:o,easing:Af(t.easing)}},Jf=e=>ha(e),Qf=e=>ha(e),zr=(e,t,n,i,r)=>{const o=e.point,s=Ht(o)?o[0]:o.timestamp,a=Ht(o)?o[1]:o.open,c=Ht(o)?o[2]:o.close;if(!Number.isFinite(s)||!Number.isFinite(a)||!Number.isFinite(c))return null;const u=(a+c)/2,p=t.scale(s),h=n.scale(u);if(!Number.isFinite(p)||!Number.isFinite(h))return null;const l=i.left+p,m=i.top+h,C=Vn(r)?r.offsetLeft+l:l,F=Vn(r)?r.offsetTop+m:m;return!Number.isFinite(C)||!Number.isFinite(F)?null:{x:C,y:F}},_s=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;i<e.length;i++){const r=e[i].data,o=Xe(r);for(let s=0;s<o;s++){const a=We(r,s);Number.isFinite(a)&&(a<t&&(t=a),a>n&&(n=a))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t)<Math.abs(n)?t:n},ed=(e,t,n)=>{const i=t.invert(n.bottom),r=t.invert(n.top),o=Math.min(i,r),s=Math.max(i,r);return!Number.isFinite(o)||!Number.isFinite(s)?_s(e):o<=0&&0<=s?0:o>0?o:s<0?s:_s(e)},td=(e,t,n,i)=>{const r=Xt(i);if(r>=1)return e;const o=ed(n,e,t),s=e.scale(o),a={domain(c,u){return e.domain(c,u),a},range(c,u){return e.range(c,u),a},scale(c){const u=e.scale(c);return!Number.isFinite(u)||!Number.isFinite(s)?u:s+(u-s)*r},invert(c){return e.invert(c)}};return a};function nd(e,t,n){var vo;if(!e.initialized)throw new Error("RenderCoordinator: gpuContext must be initialized.");const i=e.device;if(!i)throw new Error("RenderCoordinator: gpuContext.device is required.");if(!e.canvas)throw new Error("RenderCoordinator: gpuContext.canvas is required.");if(!e.canvasContext)throw new Error("RenderCoordinator: gpuContext.canvasContext is required.");i.lost.then(D=>{var z;(z=n==null?void 0:n.onDeviceLost)==null||z.call(n,D.message||D.reason||"unknown")}).catch(()=>{});const r=e.preferredFormat??Df,o=Vn(e.canvas)?e.canvas.parentElement:null,s=o?Is(o):null,a=o?Is(o):null,u=o?Cf(o,"right",(D,z)=>{if(l)return;const U=m.series;if(D<0||D>=U.length)return;const $=U[D];if(!$)return;if(z!==void 0&&$.type==="pie"){const K=$.data;if(z<0||z>=K.length)return;const ae=K.map((J,xe)=>xe===z?{...J,visible:J.visible===!1}:J),fe=U.map((J,xe)=>xe===D?{...J,data:ae}:J);fr({...m,series:fe});return}const ie=U.map((K,ae)=>ae===D?{...K,visible:K.visible===!1}:K);fr({...m,series:ie})}):null,p=(()=>{if(typeof document>"u")return null;try{return document.createElement("canvas").getContext("2d")}catch{return null}})(),h=p?new Map:null;let l=!1,m=t,C=t.series.length,F="pending",R=0;const S=Ds();let y=null,b=!1;const w=Ds();let d=null,g=1,v=null;const M={cartesianDataBySeriesIndex:[],pieDataBySeriesIndex:[]},I=()=>{M.cartesianDataBySeriesIndex.length=0,M.pieDataBySeriesIndex.length=0},T=(D,z,U,$)=>{if(D.length!==z.length)return null;const ie=z.length;if(ie===0)return $??[];const K=$&&$.length===ie?$:(()=>{const fe=new Array(ie);for(let J=0;J<ie;J++){const xe=z[J],{x:pe}=ri(xe),ye=Oi(xe)?xe[2]:xe==null?void 0:xe.size;fe[J]=Oi(xe)?ye==null?[pe,0]:[pe,0,ye]:ye==null?{x:pe,y:0}:{x:pe,y:0,size:ye}}return fe})(),ae=Xt(U);for(let fe=0;fe<ie;fe++){const J=ri(D[fe]).y,xe=ri(z[fe]).y,pe=Number.isFinite(J)&&Number.isFinite(xe)?Qi(J,xe,ae):xe,ye=K[fe];Oi(ye)?ye[1]=pe:ye.y=pe}return K},E=(D,z,U,$)=>{var xe,pe;const ie=D.data,K=z.data;if(ie.length!==K.length)return z;const ae=K.length,fe=$&&$.length===ae?$:(()=>{const ye=new Array(ae);for(let Ie=0;Ie<ae;Ie++)ye[Ie]={...K[Ie],value:0};return ye})(),J=Xt(U);for(let ye=0;ye<ae;ye++){const Ie=(xe=ie[ye])==null?void 0:xe.value,Ae=(pe=K[ye])==null?void 0:pe.value,Te=typeof Ie=="number"&&typeof Ae=="number"&&Number.isFinite(Ie)&&Number.isFinite(Ae)?Math.max(0,Qi(Ie,Ae,J)):typeof Ae=="number"&&Number.isFinite(Ae)?Ae:0;fe[ye].value=Te}return{...z,data:fe}},f=(D,z,U,$)=>{if(D.length!==z.length)return z;const ie=new Array(z.length);for(let K=0;K<z.length;K++){const ae=D[K],fe=z[K];if(ae.type!==fe.type){ie[K]=fe;continue}if(fe.type==="pie"){const Te=($==null?void 0:$.pieDataBySeriesIndex[K])??null,Nt=E(ae,fe,U,Te);$&&($.pieDataBySeriesIndex[K]=Nt.data),ie[K]=Nt;continue}const J=ae,xe=fe,pe=J.data,ye=xe.data;if(pe.length!==ye.length){ie[K]=fe;continue}if(ye.length>_f){ie[K]=fe;continue}const Ie=($==null?void 0:$.cartesianDataBySeriesIndex[K])??null,Ae=T(pe,ye,U,Ie);if(!Ae){ie[K]=fe;continue}$&&($.cartesianDataBySeriesIndex[K]=Ae),ie[K]={...fe,data:Ae}}return ie},x=(D,z,U)=>{const $=Bi(D.from.xBaseDomain,D.to.xBaseDomain,z),ie=Tn($,U),K=Bi(D.from.yBaseDomain,D.to.yBaseDomain,z),ae=f(D.from.series,D.to.series,z,null);return{xBaseDomain:$,xVisibleDomain:{min:ie.min,max:ie.max},yBaseDomain:K,series:ae}},N=new Set,A=new Set;let P=new Array(t.series.length).fill(null),L=new Array(t.series.length).fill(null),B=m.series,V=m.series,_=null;const re=D=>{if((D.yAxis.autoBounds??"visible")!=="visible")return!1;const U=yn(D.yAxis.min),$=yn(D.yAxis.max);return!(U!==void 0&&$!==void 0)},Y=()=>{re(m)?_=Kf(V):_=null};let W=[],Z=!1,oe=null,ee=null,q=null,de=!1,G=!1;const te=new Map;let X=new Array(m.series.length).fill("unknown");const Q=new Set;let ne=o&&((vo=m.tooltip)==null?void 0:vo.show)!==!1?Es(o):null,H=null,O=null,se=null;const ce=(D,z,U,$)=>{ne==null||ne.show(D,z,U)},le=()=>{ne==null||ne.hide()},me=()=>{H=null,O=null,se=null,le()};((D,z)=>{u==null||u.update(D,z)})(m.series,m.theme);let we=ka(i);const it=dl(i,{targetFormat:r}),Ke=qo(i,{targetFormat:r}),et=qo(i,{targetFormat:r}),ke=Gu(i,{targetFormat:r});ke.setVisible(!1);const he=Xu(i,{targetFormat:r});he.setVisible(!1);const be=4,Ge=xs(i,{targetFormat:r}),ze=ws(i,{targetFormat:r}),rt=xs(i,{targetFormat:r,sampleCount:be}),Ze=ws(i,{targetFormat:r,sampleCount:be});let ht=null,gt=null,ot=null,Ft=null,It=0,Bt=0,Lt=null;const k=`
|
|
1103
|
+
struct VSOut { @builtin(position) pos: vec4f };
|
|
1104
|
+
|
|
1105
|
+
@vertex
|
|
1106
|
+
fn vsMain(@builtin(vertex_index) i: u32) -> VSOut {
|
|
1107
|
+
var positions = array<vec2f, 3>(
|
|
1108
|
+
vec2f(-1.0, -1.0),
|
|
1109
|
+
vec2f( 3.0, -1.0),
|
|
1110
|
+
vec2f(-1.0, 3.0)
|
|
1111
|
+
);
|
|
1112
|
+
var o: VSOut;
|
|
1113
|
+
o.pos = vec4f(positions[i], 0.0, 1.0);
|
|
1114
|
+
return o;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// Using textureLoad (no filtering) for pixel-exact blit into the MSAA overlay pass.
|
|
1118
|
+
@group(0) @binding(0) var srcTex: texture_2d<f32>;
|
|
1119
|
+
|
|
1120
|
+
@fragment
|
|
1121
|
+
fn fsMain(@builtin(position) pos: vec4f) -> @location(0) vec4f {
|
|
1122
|
+
let xy = vec2<i32>(pos.xy);
|
|
1123
|
+
return textureLoad(srcTex, xy, 0);
|
|
1124
|
+
}
|
|
1125
|
+
`,j=i.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}}]}),ue=Tt(i,{label:"renderCoordinator/overlayBlitPipeline",bindGroupLayouts:[j],vertex:{code:k,label:"renderCoordinator/overlayBlit.wgsl"},fragment:{code:k,label:"renderCoordinator/overlayBlit.wgsl",formats:r},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:be}});let Se=null;const De=D=>{if(D)try{D.destroy()}catch{}},Ye=(D,z)=>{const U=Number.isFinite(D)?Math.max(1,Math.floor(D)):1,$=Number.isFinite(z)?Math.max(1,Math.floor(z)):1;ht&&ot&&Se&&It===U&&Bt===$&&Lt===r||(De(ht),De(ot),ht=i.createTexture({label:"renderCoordinator/mainColorTexture",size:{width:U,height:$},format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),gt=ht.createView(),ot=i.createTexture({label:"renderCoordinator/annotationOverlayMsaaTexture",size:{width:U,height:$},sampleCount:be,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}),Ft=ot.createView(),Se=i.createBindGroup({label:"renderCoordinator/overlayBlitBindGroup",layout:j,entries:[{binding:0,resource:gt}]}),It=U,Bt=$,Lt=r)},Me=Ls(e,m),ve=Vn(e.canvas)?Ju(e.canvas,Me):null;let Ce={source:"mouse",x:0,y:0,gridX:0,gridY:0,isInGrid:!1,hasPointer:!1},Fe=null,yt;const St=new Set;let tt=null;const kt=(D,z)=>{const U=Array.from(St);for(const $ of U)$(D,z)},qt=(D,z)=>{const U=D!==null&&Number.isFinite(D)?D:null;Fe===U&&yt===z||(Fe=U,yt=z,kt(Fe,yt))},He=()=>{var D;(D=n==null?void 0:n.onRequestRender)==null||D.call(n)},Ut=D=>D?Number.isFinite(D.start)&&Number.isFinite(D.end)&&D.start<=0&&D.end>=100:!0,at=()=>{oe!==null&&(cancelAnimationFrame(oe),oe=null),ee!==null&&(clearTimeout(ee),ee=null),Z=!1},ct=()=>{q!==null&&(clearTimeout(q),q=null)},ar=()=>{var fe;if(te.size===0)return!1;Q.clear();const D=(Ne==null?void 0:Ne.getRange())??null,z=Ut(D),U=m.autoScroll===!0&&Ne!=null&&m.xAxis.min==null&&m.xAxis.max==null,$=Nn(m,L),ie=D?Tn($,D):null;let K=!1;for(const[J,xe]of te){if(xe.length===0)continue;const pe=m.series[J];if(!(!pe||pe.type==="pie")){if(K=!0,pe.type==="candlestick"){let ye=P[J];if(!ye){const Ae=pe.rawData??pe.data;ye=Ae.length===0?[]:Ae.slice(),P[J]=ye,L[J]=pe.rawBounds??null}const Ie=xe;ye.push(...Ie),L[J]=Vf(L[J],Ie)}else{let ye=P[J];if(!ye){const Te=pe.rawData??pe.data;ye=ii(Te),P[J]=ye,L[J]=pe.rawBounds??sn(Te)}const Ie=xe;if(pe.type==="line"&&pe.sampling==="none"&&z&&X[J]==="fullRawLine")try{we.appendSeries(J,Ie),Q.add(J)}catch{}else pe.type==="line"&&pe.sampling!=="none"&&!A.has(J)&&(A.add(J),console.warn(`[ChartGPU] appendData() on series ${J} with sampling='${pe.sampling}' causes full buffer re-upload every frame. For optimal streaming performance, use sampling='none'. See docs/internal/INCREMENTAL_APPEND_OPTIMIZATION.md for details.`));ye.push(...Ie),L[J]=zf(L[J],Ie)}W[J]=null}}if(te.clear(),!K)return!1;if(Ne){const J=cr(),xe=Ne;(fe=xe.setSpanConstraints)==null||fe.call(xe,J.minSpan,J.maxSpan)}if(U&&D&&ie){const J=D;if(J.end>=99.5){const xe=J.end-J.start,pe=Ne;pe.setRangeAnchored?pe.setRangeAnchored(100-xe,100,"end"):Ne.setRange(100-xe,100)}else{const xe=Nn(m,L),pe=xe.max-xe.min;if(Number.isFinite(pe)&&pe>0){const ye=(ie.min-xe.min)/pe*100,Ie=(ie.max-xe.min)/pe*100,Ae=Math.max(0,Math.min(100,ye)),Te=Math.max(0,Math.min(100,Ie));Ne.setRange(Ae,Te)}}}lr();const ae=(Ne==null?void 0:Ne.getRange())??null;return(ae==null||Ut(ae))&&(V=B,Y()),!0},vt=D=>{if(l)return;const z=(D==null?void 0:D.requestRenderAfter)??!0,U=ar(),$=(Ne==null?void 0:Ne.getRange())??null,ie=Ut($),K=$!=null&&!ie;let ae=!1;de?(de=!1,ct(),!$||ie?(V=B,Y()):fi(),ae=!0):U&&K&&(de=!1,ct(),fi(),ae=!0),(U||ae)&&z&&He()},Ot=D=>{l||Z||(oe!==null&&(cancelAnimationFrame(oe),oe=null),ee!==null&&(clearTimeout(ee),ee=null),Z=!0,oe=requestAnimationFrame(()=>{if(oe=null,l){at();return}ee!==null&&(clearTimeout(ee),ee=null),Z=!1,vt()}),ee=(typeof self<"u"?self:window).setTimeout(()=>{if(l){at();return}Z&&(oe!==null&&(cancelAnimationFrame(oe),oe=null),Z=!1,ee=null,vt())},16))},Zt=()=>{l||(ct(),de=!1,q=(typeof self<"u"?self:window).setTimeout(()=>{q=null,!l&&(de=!0,Ot())},100))},Pe=(D,z)=>{let U,$;const ie=D.getBoundingClientRect();if(!(ie.width>0)||!(ie.height>0))return null;U=ie.width,$=ie.height;const K=U-z.left-z.right,ae=$-z.top-z.bottom;return!(K>0)||!(ae>0)?null:{plotWidthCss:K,plotHeightCss:ae}},Be=(D,z)=>{const U=e.canvas;if(!U)return null;const $=Pe(U,D);if(!$)return null;const ie=an().domain(z.xDomain.min,z.xDomain.max).range(0,$.plotWidthCss),K=an().domain(z.yDomain.min,z.yDomain.max).range($.plotHeightCss,0);return{xScale:ie,yScale:K,plotWidthCss:$.plotWidthCss,plotHeightCss:$.plotHeightCss}},je=(D,z,U)=>{const $=m.series[D],{x:ie,y:K}=ri(U);return{seriesName:($==null?void 0:$.name)??"",seriesIndex:D,dataIndex:z,value:[ie,K],color:($==null?void 0:$.color)??"#888"}},xt=(D,z,U)=>{const $=m.series[D];return Ht(U)?{seriesName:($==null?void 0:$.name)??"",seriesIndex:D,dataIndex:z,value:[U[0],U[1],U[2],U[3],U[4]],color:($==null?void 0:$.color)??"#888"}:{seriesName:($==null?void 0:$.name)??"",seriesIndex:D,dataIndex:z,value:[U.timestamp,U.open,U.close,U.low,U.high],color:($==null?void 0:$.color)??"#888"}},lt=(D,z,U,$,ie)=>{const K=.5*Math.min($,ie);if(!(K>0))return null;for(let ae=D.length-1;ae>=0;ae--){const fe=D[ae];if(fe.type!=="pie"||fe.visible===!1)continue;const J=fe,xe=Xf(J.center,$,ie),pe=Hf(J.radius,K),ye=qr(z,U,{seriesIndex:ae,series:J},xe,pe);if(ye)return ye}return null},cn=(D,z,U,$)=>{for(let ie=D.length-1;ie>=0;ie--){const K=D[ie];if(K.type!=="candlestick"||K.visible===!1)continue;const ae=K,fe=Yr(ae,ae.data,$.xScale,$.plotWidthCss),J=Hr([ae],z,U,$.xScale,$.yScale,fe);if(!J)continue;return{params:xt(ie,J.dataIndex,J.point),match:{point:J.point},seriesIndex:ie}}return null},Pt=D=>{if(Ce={source:"mouse",x:D.x,y:D.y,gridX:D.gridX,gridY:D.gridY,isInGrid:D.isInGrid,hasPointer:!0},D.isInGrid&&tt){const z=tt.xScale.invert(D.gridX);qt(Number.isFinite(z)?z:null,"mouse")}else D.isInGrid||qt(null,"mouse");ke.setVisible(D.isInGrid),He()},jt=D=>{Ce.source==="mouse"&&(Ce={...Ce,isInGrid:!1,hasPointer:!1},ke.setVisible(!1),me(),qt(null,"mouse"),He())};ve&&(ve.on("mousemove",Pt),ve.on("mouseleave",jt));let Ne=null,wt=null,Kt=null,xn=null;const ui=new Set,Ma=D=>{const z=Array.from(ui);for(const U of z)U(D)},Fa=D=>{var ae,fe;const z=(ae=D.dataZoom)==null?void 0:ae.find(J=>(J==null?void 0:J.type)==="inside"),U=(fe=D.dataZoom)==null?void 0:fe.find(J=>(J==null?void 0:J.type)==="slider"),$=z??U;if(!$)return null;const ie=Number.isFinite($.start)?$.start:0,K=Number.isFinite($.end)?$.end:100;return{start:ie,end:K,hasInside:!!z}},Wn=D=>Math.min(100,Math.max(0,D)),Sa=D=>{let z=null,U=null;const $=D.dataZoom??[];for(const ie of $)if(ie&&!(ie.type!=="inside"&&ie.type!=="slider")){if(Number.isFinite(ie.minSpan)){const K=Wn(ie.minSpan);z=z==null?K:Math.max(z,K)}if(Number.isFinite(ie.maxSpan)){const K=Wn(ie.maxSpan);U=U==null?K:Math.min(U,K)}}return{minSpan:z??void 0,maxSpan:U??void 0}},Na=()=>{if(m.xAxis.type==="category")return null;let D=0;for(let U=0;U<m.series.length;U++){const $=m.series[U];if($.type==="pie")continue;if($.type==="candlestick"){const K=P[U]??$.rawData??$.data;D=Math.max(D,K.length);continue}const ie=P[U]??ii($.rawData??$.data);D=Math.max(D,ie.length)}if(D<2)return null;const z=100/(D-1);return Number.isFinite(z)?Wn(z):null},cr=()=>{const D=Sa(m),z=Na(),U=Number.isFinite(D.minSpan)?Wn(D.minSpan):z??.5,$=Number.isFinite(D.maxSpan)?Wn(D.maxSpan):100;return{minSpan:U,maxSpan:$}},lo=()=>{var z;const D=Fa(m);if(!D){wt==null||wt.dispose(),wt=null,Kt==null||Kt(),Kt=null,Ne=null,xn=null;return}if(Ne){const U=cr(),$=Ne;(z=$.setSpanConstraints)==null||z.call($,U.minSpan,U.maxSpan),(xn==null||xn.start!==D.start||xn.end!==D.end)&&(Ne.setRange(D.start,D.end),xn={start:D.start,end:D.end})}else{const U=cr();Ne=lf(D.start,D.end,U),xn={start:D.start,end:D.end},Kt=Ne.onChange($=>{G=!0,He(),Zt(),Ma({start:$.start,end:$.end})})}D.hasInside&&ve?wt||(wt=of(ve,Ne),wt.enable()):(wt==null||wt.dispose(),wt=null)},uo=()=>{const D=m.series.length;P=new Array(D).fill(null),L=new Array(D).fill(null),te.clear();for(let z=0;z<D;z++){const U=m.series[z];if(U.type==="pie")continue;if(U.type==="candlestick"){const K=U.rawData??U.data,ae=K.length===0?[]:K.slice();P[z]=ae,L[z]=U.rawBounds??null;continue}const $=U.rawData??U.data,ie=ii($);P[z]=ie,L[z]=U.rawBounds??sn($)}},lr=()=>{const D=new Array(m.series.length);for(let z=0;z<m.series.length;z++){const U=m.series[z];if(U.type==="pie"){D[z]=U;continue}if(U.type==="candlestick"){const ae=P[z]??U.rawData??U.data,fe=L[z]??U.rawBounds??void 0,J=U.sampling==="ohlc"&&ae.length>U.samplingThreshold?Wr(ae,U.samplingThreshold):ae;D[z]={...U,rawData:ae,rawBounds:fe,data:J};continue}const $=P[z]??ii(U.rawData??U.data),ie=L[z]??U.rawBounds??void 0,K=_n($,U.sampling,U.samplingThreshold);D[z]={...U,rawData:$,rawBounds:ie,data:K}}B=D};function Ta(){const D=(Ne==null?void 0:Ne.getRange())??null,z=Nn(m,L),U=Tn(z,D);if(D==null||Number.isFinite(D.start)&&Number.isFinite(D.end)&&D.start<=0&&D.end>=100){V=B,Y();return}const ie=new Array(B.length);for(let K=0;K<B.length;K++){const ae=B[K];if(ae.type==="pie"){ie[K]=ae;continue}const fe=W[K];if(fe&&U.min>=fe.cachedRange.min&&U.max<=fe.cachedRange.max){ae.type==="candlestick"?ie[K]={...ae,data:bi(fe.data,U.min,U.max)}:ie[K]={...ae,data:xi(fe.data,U.min,U.max)};continue}ae.type==="candlestick"?ie[K]={...ae,data:bi(ae.data,U.min,U.max)}:ie[K]={...ae,data:xi(ae.data,U.min,U.max)}}V=ie,Y()}function fi(){const D=(Ne==null?void 0:Ne.getRange())??null,z=Nn(m,L),U=Tn(z,D),K=(U.max-U.min)*.1,ae=U.min-K,fe=U.max+K,J=2,xe=2e5,pe=32,ye=Math.max(.001,Math.min(1,U.spanFraction)),Ie=new Array(B.length);for(let Ae=0;Ae<B.length;Ae++){const Te=B[Ae];if(Te.type==="pie"){Ie[Ae]=Te;continue}if(D==null||Number.isFinite(D.start)&&Number.isFinite(D.end)&&D.start<=0&&D.end>=100){Ie[Ae]=Te;continue}if(Te.type==="candlestick"){const mi=P[Ae]??Te.rawData??Te.data,An=bi(mi,ae,fe),dr=Te.sampling,Yn=Te.samplingThreshold,pi=Number.isFinite(Yn)?Math.max(1,Yn|0):1,mr=Math.min(xe,Math.max(J,pi*pe)),Hn=On(Math.round(pi/ye),J,mr),Rn=dr==="ohlc"&&An.length>Hn?Wr(An,Hn):An;W[Ae]={data:Rn,cachedRange:{min:ae,max:fe},timestamp:Date.now()};const qn=bi(Rn,U.min,U.max);Ie[Ae]={...Te,data:qn};continue}const wn=P[Ae]??ii(Te.rawData??Te.data),ln=xi(wn,ae,fe),un=Te.sampling,ut=Te.samplingThreshold,$t=Number.isFinite(ut)?Math.max(1,ut|0):1,rn=Math.min(xe,Math.max(J,$t*pe)),Xn=On(Math.round($t/ye),J,rn),Ct=_n(ln,un,Xn);W[Ae]={data:Ct,cachedRange:{min:ae,max:fe},timestamp:Date.now()};const di=xi(Ct,U.min,U.max);Ie[Ae]={...Te,data:di}}V=Ie,Y()}uo(),lr(),lo(),fi(),W=new Array(m.series.length).fill(null);const Jt=[],Qt=[],en=[],bn=[],tn=[],nn=[],ur=Ul(i,{targetFormat:r}),fo=D=>{for(;Jt.length>D;){const z=Jt.pop();z==null||z.dispose()}for(;Jt.length<D;)Jt.push(bl(i,{targetFormat:r}))},mo=D=>{for(;Qt.length>D;){const z=Qt.pop();z==null||z.dispose()}for(;Qt.length<D;)Qt.push(Nl(i,{targetFormat:r}))},po=D=>{for(;en.length>D;){const z=en.pop();z==null||z.dispose()}for(;en.length<D;)en.push(Yl(i,{targetFormat:r}))},ho=D=>{for(;bn.length>D;){const z=bn.pop();z==null||z.dispose()}for(;bn.length<D;)bn.push(iu(i,{targetFormat:r}))},yo=D=>{for(;tn.length>D;){const z=tn.pop();z==null||z.dispose()}for(;tn.length<D;)tn.push(fu(i,{targetFormat:r}))},go=D=>{for(;nn.length>D;){const z=nn.pop();z==null||z.dispose()}for(;nn.length<D;)nn.push(Mu(i,{targetFormat:r}))};fo(m.series.length),mo(m.series.length),po(m.series.length),ho(m.series.length),yo(m.series.length),go(m.series.length);const vn=()=>{if(l)throw new Error("RenderCoordinator is disposed.")},xo=()=>{if(d)try{w.cancel(d)}catch{}d=null,g=1,v=null,I()},bo=(D,z)=>D.min===z.min&&D.max===z.max,Ia=(D,z)=>{if(D.length!==z.length)return!0;for(let U=0;U<D.length;U++){const $=D[U],ie=z[U];if($.type!==ie.type)return!0;if($.type==="pie"){const K=$,ae=ie;if(K.data!==ae.data||K.data.length!==ae.data.length)return!0}else{const K=$,ae=ie,fe=K.rawData??K.data,J=ae.rawData??ae.data;if(fe!==J||fe.length!==J.length)return!0}}return!1},Pa=(D,z)=>{if(D.length!==z.length)return!1;let U=!1;for(let $=0;$<D.length;$++){const ie=D[$],K=z[$];if(ie.type!==K.type)return!1;if(ie.type==="pie"){const J=ie,xe=K;if(J.data.length!==xe.data.length)return!1;for(let pe=0;pe<J.data.length;pe++){const ye=J.data[pe],Ie=xe.data[pe];if(!ye&&!Ie)continue;if(!ye||!Ie||ye.name!==Ie.name||ye.value!==Ie.value||ye.color!==Ie.color)return!1;const Ae=ye.visible!==!1,Te=Ie.visible!==!1;Ae!==Te&&(U=!0)}}else{const J=ie,xe=K,pe=J.rawData??J.data,ye=xe.rawData??xe.data;if(pe!==ye||pe.length!==ye.length)return!1}const ae=ie.visible!==!1,fe=K.visible!==!1;ae!==fe&&(U=!0)}return U},fr=D=>{var un;vn();const z=(Ne==null?void 0:Ne.getRange())??null,U=(()=>{if(v&&d){try{w.update(performance.now())}catch{}return x(v,g,z)}const ut=Nn(m,L),$t=Tn(ut,z),rn=Gr(m,L,_);return{xBaseDomain:ut,xVisibleDomain:{min:$t.min,max:$t.max},yBaseDomain:rn,series:V}})();xo();const $=Ia(m.series,D.series),ie=Pa(m.series,D.series);if(m=D,B=D.series,V=D.series,_=null,X=new Array(D.series.length).fill("unknown"),W=new Array(D.series.length).fill(null),u==null||u.update(D.series,D.theme),ct(),de=!1,at(),uo(),lr(),lo(),fi(),o){const ut=((un=m.tooltip)==null?void 0:un.show)!==!1;ut&&!ne&&(ne=Es(o),H=null,O=null,se=null),!ut&&ne&&me()}else me();const K=D.series.length;if(fo(K),mo(K),po(K),ho(K),yo(K),go(K),K<C)for(let ut=K;ut<C;ut++)we.removeSeries(ut);if(C=K,m.animation===!1&&F==="running"&&(S.cancelAll(),y=null,F="done",R=1),m.animation===!1){xo(),He();return}const ae=(Ne==null?void 0:Ne.getRange())??null,fe=Nn(m,L),J=Tn(fe,ae),xe=Gr(m,L,_),pe=V,ye=!bo(U.xBaseDomain,fe)||!bo(U.yBaseDomain,xe);if(!(b&&(ye||$)&&!ie)){ie&&F==="done"&&b&&(S.cancelAll(),y=null,F="pending",R=0),He();return}const Te=Qf(m.animation);if(!Te)return;v={from:{xBaseDomain:U.xBaseDomain,xVisibleDomain:U.xVisibleDomain,yBaseDomain:U.yBaseDomain,series:U.series},to:{xBaseDomain:fe,xVisibleDomain:{min:J.min,max:J.max},yBaseDomain:xe,series:pe}},I();const Nt=Te.delayMs+Te.durationMs,wn=ut=>{const $t=Xt(ut);if(!(Nt>0))return 1;const rn=$t*Nt;if(rn<=Te.delayMs)return 0;if(!(Te.durationMs>0))return 1;const Xn=(rn-Te.delayMs)/Te.durationMs;return Te.easing(Xn)};g=0;const ln=w.animate(0,1,Nt,wn,ut=>{l||d!==ln||(g=Xt(ut),g<1&&He())},()=>{l||d!==ln||(g=1,v=null,d=null,I())});d=ln,He()};return{setOptions:fr,appendData:(D,z)=>{if(vn(),!Number.isFinite(D)||D<0||D>=m.series.length||!z||z.length===0)return;if(m.series[D].type==="pie"){N.has(D)||(N.add(D),console.warn(`RenderCoordinator.appendData(${D}, ...): pie series are not supported by streaming append.`));return}const $=te.get(D);$?$.push(...z):te.set(D,Array.from(z)),Ot()},getInteractionX:()=>Fe,setInteractionX:(D,z)=>{vn();const U=D!==null&&Number.isFinite(D)?D:null;Ce={...Ce,source:U===null?"mouse":"sync"},qt(U,z),U===null&&Ce.hasPointer===!1&&(ke.setVisible(!1),he.setVisible(!1),le()),He()},onInteractionXChange:D=>(vn(),St.add(D),()=>{St.delete(D)}),getZoomRange:()=>(Ne==null?void 0:Ne.getRange())??null,setZoomRange:(D,z)=>{vn(),Ne&&Ne.setRange(D,z)},onZoomRangeChange:D=>(vn(),ui.add(D),()=>{ui.delete(D)}),render:()=>{var No,To,Io;if(vn(),!e.canvasContext||!e.canvas)return;(te.size>0||de)&&(at(),vt({requestRenderAfter:!1})),G&&(G=!1,Ta());const D=m.series.some(Re=>Re.type!=="pie"),z=V;if(F!=="done"){const Re=Jf(m.animation),Ve=(()=>{for(let At=0;At<z.length;At++){const Oe=z[At];switch(Oe.type){case"pie":{if(Oe.data.some(Ue=>typeof(Ue==null?void 0:Ue.value)=="number"&&Number.isFinite(Ue.value)&&Ue.value>0))return!0;break}case"line":case"area":case"bar":case"scatter":case"candlestick":{if((Array.isArray(Oe.data)||ArrayBuffer.isView(Oe.data)?Oe.data.length:Oe.data.x.length)>0)return!0;break}default:Gf(Oe)}}return!1})();if(F==="pending"&&Re&&Ve){const At=Re.delayMs+Re.durationMs,Oe=Ue=>{const ft=Xt(Ue);if(!(At>0))return 1;const _e=ft*At;if(_e<=Re.delayMs)return 0;if(!(Re.durationMs>0))return 1;const Le=(_e-Re.delayMs)/Re.durationMs;return Re.easing(Le)};R=0,F="running",y=S.animate(0,1,At,Oe,Ue=>{l||F!=="running"||(R=Xt(Ue),R<1&&He())},()=>{l||(F="done",R=1,y=null)})}S.update(performance.now())}v!==null&&d&&w.update(performance.now());const U=Ls(e,m);ve==null||ve.updateGridArea(U);const $=(Ne==null?void 0:Ne.getRange())??null,ie=v?Xt(g):1,K=v?Bi(v.from.xBaseDomain,v.to.xBaseDomain,ie):Nn(m,L),ae=v?Bi(v.from.yBaseDomain,v.to.yBaseDomain,ie):Gr(m,L,_),fe=Tn(K,$),J=$f(U),xe=Wf(U),pe=an().domain(fe.min,fe.max).range(J.left,J.right),ye=an().domain(ae.min,ae.max).range(J.bottom,J.top),Ie=e.canvas,Ae=Ef(Ie),Te=Ae.width,Nt=Ae.height,wn=Te>0?jr(J.left,Te):0,ln=Te>0?jr(J.right,Te):0,un=Nt>0?Us(J.top,Nt):0,ut=Nt>0?Us(J.bottom,Nt):0,$t=Math.max(0,ln-wn),rn=Math.max(0,ut-un),Xn=D?m.annotations??[]:[],Ct=Vc({annotations:Xn,xScale:pe,yScale:ye,plotBounds:{leftCss:wn,rightCss:ln,topCss:un,bottomCss:ut,widthCss:$t,heightCss:rn},canvasCssWidth:Te,canvasCssHeight:Nt,theme:m.theme}),di=Ct.linesBelow.length+Ct.linesAbove.length>0?[...Ct.linesBelow,...Ct.linesAbove]:[],mi=Ct.markersBelow.length+Ct.markersAbove.length>0?[...Ct.markersBelow,...Ct.markersAbove]:[],An=Ct.linesBelow.length,dr=Ct.linesAbove.length,Yn=Ct.markersBelow.length,pi=Ct.markersAbove.length,mr=Rf(e.canvas),Hn=Math.abs(fe.max-fe.min);let Rn=Zr,qn=[];if(m.xAxis.type==="time"){const Re=jf({axisMin:Ji(m.xAxis.min),axisMax:Ji(m.xAxis.max),xScale:pe,plotClipLeft:J.left,plotClipRight:J.right,canvasCssWidth:mr,visibleRangeMs:Hn,measureCtx:p,measureCache:h??void 0,fontSize:m.theme.fontSize,fontFamily:m.theme.fontFamily||"sans-serif"});Rn=Re.tickCount,qn=Re.tickValues}else{const Re=yn(m.xAxis.min)??pe.invert(J.left),Ve=yn(m.xAxis.max)??pe.invert(J.right);qn=$i(Re,Ve,Rn)}const $e=Be(U,{xDomain:{min:fe.min,max:fe.max},yDomain:ae});tt=$e;const Wt=v&&ie<1?f(v.from.series,v.to.series,ie,M):V;if(Ce.source==="mouse"&&Ce.hasPointer&&Ce.isInGrid&&$e){const Re=$e.xScale.invert(Ce.gridX);qt(Number.isFinite(Re)?Re:null,"mouse")}let st=Ce;if(Ce.source==="sync")if(Fe===null||!$e)st={...Ce,hasPointer:!1,isInGrid:!1};else{const Re=$e.xScale.scale(Fe),Ve=$e.plotHeightCss*.5,At=Number.isFinite(Re)&&Number.isFinite(Ve)&&Re>=0&&Re<=$e.plotWidthCss&&Ve>=0&&Ve<=$e.plotHeightCss;st={source:"sync",gridX:Number.isFinite(Re)?Re:0,gridY:Number.isFinite(Ve)?Ve:0,x:U.left+(Number.isFinite(Re)?Re:0),y:U.top+(Number.isFinite(Ve)?Ve:0),isInGrid:At,hasPointer:At}}if(Uc({gridRenderer:it,xAxisRenderer:Ke,yAxisRenderer:et,crosshairRenderer:ke,highlightRenderer:he},{currentOptions:m,xScale:pe,yScale:ye,gridArea:U,xTickCount:Rn,hasCartesianSeries:D,effectivePointer:st,interactionScales:$e,seriesForRender:Wt,withAlpha:ks}),st.hasPointer&&st.isInGrid&&((No=m.tooltip)==null?void 0:No.show)!==!1){const Re=e.canvas;if($e&&Re&&Vn(Re)){const Ve=(To=m.tooltip)==null?void 0:To.formatter,At=((Io=m.tooltip)==null?void 0:Io.trigger)??"item",Oe=Re.offsetLeft+st.x,Ue=Re.offsetTop+st.y;if(st.source==="sync"){const ft=Ns(Wt,st.gridX,$e.xScale);if(ft.length===0)me();else if(At==="axis"){const _e=ft.map(qe=>je(qe.seriesIndex,qe.dataIndex,qe.point)),Le=Ve?Ve(_e):Ur(_e);Le&&(Le!==H||Oe!==O||Ue!==se)?(H=Le,O=Oe,se=Ue,ce(Oe,Ue,Le)):Le||me()}else{const _e=ft[0],Le=je(_e.seriesIndex,_e.dataIndex,_e.point),qe=Ve?Ve(Le):ni(Le);qe&&(qe!==H||Oe!==O||Ue!==se)?(H=qe,O=Oe,se=Ue,ce(Oe,Ue,qe)):qe||me()}}else if(At==="axis"){const ft=lt(Wt,st.gridX,st.gridY,$e.plotWidthCss,$e.plotHeightCss);if(ft){const _e={seriesName:ft.slice.name,seriesIndex:ft.seriesIndex,dataIndex:ft.dataIndex,value:[0,ft.slice.value],color:ft.slice.color},Le=Ve?Ve([_e]):ni(_e);Le&&(Le!==H||Oe!==O||Ue!==se)?(H=Le,O=Oe,se=Ue,ce(Oe,Ue,Le)):Le||me()}else{const _e=cn(Wt,st.gridX,st.gridY,$e),Le=Ns(Wt,st.gridX,$e.xScale);if(Le.length===0)if(_e){const qe=[_e.params],Je=Ve?Ve(qe):Ur(qe);if(Je){const dt=zr(_e.match,$e.xScale,$e.yScale,U,Re),Rt=(dt==null?void 0:dt.x)??Oe,Cn=(dt==null?void 0:dt.y)??Ue;(Je!==H||Rt!==O||Cn!==se)&&(H=Je,O=Rt,se=Cn,ce(Rt,Cn,Je))}else me()}else me();else{const qe=Le.map(dt=>je(dt.seriesIndex,dt.dataIndex,dt.point));_e&&qe.push(_e.params);const Je=Ve?Ve(qe):Ur(qe);if(Je){let dt=Oe,Rt=Ue;if(_e){const Cn=zr(_e.match,$e.xScale,$e.yScale,U,Re);Cn&&(dt=Cn.x,Rt=Cn.y)}(Je!==H||dt!==O||Rt!==se)&&(H=Je,O=dt,se=Rt,ce(dt,Rt,Je))}else me()}}}else{const ft=lt(Wt,st.gridX,st.gridY,$e.plotWidthCss,$e.plotHeightCss);if(ft){const _e={seriesName:ft.slice.name,seriesIndex:ft.seriesIndex,dataIndex:ft.dataIndex,value:[0,ft.slice.value],color:ft.slice.color},Le=Ve?Ve(_e):ni(_e);Le&&(Le!==H||Oe!==O||Ue!==se)?(H=Le,O=Oe,se=Ue,ce(Oe,Ue,Le)):Le||me()}else{const _e=cn(Wt,st.gridX,st.gridY,$e);if(_e){const qe=Ve?Ve(_e.params):ni(_e.params);if(qe){const Je=zr(_e.match,$e.xScale,$e.yScale,U,Re),dt=(Je==null?void 0:Je.x)??Oe,Rt=(Je==null?void 0:Je.y)??Ue;(qe!==H||dt!==O||Rt!==se)&&(H=qe,O=dt,se=Rt,ce(dt,Rt,qe,_e.params))}else me();return}const Le=Zi(Wt,st.gridX,st.gridY,$e.xScale,$e.yScale);if(!Le)me();else{const qe=je(Le.seriesIndex,Le.dataIndex,Le.point),Je=Ve?Ve(qe):ni(qe);Je&&(Je!==H||Oe!==O||Ue!==se)?(H=Je,O=Oe,se=Ue,ce(Oe,Ue,Je)):Je||me()}}}}else me()}else me();const Zn=$e??(Ie&&Vn(Ie)?Pe(Ie,U):null),Aa=Zn&&typeof Zn.plotWidthCss=="number"&&typeof Zn.plotHeightCss=="number"?.5*Math.min(Zn.plotWidthCss,Zn.plotHeightCss):0,wo=$c({lineRenderers:Qt,areaRenderers:Jt,scatterRenderers:en,scatterDensityRenderers:bn,pieRenderers:tn,candlestickRenderers:nn},{currentOptions:m,seriesForRender:Wt,xScale:pe,yScale:ye,gridArea:U,dataStore:we,appendedGpuThisFrame:Q,gpuSeriesKindByIndex:X,zoomState:Ne,visibleXDomain:fe,introPhase:F,introProgress01:R,withAlpha:ks,maxRadiusCss:Aa}),{visibleBarSeriesConfigs:Co}=wo,Mo=F==="running"?Xt(R):1,Ra=Mo<1?td(ye,J,Co,Mo):ye;ur.prepare(Co,we,pe,Ra,U),D?(Ge.prepare(U,di),rt.prepare(U,di),ze.prepare({canvasWidth:U.canvasWidth,canvasHeight:U.canvasHeight,devicePixelRatio:U.devicePixelRatio,instances:mi}),Ze.prepare({canvasWidth:U.canvasWidth,canvasHeight:U.canvasHeight,devicePixelRatio:U.devicePixelRatio,instances:mi})):(Ge.prepare(U,[]),rt.prepare(U,[]),ze.prepare({canvasWidth:U.canvasWidth,canvasHeight:U.canvasHeight,devicePixelRatio:U.devicePixelRatio,instances:[]}),Ze.prepare({canvasWidth:U.canvasWidth,canvasHeight:U.canvasHeight,devicePixelRatio:U.devicePixelRatio,instances:[]})),Ye(U.canvasWidth,U.canvasHeight);const Fo=e.canvasContext.getCurrentTexture().createView(),jn=i.createCommandEncoder({label:"renderCoordinator/commandEncoder"}),So=ec(m.theme.backgroundColor,{r:0,g:0,b:0,a:1});Wc({scatterDensityRenderers:bn},Wt,jn);const pr=jn.beginRenderPass({label:"renderCoordinator/mainPass",colorAttachments:[{view:gt,clearValue:So,loadOp:"clear",storeOp:"store"}]});it&&it.render(pr),Xc({lineRenderers:Qt,areaRenderers:Jt,barRenderer:ur,scatterRenderers:en,scatterDensityRenderers:bn,pieRenderers:tn,candlestickRenderers:nn},{referenceLineRenderer:Ge,annotationMarkerRenderer:ze},{hasCartesianSeries:D,gridArea:U,mainPass:pr,plotScissor:xe,introPhase:F,introProgress01:R,referenceLineBelowCount:An,markerBelowCount:Yn},wo),pr.end();const Kn=jn.beginRenderPass({label:"renderCoordinator/annotationOverlayMsaaPass",colorAttachments:[{view:Ft,resolveTarget:Fo,clearValue:So,loadOp:"clear",storeOp:"discard"}]});Kn.setPipeline(ue),Kn.setBindGroup(0,Se),Kn.draw(3),Yc({referenceLineRendererMsaa:rt,annotationMarkerRendererMsaa:Ze},{hasCartesianSeries:D,gridArea:U,overlayPass:Kn,plotScissor:xe,referenceLineBelowCount:An,referenceLineAboveCount:dr,markerBelowCount:Yn,markerAboveCount:pi}),Kn.end();const Jn=jn.beginRenderPass({label:"renderCoordinator/topOverlayPass",colorAttachments:[{view:Fo,loadOp:"load",storeOp:"store"}]});he.render(Jn),D&&(Ke.render(Jn),et.render(Jn)),ke.render(Jn),Jn.end(),i.queue.submit([jn.finish()]),b=!0,mc(s,o,{gpuContext:e,currentOptions:m,xScale:pe,yScale:ye,xTickValues:qn,plotClipRect:J,visibleXRangeMs:Hn}),gc(a,o,{currentOptions:m,xScale:pe,yScale:ye,canvasCssWidthForAnnotations:Te,canvasCssHeightForAnnotations:Nt,plotLeftCss:wn,plotTopCss:un,plotWidthCss:$t,plotHeightCss:rn,canvas:Ie})},dispose:()=>{if(!l){l=!0;try{y&&S.cancel(y),S.cancelAll()}catch{}y=null,F="done",R=1;try{d&&w.cancel(d),w.cancelAll()}catch{}d=null,g=1,v=null,at(),ct(),de=!1,te.clear(),wt==null||wt.dispose(),wt=null,Kt==null||Kt(),Kt=null,Ne=null,xn=null,ui.clear(),ve==null||ve.dispose(),ke.dispose(),he.dispose();for(let D=0;D<Jt.length;D++)Jt[D].dispose();Jt.length=0;for(let D=0;D<Qt.length;D++)Qt[D].dispose();Qt.length=0;for(let D=0;D<en.length;D++)en[D].dispose();en.length=0;for(let D=0;D<tn.length;D++)tn[D].dispose();tn.length=0;for(let D=0;D<nn.length;D++)nn[D].dispose();nn.length=0,ur.dispose(),it.dispose(),Ke.dispose(),et.dispose(),Ge.dispose(),ze.dispose(),rt.dispose(),Ze.dispose(),De(ht),De(ot),ht=null,gt=null,ot=null,Ft=null,Se=null,we.dispose(),ne==null||ne.dispose(),ne=null,u==null||u.dispose(),s==null||s.dispose(),a==null||a.dispose()}}}}const Et={left:60,right:20,top:40,bottom:40},Wi=["#5470C6","#91CC75","#FAC858","#EE6666","#73C0DE","#3BA272","#FC8452","#9A60B4","#EA7CCC"],Gs={width:2,opacity:1},zs={opacity:.25},Dt={style:"classic",itemStyle:{upColor:"#22c55e",downColor:"#ef4444",upBorderColor:"#22c55e",downBorderColor:"#ef4444",borderWidth:1},barWidth:"80%",barMinWidth:1,barMaxWidth:50,sampling:"ohlc",samplingThreshold:5e3},Li={mode:"points",binSize:2,densityColormap:"viridis",densityNormalization:"log"},bt={grid:Et,xAxis:{type:"value"},yAxis:{type:"value",autoBounds:"visible"},autoScroll:!1,theme:"dark",palette:Wi,series:[]},id=["#00E5FF","#FF2D95","#B026FF","#00F5A0","#FFD300","#FF6B00","#4D5BFF","#FF3D3D"],ya={backgroundColor:"#1a1a2e",textColor:"#e0e0e0",axisLineColor:"rgba(224,224,224,0.35)",axisTickColor:"rgba(224,224,224,0.55)",gridLineColor:"rgba(255,255,255,0.1)",colorPalette:[...id],fontFamily:'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',fontSize:12},rd=["#1F77B4","#FF7F0E","#2CA02C","#D62728","#9467BD","#8C564B","#E377C2","#17BECF"],ga={backgroundColor:"#ffffff",textColor:"#333333",axisLineColor:"rgba(0,0,0,0.35)",axisTickColor:"rgba(0,0,0,0.55)",gridLineColor:"rgba(0,0,0,0.1)",colorPalette:[...rd],fontFamily:'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',fontSize:12};function Xi(e){return e==="dark"?ya:ga}const od=e=>{if(!Array.isArray(e))return;const t=[];for(const n of e){if(n===null||typeof n!="object"||Array.isArray(n))continue;const i=n,r=i.type;if(r!=="inside"&&r!=="slider")continue;const o=i.xAxisIndex,s=i.start,a=i.end,c=i.minSpan,u=i.maxSpan,p=typeof o=="number"&&Number.isFinite(o)?o:void 0,h=typeof s=="number"&&Number.isFinite(s)?s:void 0,l=typeof a=="number"&&Number.isFinite(a)?a:void 0,m=typeof c=="number"&&Number.isFinite(c)?c:void 0,C=typeof u=="number"&&Number.isFinite(u)?u:void 0;t.push({type:r,xAxisIndex:p,start:h,end:l,minSpan:m,maxSpan:C})}return t},sd=e=>{if(!Array.isArray(e))return;const t=[],n=u=>u==="start"||u==="center"||u==="end",i=u=>u==="circle"||u==="rect"||u==="triangle",r=u=>{if(typeof u!="string")return;const p=u.trim();return p.length>0?p:void 0},o=u=>typeof u=="number"&&Number.isFinite(u)?u:void 0,s=u=>{const p=o(u);if(p!=null)return Math.min(1,Math.max(0,p))},a=u=>{if(!Array.isArray(u))return;const p=u.filter(h=>typeof h=="number"&&Number.isFinite(h)).map(h=>h);if(p.length!==0)return Object.freeze(p),p},c=u=>{if(typeof u=="number"&&Number.isFinite(u))return u;if(!Array.isArray(u)||u.length!==4)return;const p=o(u[0]),h=o(u[1]),l=o(u[2]),m=o(u[3]);if(!(p==null||h==null||l==null||m==null))return[p,h,l,m]};for(const u of e){if(u===null||typeof u!="object"||Array.isArray(u))continue;const p=u,h=p.type;if(h!=="lineX"&&h!=="lineY"&&h!=="point"&&h!=="text")continue;const l=r(p.id),m=p.layer,C=m==="belowSeries"||m==="aboveSeries"?m:void 0,F=p.style,R=F&&typeof F=="object"&&!Array.isArray(F)?(()=>{const b=F,w=r(b.color),d=o(b.lineWidth),g=a(b.lineDash),v=s(b.opacity),M={...w?{color:w}:{},...d!=null?{lineWidth:d}:{},...g?{lineDash:g}:{},...v!=null?{opacity:v}:{}};return Object.keys(M).length>0?M:void 0})():void 0,S=p.label,y=S&&typeof S=="object"&&!Array.isArray(S)?(()=>{const b=S,w=r(b.text),d=r(b.template),g=b.decimals,v=typeof g=="number"&&Number.isFinite(g)&&g>=0?Math.min(20,Math.floor(g)):void 0,M=b.offset,I=Array.isArray(M)&&M.length===2&&typeof M[0]=="number"&&Number.isFinite(M[0])&&typeof M[1]=="number"&&Number.isFinite(M[1])?[M[0],M[1]]:void 0,T=b.anchor,E=n(T)?T:void 0,f=b.background,x=f&&typeof f=="object"&&!Array.isArray(f)?(()=>{const A=f,P=r(A.color),L=s(A.opacity),B=c(A.padding),V=o(A.borderRadius),_={...P?{color:P}:{},...L!=null?{opacity:L}:{},...B!=null?{padding:B}:{},...V!=null?{borderRadius:V}:{}};return Object.keys(_).length>0?_:void 0})():void 0,N={...w?{text:w}:{},...d?{template:d}:{},...v!=null?{decimals:v}:{},...I?{offset:I}:{},...E?{anchor:E}:{},...x?{background:x}:{}};return Object.keys(N).length>0?N:void 0})():void 0;if(h==="lineX"){const b=o(p.x);if(b==null)continue;const w={type:"lineX",x:b,...l?{id:l}:{},...C?{layer:C}:{},...R?{style:R}:{},...y?{label:y}:{}};t.push(w);continue}if(h==="lineY"){const b=o(p.y);if(b==null)continue;const w={type:"lineY",y:b,...l?{id:l}:{},...C?{layer:C}:{},...R?{style:R}:{},...y?{label:y}:{}};t.push(w);continue}if(h==="point"){const b=o(p.x),w=o(p.y);if(b==null||w==null)continue;const d=p.marker,g=d&&typeof d=="object"&&!Array.isArray(d)?(()=>{const M=d,I=M.symbol,T=i(I)?I:void 0,E=o(M.size),f=M.style,x=f&&typeof f=="object"&&!Array.isArray(f)?(()=>{const A=f,P=r(A.color),L=s(A.opacity),B=o(A.lineWidth),V=a(A.lineDash),_={...P?{color:P}:{},...L!=null?{opacity:L}:{},...B!=null?{lineWidth:B}:{},...V?{lineDash:V}:{}};return Object.keys(_).length>0?_:void 0})():void 0,N={...T?{symbol:T}:{},...E!=null?{size:E}:{},...x?{style:x}:{}};return Object.keys(N).length>0?N:void 0})():void 0,v={type:"point",x:b,y:w,...g?{marker:g}:{},...l?{id:l}:{},...C?{layer:C}:{},...R?{style:R}:{},...y?{label:y}:{}};t.push(v);continue}{const b=p.position,w=r(p.text);if(!w||!b||typeof b!="object"||Array.isArray(b))continue;const d=b,g=d.space;if(g!=="data"&&g!=="plot")continue;const v=o(d.x),M=o(d.y);if(v==null||M==null)continue;const T={type:"text",position:{space:g,x:v,y:M},text:w,...l?{id:l}:{},...C?{layer:C}:{},...R?{style:R}:{},...y?{label:y}:{}};t.push(T);continue}}if(t.length!==0)return Object.freeze(t),t},oi=e=>Array.isArray(e)?e.filter(t=>typeof t=="string").map(t=>t.trim()).filter(t=>t.length>0):[],ad=e=>{const t=Xi("dark");if(typeof e=="string"){const a=e.trim().toLowerCase();return Xi(a==="light"?"light":"dark")}if(e===null||typeof e!="object"||Array.isArray(e))return t;const n=e,i=a=>{const c=n[a];if(typeof c!="string")return;const u=c.trim();return u.length>0?u:void 0},r=n.fontSize,o=typeof r=="number"&&Number.isFinite(r)?r:void 0,s=oi(n.colorPalette);return{backgroundColor:i("backgroundColor")??t.backgroundColor,textColor:i("textColor")??t.textColor,axisLineColor:i("axisLineColor")??t.axisLineColor,axisTickColor:i("axisTickColor")??t.axisTickColor,gridLineColor:i("gridLineColor")??t.gridLineColor,colorPalette:s.length>0?s:Array.from(t.colorPalette),fontFamily:i("fontFamily")??t.fontFamily,fontSize:o??t.fontSize}},on=e=>{if(typeof e!="string")return;const t=e.trim();return t.length>0?t:void 0},cd=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="none"||t==="lttb"||t==="average"||t==="max"||t==="min"||t==="ohlc"?t:void 0},ld=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="points"||t==="density"?t:void 0},ud=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="linear"||t==="sqrt"||t==="log"?t:void 0},fd=e=>{if(typeof e!="number"||!Number.isFinite(e))return;const t=Math.floor(e);return t>0?Math.max(1,t):void 0},dd=e=>{if(typeof e=="string"){const i=e.trim().toLowerCase();return i==="viridis"||i==="plasma"||i==="inferno"?i:void 0}if(!Array.isArray(e))return;if(e.length>0&&e.every(i=>typeof i=="string"&&i.length>0&&i===i.trim())){const i=e;return Object.isFrozen(i)||Object.freeze(i),i}const n=e.filter(i=>typeof i=="string").map(i=>i.trim()).filter(i=>i.length>0);if(n.length!==0)return Object.freeze(n),n},md=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="none"||t==="ohlc"?t:void 0},Vs=e=>{if(typeof e!="number"||!Number.isFinite(e))return;const t=Math.floor(e);return t>0?t:void 0},Os=e=>{if(typeof e!="string")return;const t=e.trim().toLowerCase();return t==="global"||t==="visible"?t:void 0},pd=e=>Array.isArray(e),hd=e=>{if(e.length===0)return;let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;if(pd(e[0])){const s=e;for(let a=0;a<s.length;a++){const c=s[a],u=c[0],p=c[3],h=c[4];if(!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(h))continue;const l=Math.min(p,h),m=Math.max(p,h);u<t&&(t=u),u>n&&(n=u),l<i&&(i=l),m>r&&(r=m)}}else{const s=e;for(let a=0;a<s.length;a++){const c=s[a],u=c.timestamp,p=c.low,h=c.high;if(!Number.isFinite(u)||!Number.isFinite(p)||!Number.isFinite(h))continue;const l=Math.min(p,h),m=Math.max(p,h);u<t&&(t=u),u>n&&(n=u),l<i&&(i=l),m>r&&(r=m)}}if(!(!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)))return t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r}},yd=e=>{throw new Error(`Unhandled series type: ${(e==null?void 0:e.type)??"unknown"}`)};let $s=!1;const gd=()=>{$s||(console.warn("ChartGPU: Candlestick series rendering is not yet implemented. Series will be skipped."),$s=!0)};function ao(e={}){var S,y,b,w;const t=ad(e.theme),n=e.autoScroll,i=typeof n=="boolean"?n:bt.autoScroll,r=e.animation,s=(typeof r=="boolean"||r!==null&&typeof r=="object"&&!Array.isArray(r)?r:void 0)??!0,a=oi(e.palette),c=a.length>0?{...t,colorPalette:a}:t,u=oi(c.colorPalette),p=u.length>0?u:oi(bt.palette??Wi).length>0?oi(bt.palette??Wi):Array.from(Wi),h=p.length>0?p:["#000000"],l={...c,colorPalette:h.slice()},m={left:((S=e.grid)==null?void 0:S.left)??bt.grid.left,right:((y=e.grid)==null?void 0:y.right)??bt.grid.right,top:((b=e.grid)==null?void 0:b.top)??bt.grid.top,bottom:((w=e.grid)==null?void 0:w.bottom)??bt.grid.bottom},C=e.xAxis?{...bt.xAxis,...e.xAxis,type:e.xAxis.type??bt.xAxis.type,autoBounds:Os(e.xAxis.autoBounds)??bt.xAxis.autoBounds}:{...bt.xAxis},F=e.yAxis?{...bt.yAxis,...e.yAxis,type:e.yAxis.type??bt.yAxis.type,autoBounds:Os(e.yAxis.autoBounds)??bt.yAxis.autoBounds}:{...bt.yAxis},R=(e.series??[]).map((d,g)=>{var x,N,A,P,L,B,V,_,re,Y;const v=on(d.color),M=l.colorPalette[g%l.colorPalette.length],I=v??M,T=d.visible!==!1,E=cd(d.sampling)??"lttb",f=Vs(d.samplingThreshold)??5e3;switch(d.type){case"area":{const Z=on((x=d.areaStyle)==null?void 0:x.color)??v??M,oe={opacity:((N=d.areaStyle)==null?void 0:N.opacity)??zs.opacity,color:Z},ee=sn(d.data)??void 0;return{...d,visible:T,rawData:d.data,data:_n(d.data,E,f),color:Z,areaStyle:oe,sampling:E,samplingThreshold:f,rawBounds:ee}}case"line":{const Z=on((A=d.lineStyle)==null?void 0:A.color)??v??M,oe={width:((P=d.lineStyle)==null?void 0:P.width)??Gs.width,opacity:((L=d.lineStyle)==null?void 0:L.opacity)??Gs.opacity,color:Z},{areaStyle:ee,...q}=d,de=sn(d.data)??void 0,G=_n(d.data,E,f);return{...q,visible:T,rawData:d.data,data:G,color:Z,lineStyle:oe,...d.areaStyle?{areaStyle:{opacity:d.areaStyle.opacity??zs.opacity,color:on(d.areaStyle.color)??Z}}:{},sampling:E,samplingThreshold:f,rawBounds:de}}case"bar":{const W=sn(d.data)??void 0;return{...d,visible:T,rawData:d.data,data:_n(d.data,E,f),color:I,sampling:E,samplingThreshold:f,rawBounds:W}}case"scatter":{const W=sn(d.data)??void 0,Z=ld(d.mode)??Li.mode,oe=fd(d.binSize)??Li.binSize,ee=dd(d.densityColormap)??Li.densityColormap,q=ud(d.densityNormalization)??Li.densityNormalization;return{...d,visible:T,rawData:d.data,data:_n(d.data,E,f),color:I,mode:Z,binSize:oe,densityColormap:ee,densityNormalization:q,sampling:E,samplingThreshold:f,rawBounds:W}}case"pie":{const{sampling:W,samplingThreshold:Z,...oe}=d,ee=(d.data??[]).map((q,de)=>{const G=on(q==null?void 0:q.color),te=l.colorPalette[(g+de)%l.colorPalette.length],X=(q==null?void 0:q.visible)!==!1;return{...q,color:G??te,visible:X}});return{...oe,visible:T,color:I,data:ee}}case"candlestick":{gd();const W=md(d.sampling)??Dt.sampling,Z=Vs(d.samplingThreshold)??Dt.samplingThreshold,oe={upColor:on((B=d.itemStyle)==null?void 0:B.upColor)??Dt.itemStyle.upColor,downColor:on((V=d.itemStyle)==null?void 0:V.downColor)??Dt.itemStyle.downColor,upBorderColor:on((_=d.itemStyle)==null?void 0:_.upBorderColor)??Dt.itemStyle.upBorderColor,downBorderColor:on((re=d.itemStyle)==null?void 0:re.downBorderColor)??Dt.itemStyle.downBorderColor,borderWidth:typeof((Y=d.itemStyle)==null?void 0:Y.borderWidth)=="number"&&Number.isFinite(d.itemStyle.borderWidth)?d.itemStyle.borderWidth:Dt.itemStyle.borderWidth},ee=hd(d.data),q=W==="ohlc"&&d.data.length>Z?Wr(d.data,Z):d.data;return{...d,visible:T,rawData:d.data,data:q,color:I,style:d.style??Dt.style,itemStyle:oe,barWidth:d.barWidth??Dt.barWidth,barMinWidth:d.barMinWidth??Dt.barMinWidth,barMaxWidth:d.barMaxWidth??Dt.barMaxWidth,sampling:W,samplingThreshold:Z,rawBounds:ee}}default:return yd(d)}});return{grid:m,xAxis:C,yAxis:F,autoScroll:i,dataZoom:od(e.dataZoom),annotations:sd(e.annotations),animation:s,theme:l,palette:l.colorPalette,series:R,legend:e.legend}}const xd=32,bd=8,vd=xd+bd,wd=e=>{var t;return((t=e.dataZoom)==null?void 0:t.some(n=>(n==null?void 0:n.type)==="slider"))??!1};function Ws(e={}){const t={...ao(e),tooltip:e.tooltip};return wd(e)?{...t,grid:{...t.grid,bottom:t.grid.bottom+vd}}:t}const Cd={resolve:ao},Kr=(e,t,n)=>Math.min(n,Math.max(t,e)),Md=e=>{let{start:t,end:n}=e;if(t>n){const i=t;t=n,n=i}return{start:Kr(t,0,100),end:Kr(n,0,100)}};function Fd(e,t,n){const i=n==null?void 0:n.height,r=n==null?void 0:n.marginTop,o=(n==null?void 0:n.zIndex)??4,s=(n==null?void 0:n.showPreview)??!1,a=document.createElement("div");a.style.display="block",a.style.width="100%",a.style.height=`${i}px`,a.style.marginTop=`${r}px`,a.style.boxSizing="border-box",a.style.position="relative",a.style.zIndex=`${o}`,a.style.userSelect="none",a.style.touchAction="none";const c=document.createElement("div");c.style.position="relative",c.style.height="100%",c.style.width="100%",c.style.boxSizing="border-box",c.style.borderRadius="8px",c.style.borderStyle="solid",c.style.borderWidth="1px",c.style.overflow="hidden",a.appendChild(c);const u=document.createElement("div");u.style.position="absolute",u.style.inset="0",u.style.pointerEvents="none",u.style.opacity="0.4",u.style.display=s?"block":"none",c.appendChild(u);const p=document.createElement("div");p.style.position="absolute",p.style.top="0",p.style.bottom="0",p.style.left="0%",p.style.width="100%",p.style.boxSizing="border-box",p.style.cursor="grab",c.appendChild(p);const h=document.createElement("div");h.style.position="absolute",h.style.left="0",h.style.top="0",h.style.bottom="0",h.style.width="10px",h.style.cursor="ew-resize",p.appendChild(h);const l=document.createElement("div");l.style.position="absolute",l.style.right="0",l.style.top="0",l.style.bottom="0",l.style.width="10px",l.style.cursor="ew-resize",p.appendChild(l);const m=document.createElement("div");m.style.position="absolute",m.style.left="10px",m.style.right="10px",m.style.top="0",m.style.bottom="0",m.style.cursor="grab",p.appendChild(m),e.appendChild(a);let C=!1,F=null;const R=f=>{const x=Md(f),N=Kr(x.end-x.start,0,100);p.style.left=`${x.start}%`,p.style.width=`${N}%`},S=()=>{const f=c.getBoundingClientRect().width;return Number.isFinite(f)&&f>0?f:null},y=f=>{const x=S();if(x===null)return null;const N=f/x*100;return Number.isFinite(N)?N:null},b=(f,x)=>{try{f.setPointerCapture(x)}catch{}},w=(f,x)=>{try{f.releasePointerCapture(x)}catch{}},d=(f,x)=>{if(C||f.button!==0)return;f.preventDefault(),F==null||F(),F=null;const N=f.clientX,A=t.getRange(),P=f.currentTarget instanceof Element?f.currentTarget:p;b(P,f.pointerId),x==="pan-window"&&(p.style.cursor="grabbing",m.style.cursor="grabbing");const L=re=>{if(C||re.pointerId!==f.pointerId)return;re.preventDefault();const Y=y(re.clientX-N);if(Y!==null)switch(x){case"left-handle":{const W=Math.min(A.end,A.start+Y),Z=t;Z.setRangeAnchored?Z.setRangeAnchored(W,A.end,"end"):t.setRange(W,A.end);return}case"right-handle":{const W=Math.max(A.start,A.end+Y),Z=t;Z.setRangeAnchored?Z.setRangeAnchored(A.start,W,"start"):t.setRange(A.start,W);return}case"pan-window":{t.setRange(A.start+Y,A.end+Y);return}}};let B=!1;const V=()=>{B||(B=!0,window.removeEventListener("pointermove",L),window.removeEventListener("pointerup",_),window.removeEventListener("pointercancel",_),x==="pan-window"&&(p.style.cursor="grab",m.style.cursor="grab"),w(P,f.pointerId),F===V&&(F=null))},_=re=>{re.pointerId===f.pointerId&&V()};F=V,window.addEventListener("pointermove",L,{passive:!1}),window.addEventListener("pointerup",_,{passive:!0}),window.addEventListener("pointercancel",_,{passive:!0})},g=f=>d(f,"left-handle"),v=f=>d(f,"right-handle"),M=f=>d(f,"pan-window");h.addEventListener("pointerdown",g,{passive:!1}),l.addEventListener("pointerdown",v,{passive:!1}),m.addEventListener("pointerdown",M,{passive:!1});const I=t.onChange(f=>{C||R(f)});return R(t.getRange()),{update:f=>{if(C)return;c.style.background=f.backgroundColor,c.style.borderColor=f.axisLineColor,u.style.background=f.gridLineColor,p.style.background=f.gridLineColor,p.style.border=`1px solid ${f.axisTickColor}`,p.style.borderRadius="8px",p.style.boxSizing="border-box";const x=`1px solid ${f.axisLineColor}`;h.style.background=f.axisTickColor,h.style.borderRight=x,l.style.background=f.axisTickColor,l.style.borderLeft=x,m.style.background="transparent",m.style.backgroundImage="linear-gradient(90deg, rgba(255,255,255,0.0) 0, rgba(255,255,255,0.0) 42%, rgba(255,255,255,0.18) 42%, rgba(255,255,255,0.18) 46%, rgba(255,255,255,0.0) 46%, rgba(255,255,255,0.0) 54%, rgba(255,255,255,0.18) 54%, rgba(255,255,255,0.18) 58%, rgba(255,255,255,0.0) 58%, rgba(255,255,255,0.0) 100%)",m.style.mixBlendMode="normal"},dispose:()=>{if(!C){C=!0,F==null||F(),F=null;try{I()}catch{}h.removeEventListener("pointerdown",g),l.removeEventListener("pointerdown",v),m.removeEventListener("pointerdown",M),a.remove()}}}}let ki=null;async function Sd(){return ki||(ki=(async()=>{if(typeof window>"u")return{supported:!1,reason:"Not running in a browser environment (window is undefined)."};if(typeof navigator>"u")return{supported:!1,reason:"Navigator is not available in this environment."};if(!navigator.gpu)return{supported:!1,reason:"WebGPU API (navigator.gpu) is not available. Your browser does not support WebGPU."};try{let e=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});return e||(e=await navigator.gpu.requestAdapter()),e?{supported:!0}:{supported:!1,reason:"No compatible WebGPU adapter found. This may occur if: (1) no GPU is available, (2) GPU drivers are outdated or incompatible, (3) running in a VM or headless environment, or (4) WebGPU is disabled in browser settings."}}catch(e){let t="Failed to request WebGPU adapter.";return e instanceof DOMException?(t=`Failed to request WebGPU adapter: ${e.name}`,e.message&&(t+=` - ${e.message}`)):e instanceof Error?t=`Failed to request WebGPU adapter: ${e.message}`:t=`Failed to request WebGPU adapter: ${String(e)}`,{supported:!1,reason:t}}})(),ki)}const zt=120,Nd=1e3/60,Td=1.5,Id=6,Pd=500,Ad=e=>Array.isArray(e),$n=e=>Array.isArray(e),er=e=>Ad(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},Rd=e=>{if(Array.isArray(e))return e.length===0?[]:e.slice();const t=Xe(e);if(t===0)return[];const n=new Array(t);for(let i=0;i<t;i++){const r=Ee(e,i),o=We(e,i),s=mt(e,i);n[i]=s===void 0?[r,o]:[r,o,s]}return n},tr=e=>$n(e)?e[0]:e.timestamp,Xs=e=>$n(e)?e[2]:e.close,Ed=e=>{var t;return((t=e.dataZoom)==null?void 0:t.some(n=>(n==null?void 0:n.type)==="slider"))??!1},Vr=(e,t,n)=>Math.min(n,Math.max(t,e)),Dd=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;for(let o=0;o<e.length;o++){const{x:s,y:a}=er(e[o]);!Number.isFinite(s)||!Number.isFinite(a)||(s<t&&(t=s),s>n&&(n=s),a<i&&(i=a),a>r&&(r=a))}return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)?null:(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r})},Bd=(e,t)=>{if(t.length===0)return e;let n=e;if(!n){const a=Dd(t);if(!a)return e;n=a}let i=n.xMin,r=n.xMax,o=n.yMin,s=n.yMax;for(let a=0;a<t.length;a++){const{x:c,y:u}=er(t[a]);!Number.isFinite(c)||!Number.isFinite(u)||(c<i&&(i=c),c>r&&(r=c),u<o&&(o=u),u>s&&(s=u))}return i===r&&(r=i+1),o===s&&(s=o+1),{xMin:i,xMax:r,yMin:o,yMax:s}},Ld=(e,t)=>{if(t.length===0)return e;let n=(e==null?void 0:e.xMin)??Number.POSITIVE_INFINITY,i=(e==null?void 0:e.xMax)??Number.NEGATIVE_INFINITY,r=(e==null?void 0:e.yMin)??Number.POSITIVE_INFINITY,o=(e==null?void 0:e.yMax)??Number.NEGATIVE_INFINITY;for(let s=0;s<t.length;s++){const a=t[s],c=tr(a),u=$n(a)?a[3]:a.low,p=$n(a)?a[4]:a.high;!Number.isFinite(c)||!Number.isFinite(u)||!Number.isFinite(p)||(c<n&&(n=c),c>i&&(i=c),u<r&&(r=u),p>o&&(o=p))}return!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(o)?e:(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o})},Or=(e,t)=>{let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(let s=0;s<e.length;s++){const a=e[s];if(a.type==="pie")continue;const c=(t==null?void 0:t[s])??null;if(c){const h=c;if(Number.isFinite(h.xMin)&&Number.isFinite(h.xMax)&&Number.isFinite(h.yMin)&&Number.isFinite(h.yMax)){h.xMin<n&&(n=h.xMin),h.xMax>i&&(i=h.xMax),h.yMin<r&&(r=h.yMin),h.yMax>o&&(o=h.yMax);continue}}const u=a.rawBounds??null;if(u){const h=u;if(Number.isFinite(h.xMin)&&Number.isFinite(h.xMax)&&Number.isFinite(h.yMin)&&Number.isFinite(h.yMax)){h.xMin<n&&(n=h.xMin),h.xMax>i&&(i=h.xMax),h.yMin<r&&(r=h.yMin),h.yMax>o&&(o=h.yMax);continue}}if(a.type==="candlestick"){const h=a.data;for(let l=0;l<h.length;l++){const m=h[l],C=tr(m),F=$n(m)?m[3]:m.low,R=$n(m)?m[4]:m.high;!Number.isFinite(C)||!Number.isFinite(F)||!Number.isFinite(R)||(C<n&&(n=C),C>i&&(i=C),F<r&&(r=F),R>o&&(o=R))}continue}const p=sn(a.data);p&&(p.xMin<n&&(n=p.xMin),p.xMax>i&&(i=p.xMax),p.yMin<r&&(r=p.yMin),p.yMax>o&&(o=p.yMax))}return!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(o)?{xMin:0,xMax:1,yMin:0,yMax:1}:(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o})},Ln=(e,t)=>{let n=e,i=t;if((!Number.isFinite(n)||!Number.isFinite(i))&&(n=0,i=1),n===i)i=n+1;else if(n>i){const r=n;n=i,i=r}return{min:n,max:i}},ci=(e,t)=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;const n=e.trim();if(n.length===0)return null;if(n.endsWith("%")){const r=Number.parseFloat(n.slice(0,-1));return Number.isFinite(r)?r/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},Ys=(e,t,n)=>{const i=(e==null?void 0:e[0])??"50%",r=(e==null?void 0:e[1])??"50%",o=ci(i,t),s=ci(r,n);return{x:Number.isFinite(o)?o:t*.5,y:Number.isFinite(s)?s:n*.5}},kd=e=>Array.isArray(e),Hs=(e,t)=>{if(e==null)return{inner:0,outer:t*.7};if(kd(e)){const r=ci(e[0],t),o=ci(e[1],t),s=Math.max(0,Number.isFinite(r)?r:0),a=Math.max(s,Number.isFinite(o)?o:t*.7);return{inner:s,outer:Math.min(t,a)}}const n=ci(e,t),i=Math.max(0,Number.isFinite(n)?n:t*.7);return{inner:0,outer:Math.min(t,i)}};async function xa(e,t){var Lt;const n=await Sd();if(!n.supported){const k=n.reason||"Unknown reason";throw new Error(`ChartGPU: WebGPU is not available.
|
|
1126
|
+
Reason: ${k}
|
|
1127
|
+
Browser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.
|
|
1128
|
+
Resources:
|
|
1129
|
+
- MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API
|
|
1130
|
+
- Browser compatibility: https://caniuse.com/webgpu
|
|
1131
|
+
- WebGPU specification: https://www.w3.org/TR/webgpu/
|
|
1132
|
+
- Check your system: https://webgpureport.org/`)}const i=document.createElement("canvas");i.style.display="block",i.style.width="100%",i.style.height="100%",e.appendChild(i);let r=!1,o=null,s=null,a=null,c=null,u=null,p=null,h=t,l=Ws(h),m=new Array(l.series.length).fill(null).map(()=>[]),C=new Array(l.series.length).fill(null),F=null;const R=()=>{m=new Array(l.series.length).fill(null).map(()=>[]),C=new Array(l.series.length).fill(null),F=null;for(let k=0;k<l.series.length;k++){const j=l.series[k];if(j.type!=="pie")if(j.type==="candlestick"){const ue=j.rawData??j.data;m[k]=ue.length===0?[]:ue.slice(),C[k]=j.rawBounds??null}else{const ue=j.rawData??j.data;m[k]=Rd(ue),C[k]=j.rawBounds??null??sn(ue)}}},S=()=>F||(F=l.series.map((k,j)=>k.type==="pie"?k:k.type==="candlestick"?{...k,data:m[j]??k.data}:{...k,data:m[j]??k.data}),F);R();let y=Or(l.series,C),b=null;const w={click:new Set,mouseover:new Set,mouseout:new Set,crosshairMove:new Set};let d=null,g=null,v=null;const M=new Set;let I=null,T=null,E=!0;const f=new Float64Array(zt);let x=0,N=0,A=0,P=0,L=0,B=0;const V=performance.now();let _=0,re=0;const Y=new Set,W=()=>w.mouseover.size>0||w.mouseout.size>0,Z=()=>w.click.size>0,oe=()=>{I!==null&&(cancelAnimationFrame(I),I=null)},ee=()=>{r||(E=!0,I===null&&(I=requestAnimationFrame(()=>{if(I=null,r)return;const k=performance.now();f[x]=k,x=(x+1)%zt,N<zt&&N++,A++,_>0&&(k-_>Nd*Td?(P++,L++,B=k):L=0),_=k,ge(!1),E&&(E=!1,s==null||s.render()),re=performance.now()-k;const ue=ke();for(const Se of Y)try{Se(ue)}catch(De){console.error("Error in performance update callback:",De)}})))},q=()=>{if(c)try{c()}finally{c=null}},de=()=>{p==null||p.dispose(),p=null},G=()=>{u==null||u.remove(),u=null},te=()=>{de(),G()},X=32,Q=8,ne=X+Q,H=()=>{if(u)return u;try{window.getComputedStyle(e).position==="static"&&(e.style.position="relative")}catch{}const k=document.createElement("div");return k.style.position="absolute",k.style.left="0",k.style.right="0",k.style.bottom="0",k.style.height=`${ne}px`,k.style.paddingTop=`${Q}px`,k.style.boxSizing="border-box",k.style.pointerEvents="auto",k.style.zIndex="5",e.appendChild(k),u=k,k},O=(k,j)=>{const ue=k.end-k.start;return!Number.isFinite(ue)||ue===0?.5:Vr((j-k.start)/ue,0,1)},se=()=>({getRange:()=>(s==null?void 0:s.getZoomRange())??{start:0,end:100},setRange:(Me,ve)=>{s==null||s.setZoomRange(Me,ve)},zoomIn:(Me,ve)=>{if(!Number.isFinite(Me)||!Number.isFinite(ve)||ve<=1)return;const Ce=s==null?void 0:s.getZoomRange();if(!Ce)return;const Fe=Vr(Me,0,100),yt=O(Ce,Fe),tt=(Ce.end-Ce.start)/ve,kt=Fe-yt*tt;s==null||s.setZoomRange(kt,kt+tt)},zoomOut:(Me,ve)=>{if(!Number.isFinite(Me)||!Number.isFinite(ve)||ve<=1)return;const Ce=s==null?void 0:s.getZoomRange();if(!Ce)return;const Fe=Vr(Me,0,100),yt=O(Ce,Fe),tt=(Ce.end-Ce.start)*ve,kt=Fe-yt*tt;s==null||s.setZoomRange(kt,kt+tt)},pan:Me=>{if(!Number.isFinite(Me))return;const ve=s==null?void 0:s.getZoomRange();ve&&(s==null||s.setZoomRange(ve.start+Me,ve.end+Me))},onChange:Me=>(s==null?void 0:s.onZoomRangeChange(Me))??(()=>{})}),ce=()=>{if(!Ed(h)){te();return}if(!s||!s.getZoomRange())return;const j=H();p||(p=Fd(j,se(),{height:X,marginTop:0})),p.update(l.theme)},le=()=>{q(),!r&&s&&(c=s.onInteractionXChange((k,j)=>{be("crosshairMove",{x:k,source:j})}))},me=()=>{if(r||!o||!o.initialized)return;const k=(s==null?void 0:s.getZoomRange())??null;q(),de(),s==null||s.dispose(),s=nd(o,l,{onRequestRender:ee}),a=o.preferredFormat,le(),k&&s.setZoomRange(k.start,k.end),ce()},ge=k=>{var St;if(r)return;const j=i.getBoundingClientRect(),ue=window.devicePixelRatio||1,Se=((St=o==null?void 0:o.device)==null?void 0:St.limits.maxTextureDimension2D)??8192,De=Math.min(Se,Math.max(1,Math.round(j.width*ue))),Ye=Math.min(Se,Math.max(1,Math.round(j.height*ue))),Me=i.width!==De||i.height!==Ye;Me&&(i.width=De,i.height=Ye);const ve=o==null?void 0:o.device,Ce=o==null?void 0:o.canvasContext,Fe=o==null?void 0:o.preferredFormat;let yt=!1;ve&&Ce&&Fe&&(Me||!T||T.width!==i.width||T.height!==i.height||T.format!==Fe)&&(Ce.configure({device:ve,format:Fe,alphaMode:"opaque"}),T={width:i.width,height:i.height,format:Fe},yt=!0,s&&a!==Fe&&me()),k&&(Me||yt)&&ee()},we=()=>ge(!0),it=k=>{const j=i.getBoundingClientRect();if(!(j.width>0)||!(j.height>0))return{match:null,isInGrid:!1};const ue=k.clientX-j.left,Se=k.clientY-j.top,De=l.grid.left,Ye=l.grid.top,Me=j.width-l.grid.left-l.grid.right,ve=j.height-l.grid.top-l.grid.bottom;if(!(Me>0)||!(ve>0))return{match:null,isInGrid:!1};const Ce=ue-De,Fe=Se-Ye;if(!(Ce>=0&&Ce<=Me&&Fe>=0&&Fe<=ve))return{match:null,isInGrid:!1};const St=l.xAxis.min??y.xMin,tt=l.xAxis.max??y.xMax,kt=l.yAxis.min??y.yMin,qt=l.yAxis.max??y.yMax,He=Ln(St,tt),Ut=(s==null?void 0:s.getZoomRange())??null,at=(()=>{if(!Ut)return He;const Pe=He.max-He.min;if(!Number.isFinite(Pe)||Pe===0)return He;const Be=Ut.start,je=Ut.end,xt=He.min+Be/100*Pe,lt=He.min+je/100*Pe;return Ln(xt,lt)})(),ct=Ln(kt,qt);if(!(b!==null&&b.rectWidthCss===j.width&&b.rectHeightCss===j.height&&b.plotWidthCss===Me&&b.plotHeightCss===ve&&b.xDomainMin===at.min&&b.xDomainMax===at.max&&b.yDomainMin===ct.min&&b.yDomainMax===ct.max)){const Pe=an().domain(at.min,at.max).range(0,Me),Be=an().domain(ct.min,ct.max).range(ve,0);b={rectWidthCss:j.width,rectHeightCss:j.height,plotWidthCss:Me,plotHeightCss:ve,xDomainMin:at.min,xDomainMax:at.max,yDomainMin:ct.min,yDomainMax:ct.max,xScale:Pe,yScale:Be}}const vt=b,Ot=(()=>{const Pe=.5*Math.min(Me,ve);if(!(Pe>0))return null;for(let Be=l.series.length-1;Be>=0;Be--){const je=l.series[Be];if(je.type!=="pie"||je.visible===!1)continue;const xt=je,lt=Ys(xt.center,Me,ve),cn=Hs(xt.radius,Pe),Pt=qr(Ce,Fe,{seriesIndex:Be,series:xt},lt,cn);if(!Pt)continue;const jt=Pt.slice.value;return{kind:"pie",seriesIndex:Pt.seriesIndex,dataIndex:Pt.dataIndex,sliceValue:typeof jt=="number"&&Number.isFinite(jt)?jt:0}}return null})();if(Ot)return{match:Ot,isInGrid:!0};for(let Pe=l.series.length-1;Pe>=0;Pe--){const Be=l.series[Pe];if((Be==null?void 0:Be.type)!=="candlestick"||Be.visible===!1)continue;const je=Be,xt=Yr(je,je.data,vt.xScale,Me),lt=Hr([je],Ce,Fe,vt.xScale,vt.yScale,xt);if(lt)return{match:{kind:"candlestick",seriesIndex:Pe,dataIndex:lt.dataIndex,point:lt.point},isInGrid:!0}}const Zt=Zi(S(),Ce,Fe,vt.xScale,vt.yScale);return{match:Zt?{kind:"cartesian",match:Zt}:null,isInGrid:!0}},Ke=()=>{if(N<2)return 0;const k=(x-N+zt)%zt;let j=0;for(let De=1;De<N;De++){const Ye=(k+De-1)%zt,Me=(k+De)%zt,ve=f[Me]-f[Ye];j+=ve}const ue=j/(N-1);return ue>0?1e3/ue:0},et=()=>{if(N<2)return{min:0,max:0,avg:0,p50:0,p95:0,p99:0};const k=(x-N+zt)%zt,j=new Array(N-1);let ue=Number.POSITIVE_INFINITY,Se=Number.NEGATIVE_INFINITY,De=0;for(let Fe=1;Fe<N;Fe++){const yt=(k+Fe-1)%zt,St=(k+Fe)%zt,tt=f[St]-f[yt];j[Fe-1]=tt,tt<ue&&(ue=tt),tt>Se&&(Se=tt),De+=tt}const Ye=De/j.length;j.sort((Fe,yt)=>Fe-yt);const Me=Math.floor(j.length*.5),ve=Math.floor(j.length*.95),Ce=Math.floor(j.length*.99);return{min:ue,max:Se,avg:Ye,p50:j[Me],p95:j[ve],p99:j[Ce]}},ke=()=>{const k=Ke(),j=et(),ue={enabled:!1,cpuTime:re,gpuTime:0},Se={used:0,peak:0,allocated:0},De={totalDrops:P,consecutiveDrops:L,lastDropTimestamp:B},Ye=performance.now()-V;return{fps:k,frameTimeStats:j,gpuTiming:ue,memory:Se,frameDrops:De,totalFrames:A,elapsedTime:Ye}},he=(k,j)=>{if(!k)return{seriesIndex:null,dataIndex:null,value:null,seriesName:null,event:j};const ue=k.kind==="cartesian"?k.match.seriesIndex:k.seriesIndex,Se=k.kind==="cartesian"?k.match.dataIndex:k.dataIndex,De=l.series[ue],Ye=(De==null?void 0:De.name)??null,Me=Ye&&Ye.trim().length>0?Ye:null;if(k.kind==="pie")return{seriesIndex:ue,dataIndex:Se,value:[0,k.sliceValue],seriesName:Me,event:j};if(k.kind==="candlestick"){const Fe=tr(k.point),yt=Xs(k.point);return{seriesIndex:ue,dataIndex:Se,value:[Fe,yt],seriesName:Me,event:j}}const{x:ve,y:Ce}=er(k.match.point);return{seriesIndex:ue,dataIndex:Se,value:[ve,Ce],seriesName:Me,event:j}},be=(k,j)=>{if(!r)for(const ue of w[k])ue(j)},Ge=(k,j)=>{const ue=v;if(v=k,ue===null&&k===null)return;if(ue===null&&k!==null){be("mouseover",he(k,j));return}if(ue!==null&&k===null){be("mouseout",he(ue,j));return}if(ue===null||k===null)return;const Se=ue.kind==="cartesian"?ue.match.seriesIndex:ue.seriesIndex,De=ue.kind==="cartesian"?ue.match.dataIndex:ue.dataIndex,Ye=k.kind==="cartesian"?k.match.seriesIndex:k.seriesIndex,Me=k.kind==="cartesian"?k.match.dataIndex:k.dataIndex;Se===Ye&&De===Me||(be("mouseout",he(ue,j)),be("mouseover",he(k,j)))},ze=k=>{d&&k.isPrimary&&k.pointerId===d.pointerId&&(d=null)},rt=k=>{if(r||!W())return;const{match:j,isInGrid:ue}=it(k);if(!ue){Ge(null,k);return}Ge(j,k)},Ze=k=>{r||!W()&&!d||(ze(k),Ge(null,k))},ht=k=>{r||!W()&&!d||(ze(k),Ge(null,k))},gt=k=>{if(!r&&!(!W()&&!d&&g!==k.pointerId)){if(g===k.pointerId){g=null;return}ze(k),Ge(null,k)}},ot=k=>{if(!r&&Z()&&k.isPrimary&&!(k.pointerType==="mouse"&&k.button!==0)){d={pointerId:k.pointerId,startClientX:k.clientX,startClientY:k.clientY,startTimeMs:k.timeStamp};try{i.setPointerCapture(k.pointerId)}catch{}}},Ft=k=>{if(r||!Z()||!k.isPrimary||!d||k.pointerId!==d.pointerId)return;const j=k.timeStamp-d.startTimeMs,ue=k.clientX-d.startClientX,Se=k.clientY-d.startClientY,De=ue*ue+Se*Se;d=null;try{i.hasPointerCapture(k.pointerId)&&(g=k.pointerId,i.releasePointerCapture(k.pointerId))}catch{}const Ye=Id;if(!(j<=Pd&&De<=Ye*Ye))return;const{match:ve}=it(k);be("click",he(ve,k))};i.addEventListener("pointermove",rt,{passive:!0}),i.addEventListener("pointerleave",Ze,{passive:!0}),i.addEventListener("pointercancel",ht,{passive:!0}),i.addEventListener("lostpointercapture",gt,{passive:!0}),i.addEventListener("pointerdown",ot,{passive:!0}),i.addEventListener("pointerup",Ft,{passive:!0});const It=()=>{if(!r){r=!0;try{oe(),te(),q(),s==null||s.dispose(),s=null,a=null,o==null||o.destroy()}finally{d=null,g=null,v=null,b=null,i.removeEventListener("pointermove",rt),i.removeEventListener("pointerleave",Ze),i.removeEventListener("pointercancel",ht),i.removeEventListener("lostpointercapture",gt),i.removeEventListener("pointerdown",ot),i.removeEventListener("pointerup",Ft),w.click.clear(),w.mouseover.clear(),w.mouseout.clear(),w.crosshairMove.clear(),o=null,i.remove()}}},Bt={get options(){return h},get disposed(){return r},setOption(k){r||(h=k,l=Ws(k),s==null||s.setOptions(l),R(),y=Or(l.series,C),b=null,ce(),ee())},appendData(k,j){if(r||!Number.isFinite(k)||k<0||k>=l.series.length||!j||j.length===0)return;const ue=l.series[k];if(ue.type==="pie"){M.has(k)||(M.add(k),console.warn(`ChartGPU.appendData(${k}, ...): pie series are not supported by streaming append. Use setOption(...) to replace pie data.`));return}if(s==null||s.appendData(k,j),ue.type==="candlestick"){const Se=m[k]??[];Se.push(...j),m[k]=Se,C[k]=Ld(C[k],j)}else{const Se=m[k]??[];Se.push(...j),m[k]=Se,C[k]=Bd(C[k],j)}y=Or(l.series,C),F=null,b=null,ee()},resize:we,dispose:It,on(k,j){r||w[k].add(j)},off(k,j){w[k].delete(j)},getInteractionX(){return r?null:(s==null?void 0:s.getInteractionX())??null},setInteractionX(k,j){r||s==null||s.setInteractionX(k,j)},setCrosshairX(k,j){r||s==null||s.setInteractionX(k,j)},onInteractionXChange(k){return r?()=>{}:(s==null?void 0:s.onInteractionXChange(k))??(()=>{})},getZoomRange(){return r?null:(s==null?void 0:s.getZoomRange())??null},setZoomRange(k,j){r||s==null||s.setZoomRange(k,j)},getPerformanceMetrics(){return r?null:ke()},getPerformanceCapabilities(){return r?null:{gpuTimingSupported:!1,highResTimerSupported:typeof performance<"u"&&typeof performance.now=="function",performanceMetricsSupported:!0}},onPerformanceUpdate(k){return r?()=>{}:(Y.add(k),()=>{Y.delete(k)})},hitTest(k){const j=i.getBoundingClientRect(),ue=k.clientX-j.left,Se=k.clientY-j.top;if(r||!(j.width>0)||!(j.height>0))return{isInGrid:!1,canvasX:ue,canvasY:Se,gridX:0,gridY:0,match:null};const De=l.grid.left,Ye=l.grid.top,Me=j.width-l.grid.left-l.grid.right,ve=j.height-l.grid.top-l.grid.bottom,Ce=ue-De,Fe=Se-Ye;if(!(Me>0)||!(ve>0))return{isInGrid:!1,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:null};if(!(Ce>=0&&Ce<=Me&&Fe>=0&&Fe<=ve))return{isInGrid:!1,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:null};const St=l.xAxis.min??y.xMin,tt=l.xAxis.max??y.xMax,kt=l.yAxis.min??y.yMin,qt=l.yAxis.max??y.yMax,He=Ln(St,tt),Ut=(s==null?void 0:s.getZoomRange())??null,at=(()=>{if(!Ut)return He;const Pe=He.max-He.min;if(!Number.isFinite(Pe)||Pe===0)return He;const Be=Ut.start,je=Ut.end,xt=He.min+Be/100*Pe,lt=He.min+je/100*Pe;return Ln(xt,lt)})(),ct=Ln(kt,qt);if(!(b!==null&&b.rectWidthCss===j.width&&b.rectHeightCss===j.height&&b.plotWidthCss===Me&&b.plotHeightCss===ve&&b.xDomainMin===at.min&&b.xDomainMax===at.max&&b.yDomainMin===ct.min&&b.yDomainMax===ct.max)){const Pe=an().domain(at.min,at.max).range(0,Me),Be=an().domain(ct.min,ct.max).range(ve,0);b={rectWidthCss:j.width,rectHeightCss:j.height,plotWidthCss:Me,plotHeightCss:ve,xDomainMin:at.min,xDomainMax:at.max,yDomainMin:ct.min,yDomainMax:ct.max,xScale:Pe,yScale:Be}}const vt=b,Ot=(()=>{const Pe=.5*Math.min(Me,ve);if(!(Pe>0))return null;for(let Be=l.series.length-1;Be>=0;Be--){const je=l.series[Be];if(je.type!=="pie")continue;const xt=je,lt=Ys(xt.center,Me,ve),cn=Hs(xt.radius,Pe),Pt=qr(Ce,Fe,{seriesIndex:Be,series:xt},lt,cn);if(!Pt)continue;const jt=Pt.slice.value;return{kind:"pie",seriesIndex:Pt.seriesIndex,dataIndex:Pt.dataIndex,sliceValue:typeof jt=="number"&&Number.isFinite(jt)?jt:0}}return null})();if(Ot)return{isInGrid:!0,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:{kind:"pie",seriesIndex:Ot.seriesIndex,dataIndex:Ot.dataIndex,value:[0,Ot.sliceValue]}};for(let Pe=l.series.length-1;Pe>=0;Pe--){const Be=l.series[Pe];if((Be==null?void 0:Be.type)!=="candlestick")continue;const je=Be,xt=Yr(je,je.data,vt.xScale,Me),lt=Hr([je],Ce,Fe,vt.xScale,vt.yScale,xt);if(!lt)continue;const cn=tr(lt.point),Pt=Xs(lt.point);return{isInGrid:!0,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:{kind:"candlestick",seriesIndex:Pe,dataIndex:lt.dataIndex,value:[cn,Pt]}}}const Zt=Zi(S(),Ce,Fe,vt.xScale,vt.yScale);if(Zt){const{x:Pe,y:Be}=er(Zt.point);return{isInGrid:!0,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:{kind:"cartesian",seriesIndex:Zt.seriesIndex,dataIndex:Zt.dataIndex,value:[Pe,Be]}}}return{isInGrid:!0,canvasX:ue,canvasY:Se,gridX:Ce,gridY:Fe,match:null}}};try{ge(!1);try{o=await nr.create(i)}catch(k){const j=k instanceof Error?k.message:String(k);throw new Error(`ChartGPU: WebGPU is not available.
|
|
1133
|
+
Reason: ${j}
|
|
1134
|
+
Browser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.
|
|
1135
|
+
Resources:
|
|
1136
|
+
- MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API
|
|
1137
|
+
- Browser compatibility: https://caniuse.com/webgpu
|
|
1138
|
+
- WebGPU specification: https://www.w3.org/TR/webgpu/
|
|
1139
|
+
- Check your system: https://webgpureport.org/`)}return(Lt=o.device)==null||Lt.lost.then(k=>{r||(k.reason!=="destroyed"&&console.warn("WebGPU device lost:",k),It())}),ge(!1),me(),ce(),ee(),Bt}catch(k){throw Bt.dispose(),k}}const Ud={create:xa};function _d(e){const t=Symbol("ChartGPU.connectCharts");let n=!1;const i=[],r=(o,s)=>{for(const a of e)a!==o&&(a.disposed||a.setCrosshairX(s,t))};for(const o of e){if(o.disposed)continue;const s=c=>{n||c.source!==t&&(o.disposed||r(o,c.x))};o.on("crosshairMove",s);const a=()=>o.off("crosshairMove",s);i.push(a)}return()=>{if(!n){n=!0;for(const o of i)o();i.length=0;for(const o of e)o.disposed||o.setCrosshairX(null,t)}}}function Gd(e,t,n={}){const i=n.lineTolerance??20,r=n.textTolerance??8,o=n.pointTolerance??16;let s=new Map,a=new Map,c=!1;const u=f=>Array.isArray(f),p=f=>Array.isArray(f),h=f=>u(f)?f[0]:f.x,l=f=>u(f)?f[1]:f.y,m=f=>p(f)?f[0]:f.timestamp,C=f=>p(f)?f[2]:f.high,F=f=>p(f)?f[3]:f.low;function R(){var P,L;const f=e.options;let x=(P=f.xAxis)==null?void 0:P.min,N=(L=f.xAxis)==null?void 0:L.max;if(x===void 0||N===void 0){const B=f.series??[];let V=Number.POSITIVE_INFINITY,_=Number.NEGATIVE_INFINITY;for(const re of B)if(re.type!=="pie")if(re.type==="candlestick"){const Y=re.data;for(const W of Y){const Z=m(W);Z<V&&(V=Z),Z>_&&(_=Z)}}else{const Y=re.data;for(const W of Y){const Z=h(W);Z<V&&(V=Z),Z>_&&(_=Z)}}x===void 0&&(x=Number.isFinite(V)?V:0),N===void 0&&(N=Number.isFinite(_)?_:100)}const A=e.getZoomRange();if(A){const B=N-x,V=x+A.start/100*B,_=x+A.end/100*B;return{min:V,max:_}}return{min:x,max:N}}function S(){var A,P;const f=e.options;let x=(A=f.yAxis)==null?void 0:A.min,N=(P=f.yAxis)==null?void 0:P.max;if(x===void 0||N===void 0){const L=f.series??[];let B=Number.POSITIVE_INFINITY,V=Number.NEGATIVE_INFINITY;for(const _ of L)if(_.type!=="pie")if(_.type==="candlestick"){const re=_.data;for(const Y of re){const W=C(Y),Z=F(Y);W>V&&(V=W),Z<B&&(B=Z)}}else{const re=_.data;for(const Y of re){const W=l(Y);W<B&&(B=W),W>V&&(V=W)}}x===void 0&&(x=Number.isFinite(B)?B:0),N===void 0&&(N=Number.isFinite(V)?V:100)}return{min:x,max:N}}function y(f,x){const N=e.options,A=t.getBoundingClientRect(),P=N.grid??{left:60,right:20,top:40,bottom:40},L=A.width,B=A.height,V=P.left??60,_=L-(P.right??20),re=P.top??40,Y=B-(P.bottom??40),W=_-V,Z=Y-re,oe=N.xAxis,ee=N.yAxis;let q=0,de=0;if(f!==void 0&&oe)if(oe.type==="category"&&Array.isArray(oe.data)){const G=oe.data,te=G.indexOf(String(f));if(te>=0){const X=te/(G.length-1||1);q=V+X*W}}else{const G=R(),te=G.min,X=G.max,Q=(f-te)/(X-te||1);q=V+Q*W}if(x!==void 0&&ee){const G=S(),te=G.min,X=G.max,Q=(x-te)/(X-te||1);de=Y-Q*Z}return{x:q,y:de}}function b(f,x){const N=e.options,A=t.getBoundingClientRect(),P=N.grid??{left:60,right:20,top:40,bottom:40},L=A.width,B=A.height,V=P.left??60,_=L-(P.right??20),re=P.top??40,Y=B-(P.bottom??40),W=_-V,Z=Y-re;return{x:V+f*W,y:re+x*Z}}function w(f){s.clear(),f.forEach((x,N)=>{const A={};if(x.type==="lineX"&&x.x!==void 0){const{x:P}=y(x.x,void 0);A.canvasX=P}else if(x.type==="lineY"&&x.y!==void 0){const{y:P}=y(void 0,x.y);A.canvasY=P}else if(x.type==="point"&&x.x!==void 0&&x.y!==void 0){const{x:P,y:L}=y(x.x,x.y);A.canvasX=P,A.canvasY=L}else if(x.type==="text"){const P=x.position;if(P.space==="plot"){const{x:L,y:B}=b(P.x,P.y);A.canvasX=L,A.canvasY=B}else if(P.space==="data"){const{x:L,y:B}=y(P.x,P.y);A.canvasX=L,A.canvasY=B}}s.set(N,A)}),c=!0}function d(f,x,N,A){return N!==void 0?Math.abs(f-N):A!==void 0?Math.abs(x-A):1/0}function g(f,x,N,A){const P=f-N,L=x-A;return Math.sqrt(P*P+L*L)}function v(f,x,N,A){return f>=N.left-A&&f<=N.right+A&&x>=N.top-A&&x<=N.bottom+A}function M(f,x){const N=e.options.annotations??[];if(N.length===0)return null;c||w(N);let A=null,P=1/0;for(let L=0;L<N.length;L++){const B=N[L],V=s.get(L);if(V){if(B.type==="lineX"&&V.canvasX!==void 0){const _=d(f,x,V.canvasX,void 0);_<=i&&_<P&&(P=_,A={annotationIndex:L,annotation:B,hitType:"line",distanceCssPx:_})}else if(B.type==="lineY"&&V.canvasY!==void 0){const _=d(f,x,void 0,V.canvasY);_<=i&&_<P&&(P=_,A={annotationIndex:L,annotation:B,hitType:"line",distanceCssPx:_})}}}for(let L=0;L<N.length;L++){const B=N[L],V=a.get(L);if(B.type==="text"&&V&&v(f,x,V,r)){const _=V.left+V.width/2,re=V.top+V.height/2,Y=g(f,x,_,re);Y<P&&(P=Y,A={annotationIndex:L,annotation:B,hitType:"text",distanceCssPx:Y})}}for(let L=0;L<N.length;L++){const B=N[L],V=s.get(L);if(V&&B.type==="point"&&V.canvasX!==void 0&&V.canvasY!==void 0){const _=g(f,x,V.canvasX,V.canvasY);_<=o&&_<P&&(P=_,A={annotationIndex:L,annotation:B,hitType:"point",distanceCssPx:_})}}return A}function I(f){a=new Map(f)}function T(){c=!1}function E(){s.clear(),a.clear()}return{hitTest:M,updateTextBounds:I,invalidateCache:T,dispose:E}}function zd(e,t,n){let i=null;const r=v=>Array.isArray(v),o=v=>Array.isArray(v),s=v=>r(v)?v[0]:v.x,a=v=>r(v)?v[1]:v.y,c=v=>o(v)?v[0]:v.timestamp,u=v=>o(v)?v[2]:v.high,p=v=>o(v)?v[3]:v.low;function h(){var E,f;const v=e.options;let M=(E=v.xAxis)==null?void 0:E.min,I=(f=v.xAxis)==null?void 0:f.max;if(M===void 0||I===void 0){const x=v.series??[];let N=Number.POSITIVE_INFINITY,A=Number.NEGATIVE_INFINITY;for(const P of x)if(P.type!=="pie")if(P.type==="candlestick"){const L=P.data;for(const B of L){const V=c(B);V<N&&(N=V),V>A&&(A=V)}}else{const L=P.data;for(const B of L){const V=s(B);V<N&&(N=V),V>A&&(A=V)}}M===void 0&&(M=Number.isFinite(N)?N:0),I===void 0&&(I=Number.isFinite(A)?A:100)}const T=e.getZoomRange();if(T){const x=I-M,N=M+T.start/100*x,A=M+T.end/100*x;return{min:N,max:A}}return{min:M,max:I}}function l(){var T,E;const v=e.options;let M=(T=v.yAxis)==null?void 0:T.min,I=(E=v.yAxis)==null?void 0:E.max;if(M===void 0||I===void 0){const f=v.series??[];let x=Number.POSITIVE_INFINITY,N=Number.NEGATIVE_INFINITY;for(const A of f)if(A.type!=="pie")if(A.type==="candlestick"){const P=A.data;for(const L of P){const B=u(L),V=p(L);B>N&&(N=B),V<x&&(x=V)}}else{const P=A.data;for(const L of P){const B=a(L);B<x&&(x=B),B>N&&(N=B)}}M===void 0&&(M=Number.isFinite(x)?x:0),I===void 0&&(I=Number.isFinite(N)?N:100)}return{min:M,max:I}}function m(v,M){const I=e.options,T=t.getBoundingClientRect(),E=I.grid??{left:60,right:20,top:40,bottom:40},f=T.width,x=T.height,N=E.left??60,A=f-(E.right??20),P=E.top??40,L=x-(E.bottom??40),B=A-N,V=L-P,_=I.xAxis,re=I.yAxis;let Y=0,W=0;if(_){const Z=(v-N)/B;if(_.type==="category"&&Array.isArray(_.data)){const oe=_.data,ee=Math.round(Z*(oe.length-1||1));Y=oe[Math.max(0,Math.min(ee,oe.length-1))]}else{const oe=h();Y=oe.min+Z*(oe.max-oe.min)}}if(re){const Z=(L-M)/V,oe=l();W=oe.min+Z*(oe.max-oe.min)}return{x:Y,y:W}}function C(v,M){const I=e.options,T=t.getBoundingClientRect(),E=I.grid??{left:60,right:20,top:40,bottom:40},f=T.width,x=T.height,N=E.left??60,A=f-(E.right??20),P=E.top??40,L=x-(E.bottom??40),B=A-N,V=L-P,_=(v-N)/B,re=(M-P)/V;return{x:Math.max(0,Math.min(1,_)),y:Math.max(0,Math.min(1,re))}}function F(v){if(!i)return;v.preventDefault();const M=t.getBoundingClientRect(),I=v.clientX-M.left,T=v.clientY-M.top,E=i.annotation,f={};if(E.type==="lineX"){const{x}=m(I,0);f.x=x}else if(E.type==="lineY"){const{y:x}=m(0,T);f.y=x}else if(E.type==="text"){const x=E.position.space;if(x==="plot"){const{x:N,y:A}=C(I,T);f.position={space:x,x:N,y:A}}else{const{x:N,y:A}=m(I,T);f.position={space:x,x:N,y:A}}}else if(E.type==="point"){const{x,y:N}=m(I,T);f.x=x,f.y=N}n.onDragMove(i.annotationIndex,f)}function R(v){if(!i)return;const M=t.getBoundingClientRect(),I=v.clientX-M.left,T=v.clientY-M.top,E=i.annotation,f={};if(E.type==="lineX"){const{x}=m(I,0);f.x=x}else if(E.type==="lineY"){const{y:x}=m(0,T);f.y=x}else if(E.type==="text"){const x=E.position.space;if(x==="plot"){const{x:N,y:A}=C(I,T);f.position={space:x,x:N,y:A}}else{const{x:N,y:A}=m(I,T);f.position={space:x,x:N,y:A}}}else if(E.type==="point"){const{x,y:N}=m(I,T);f.x=x,f.y=N}n.onDragEnd(i.annotationIndex,f),b()}function S(){i&&(n.onDragCancel(),b())}function y(v){i&&v.key==="Escape"&&(v.preventDefault(),S())}function b(){if(i){if(window.removeEventListener("pointermove",F),window.removeEventListener("pointerup",R),window.removeEventListener("pointercancel",S),document.removeEventListener("keydown",y),i.pointerId!==null)try{t.releasePointerCapture(i.pointerId)}catch{}document.body.style.cursor="",i=null}}function w(v,M,I,T){i&&b(),i={annotationIndex:v,annotation:M,startPointerX:I,startPointerY:T,pointerId:null},M.type==="lineX"?document.body.style.cursor="ew-resize":M.type==="lineY"?document.body.style.cursor="ns-resize":document.body.style.cursor="grabbing",window.addEventListener("pointermove",F,{passive:!1}),window.addEventListener("pointerup",R,{passive:!0}),window.addEventListener("pointercancel",S,{passive:!0}),document.addEventListener("keydown",y,{passive:!1}),n.onDragMove(v,{style:{...M.style,opacity:.7}})}function d(){return i!==null}function g(){b()}return{startDrag:w,isDragging:d,dispose:g}}const Vd=["#ef4444","#f97316","#eab308","#22c55e","#06b6d4","#3b82f6","#8b5cf6","#ec4899","#ffffff","#94a3b8","#64748b","#1e293b"];function Od(e,t={}){const n=t.palette??Vd,i=t.zIndex??1e3;let r=null,o=null,s=null,a=null,c="create";function u(){const f=document.createElement("div");return f.style.cssText=`
|
|
1140
|
+
position: fixed;
|
|
1141
|
+
top: 0;
|
|
1142
|
+
left: 0;
|
|
1143
|
+
right: 0;
|
|
1144
|
+
bottom: 0;
|
|
1145
|
+
background: rgba(0, 0, 0, 0.4);
|
|
1146
|
+
z-index: ${i+1};
|
|
1147
|
+
display: flex;
|
|
1148
|
+
align-items: center;
|
|
1149
|
+
justify-content: center;
|
|
1150
|
+
`,f.addEventListener("click",x=>{x.target===f&&g()}),f}function p(){const f=document.createElement("div");return f.style.cssText=`
|
|
1151
|
+
width: 320px;
|
|
1152
|
+
background: #1a1a2e;
|
|
1153
|
+
border: 1px solid #333;
|
|
1154
|
+
border-radius: 8px;
|
|
1155
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.7);
|
|
1156
|
+
padding: 20px;
|
|
1157
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
1158
|
+
color: #e0e0e0;
|
|
1159
|
+
`,f}function h(f,x){const N=document.createElement("div");N.style.cssText=`
|
|
1160
|
+
margin-bottom: 16px;
|
|
1161
|
+
`;const A=document.createElement("label");return A.textContent=f,A.style.cssText=`
|
|
1162
|
+
display: block;
|
|
1163
|
+
margin-bottom: 8px;
|
|
1164
|
+
font-size: 13px;
|
|
1165
|
+
font-weight: 500;
|
|
1166
|
+
color: #b0b0b0;
|
|
1167
|
+
`,N.appendChild(A),N.appendChild(x),N}function l(f,x,N=""){const A=document.createElement("input");return A.type="text",A.placeholder=f,A.maxLength=x,A.value=N,A.style.cssText=`
|
|
1168
|
+
width: 100%;
|
|
1169
|
+
padding: 8px 12px;
|
|
1170
|
+
background: #2a2a3e;
|
|
1171
|
+
border: 1px solid #444;
|
|
1172
|
+
border-radius: 4px;
|
|
1173
|
+
color: #e0e0e0;
|
|
1174
|
+
font-size: 14px;
|
|
1175
|
+
box-sizing: border-box;
|
|
1176
|
+
`,A.addEventListener("focus",()=>{A.style.borderColor="#3b82f6"}),A.addEventListener("blur",()=>{A.style.borderColor="#444"}),A}function m(f,x,N=""){const A=document.createElement("textarea");return A.placeholder=f,A.maxLength=x,A.value=N,A.rows=3,A.style.cssText=`
|
|
1177
|
+
width: 100%;
|
|
1178
|
+
padding: 8px 12px;
|
|
1179
|
+
background: #2a2a3e;
|
|
1180
|
+
border: 1px solid #444;
|
|
1181
|
+
border-radius: 4px;
|
|
1182
|
+
color: #e0e0e0;
|
|
1183
|
+
font-size: 14px;
|
|
1184
|
+
box-sizing: border-box;
|
|
1185
|
+
resize: vertical;
|
|
1186
|
+
font-family: inherit;
|
|
1187
|
+
`,A.addEventListener("focus",()=>{A.style.borderColor="#3b82f6"}),A.addEventListener("blur",()=>{A.style.borderColor="#444"}),A}function C(f){const x=document.createElement("div");x.style.cssText=`
|
|
1188
|
+
display: grid;
|
|
1189
|
+
grid-template-columns: repeat(4, 1fr);
|
|
1190
|
+
gap: 8px;
|
|
1191
|
+
`;let N=f;return n.forEach(A=>{const P=document.createElement("button");P.type="button",P.dataset.color=A,P.style.cssText=`
|
|
1192
|
+
position: relative;
|
|
1193
|
+
width: 100%;
|
|
1194
|
+
aspect-ratio: 1;
|
|
1195
|
+
background: ${A};
|
|
1196
|
+
border: none;
|
|
1197
|
+
border-radius: 4px;
|
|
1198
|
+
cursor: pointer;
|
|
1199
|
+
transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
|
|
1200
|
+
box-shadow: ${A===N?"inset 0 0 0 2px #ffffff, inset 0 0 0 3px rgba(0, 0, 0, 0.3), 0 2px 8px rgba(0, 0, 0, 0.3)":"inset 0 0 0 1px rgba(255, 255, 255, 0.1)"};
|
|
1201
|
+
transform: ${A===N?"scale(1.05)":"scale(1)"};
|
|
1202
|
+
`;const L=document.createElementNS("http://www.w3.org/2000/svg","svg");L.setAttribute("viewBox","0 0 24 24"),L.setAttribute("fill","none"),L.style.cssText=`
|
|
1203
|
+
position: absolute;
|
|
1204
|
+
top: 50%;
|
|
1205
|
+
left: 50%;
|
|
1206
|
+
transform: translate(-50%, -50%);
|
|
1207
|
+
width: 60%;
|
|
1208
|
+
height: 60%;
|
|
1209
|
+
pointer-events: none;
|
|
1210
|
+
opacity: ${A===N?"1":"0"};
|
|
1211
|
+
transition: opacity 0.15s ease-out;
|
|
1212
|
+
`;const B=document.createElementNS("http://www.w3.org/2000/svg","path");B.setAttribute("d","M20 6L9 17l-5-5"),B.setAttribute("stroke","#ffffff"),B.setAttribute("stroke-width","3"),B.setAttribute("stroke-linecap","round"),B.setAttribute("stroke-linejoin","round"),B.style.cssText=`
|
|
1213
|
+
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.8)) drop-shadow(0 0 1px rgba(0, 0, 0, 0.9));
|
|
1214
|
+
`,L.appendChild(B),P.appendChild(L),P.addEventListener("click",()=>{N=A,Array.from(x.children).forEach(V=>{const _=V,Y=_.dataset.color===A;_.style.boxShadow=Y?"inset 0 0 0 2px #ffffff, inset 0 0 0 3px rgba(0, 0, 0, 0.3), 0 2px 8px rgba(0, 0, 0, 0.3)":"inset 0 0 0 1px rgba(255, 255, 255, 0.1)",_.style.transform=Y?"scale(1.05)":"scale(1)";const W=_.querySelector("svg");W&&(W.style.opacity=Y?"1":"0")})}),P.addEventListener("mouseenter",()=>{A!==N&&(P.style.transform="scale(1.1)",P.style.boxShadow="inset 0 0 0 2px rgba(255, 255, 255, 0.2), 0 4px 12px rgba(0, 0, 0, 0.4)")}),P.addEventListener("mouseleave",()=>{A!==N&&(P.style.transform="scale(1)",P.style.boxShadow="inset 0 0 0 1px rgba(255, 255, 255, 0.1)")}),x.appendChild(P)}),{container:x,getValue:()=>N}}function F(f,x){const N=document.createElement("select");return N.style.cssText=`
|
|
1215
|
+
width: 100%;
|
|
1216
|
+
padding: 8px 12px;
|
|
1217
|
+
background: #2a2a3e;
|
|
1218
|
+
border: 1px solid #444;
|
|
1219
|
+
border-radius: 4px;
|
|
1220
|
+
color: #e0e0e0;
|
|
1221
|
+
font-size: 14px;
|
|
1222
|
+
cursor: pointer;
|
|
1223
|
+
`,f.forEach(A=>{const P=document.createElement("option");P.value=A.value,P.textContent=A.label,A.value===x&&(P.selected=!0),N.appendChild(P)}),{container:N,getValue:()=>N.value}}function R(f,x,N,A,P=""){const L=document.createElement("div");L.style.cssText=`
|
|
1224
|
+
display: flex;
|
|
1225
|
+
align-items: center;
|
|
1226
|
+
gap: 12px;
|
|
1227
|
+
`;const B=document.createElement("input");B.type="range",B.min=String(f),B.max=String(x),B.step=String(N),B.value=String(A),B.style.cssText=`
|
|
1228
|
+
flex: 1;
|
|
1229
|
+
cursor: pointer;
|
|
1230
|
+
`;const V=document.createElement("span");return V.textContent=`${A}${P}`,V.style.cssText=`
|
|
1231
|
+
min-width: 40px;
|
|
1232
|
+
text-align: right;
|
|
1233
|
+
font-size: 13px;
|
|
1234
|
+
color: #b0b0b0;
|
|
1235
|
+
`,B.addEventListener("input",()=>{V.textContent=`${B.value}${P}`}),L.appendChild(B),L.appendChild(V),{container:L,getValue:()=>parseFloat(B.value)}}function S(f,x,N){const A=document.createElement("div");A.style.cssText=`
|
|
1236
|
+
display: flex;
|
|
1237
|
+
justify-content: flex-end;
|
|
1238
|
+
gap: 12px;
|
|
1239
|
+
margin-top: 24px;
|
|
1240
|
+
`;const P=document.createElement("button");P.type="button",P.textContent="Cancel",P.style.cssText=`
|
|
1241
|
+
padding: 8px 16px;
|
|
1242
|
+
background: transparent;
|
|
1243
|
+
border: 1px solid #444;
|
|
1244
|
+
border-radius: 4px;
|
|
1245
|
+
color: #888;
|
|
1246
|
+
font-size: 14px;
|
|
1247
|
+
cursor: pointer;
|
|
1248
|
+
transition: background 0.15s;
|
|
1249
|
+
`,P.addEventListener("mouseenter",()=>{P.style.background="#2a2a3e"}),P.addEventListener("mouseleave",()=>{P.style.background="transparent"}),P.addEventListener("click",N);const L=document.createElement("button");return L.type="button",L.textContent=f,L.style.cssText=`
|
|
1250
|
+
padding: 8px 16px;
|
|
1251
|
+
background: #2a2a3e;
|
|
1252
|
+
border: 1px solid #444;
|
|
1253
|
+
border-radius: 4px;
|
|
1254
|
+
color: #e0e0e0;
|
|
1255
|
+
font-size: 14px;
|
|
1256
|
+
font-weight: 500;
|
|
1257
|
+
cursor: pointer;
|
|
1258
|
+
transition: background 0.15s;
|
|
1259
|
+
`,L.addEventListener("mouseenter",()=>{L.style.background="#3a3a4e"}),L.addEventListener("mouseleave",()=>{L.style.background="#2a2a3e"}),L.addEventListener("click",x),A.appendChild(P),A.appendChild(L),A}function y(f){var _,re,Y,W;const x=document.createElement("div"),N=((_=f.label)==null?void 0:_.text)??"",A=l("Line label",100,N),P=C(((re=f.style)==null?void 0:re.color)??n[0]),L=F([{label:"Solid",value:"solid"},{label:"Dashed",value:"dashed"},{label:"Dotted",value:"dotted"}],(Y=f.style)!=null&&Y.lineDash?f.style.lineDash.length===4?"dashed":"dotted":"solid"),B=R(1,8,1,((W=f.style)==null?void 0:W.lineWidth)??2,"px");x.appendChild(h("Label (optional)",A)),x.appendChild(h("Color",P.container)),x.appendChild(h("Line Style",L.container)),x.appendChild(h("Line Width",B.container));const V=S(c==="create"?"Create":"Save",()=>{const Z={solid:void 0,dashed:[4,4],dotted:[2,2]},oe=A.value.trim(),ee={...f,label:oe?{...f.label,text:oe}:void 0,style:{...f.style,color:P.getValue(),lineWidth:B.getValue(),lineDash:Z[L.getValue()]}};d(ee)},()=>g());return x.appendChild(V),x}function b(f){var B;const x=document.createElement("div"),N=f.text??"",A=m("Text content",500,N),P=C(((B=f.style)==null?void 0:B.color)??n[0]);x.appendChild(h("Text",A)),x.appendChild(h("Color",P.container));const L=S(c==="create"?"Create":"Save",()=>{const V=A.value.trim();if(!V){A.style.borderColor="#ef4444",A.focus();return}const _={...f,text:V,style:{...f.style,color:P.getValue()}};d(_)},()=>g());return x.appendChild(L),x}function w(f){var _,re,Y,W,Z;const x=document.createElement("div"),N=((_=f.label)==null?void 0:_.text)??"",A=l("Point label",100,N),P=C(((re=f.style)==null?void 0:re.color)??n[0]),L=((Y=f.marker)==null?void 0:Y.size)??((Z=(W=f.marker)==null?void 0:W.style)==null?void 0:Z.markerSize)??8,B=R(4,16,1,L,"px");x.appendChild(h("Label (optional)",A)),x.appendChild(h("Color",P.container)),x.appendChild(h("Marker Size",B.container));const V=S(c==="create"?"Create":"Save",()=>{var q;const oe=A.value.trim(),ee={...f,label:oe?{...f.label,text:oe}:void 0,marker:{...f.marker,size:B.getValue(),style:{...(q=f.marker)==null?void 0:q.style,color:P.getValue()}}};d(ee)},()=>g());return x.appendChild(V),x}function d(f){s&&s(f),T()}function g(){a&&a(),T()}function v(f){f.key==="Escape"&&(f.preventDefault(),g())}function M(f,x,N,A){c="create",s=N,a=A,r=u(),o=p();const P=document.createElement("h3");P.textContent=`Add ${f==="lineX"?"Vertical Line":f==="lineY"?"Horizontal Line":f==="text"?"Text Note":"Point Marker"}`,P.style.cssText=`
|
|
1260
|
+
margin: 0 0 20px 0;
|
|
1261
|
+
font-size: 16px;
|
|
1262
|
+
font-weight: 600;
|
|
1263
|
+
color: #ffffff;
|
|
1264
|
+
`,o.appendChild(P);let L;f==="lineX"||f==="lineY"?L=y(x):f==="text"?L=b(x):L=w(x),o.appendChild(L),r.appendChild(o),e.appendChild(r),document.addEventListener("keydown",v);const B=o.querySelector("input, textarea");B&&setTimeout(()=>B.focus(),50)}function I(f,x,N){c="edit",s=x,a=N,r=u(),o=p();const A=document.createElement("h3");A.textContent="Edit Annotation",A.style.cssText=`
|
|
1265
|
+
margin: 0 0 20px 0;
|
|
1266
|
+
font-size: 16px;
|
|
1267
|
+
font-weight: 600;
|
|
1268
|
+
color: #ffffff;
|
|
1269
|
+
`,o.appendChild(A);let P;f.type==="lineX"||f.type==="lineY"?P=y(f):f.type==="text"?P=b(f):P=w(f),o.appendChild(P),r.appendChild(o),e.appendChild(r),document.addEventListener("keydown",v);const L=o.querySelector("input, textarea");L&&setTimeout(()=>L.focus(),50)}function T(){r&&r.parentNode&&r.parentNode.removeChild(r),r=null,o=null,s=null,a=null,document.removeEventListener("keydown",v)}function E(){T()}return{showCreate:M,showEdit:I,hide:T,dispose:E}}const ba=e=>Array.isArray(e),Jr=e=>Array.isArray(e),$d=e=>ba(e)?e[0]:e.x,Wd=e=>ba(e)?e[1]:e.y,Xd=e=>Jr(e)?e[0]:e.timestamp;function Yd(e,t,n={}){const{menuZIndex:i=1e3,enableContextMenu:r=!0}=n,o=e.querySelector("canvas");if(!o)throw new Error("createAnnotationAuthoring: canvas element not found in container");let s=[{annotations:t.options.annotations??[]}],a=0,c=!1;const u=Gd(t,o,{lineTolerance:20,textTolerance:8,pointTolerance:16}),p=Od(e,{zIndex:i}),h=zd(t,o,{onDragMove:(G,te)=>{const Q=l().map((ne,H)=>H===G?{...ne,...te}:ne);C(Q)},onDragEnd:(G,te)=>{const Q=l().map((ne,H)=>H===G?{...ne,...te}:ne);C(Q),m(Q)},onDragCancel:()=>{const G=s[a];G&&C(G.annotations)}}),l=()=>t.options.annotations??[],m=G=>{s=s.slice(0,a+1),s.push({annotations:[...G]}),a=s.length-1,s.length>50&&(s.shift(),a--)},C=G=>{t.setOption({...t.options,annotations:[...G]}),u.invalidateCache()};let F=null;const R=()=>{const G=document.createElement("div");return G.style.position="fixed",G.style.display="none",G.style.backgroundColor="#1a1a2e",G.style.border="1px solid #333",G.style.borderRadius="8px",G.style.boxShadow="0 4px 12px rgba(0, 0, 0, 0.5)",G.style.zIndex=String(i),G.style.minWidth="180px",G.style.padding="6px 0",G.style.fontFamily='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',G.style.fontSize="14px",G.style.color="#e0e0e0",document.body.appendChild(G),G},S=(G,te)=>{const X=document.createElement("div");return X.textContent=G,X.style.padding="8px 16px",X.style.cursor="pointer",X.style.transition="background-color 0.15s",X.style.userSelect="none",X.addEventListener("mouseenter",()=>{X.style.backgroundColor="#2a2a3e"}),X.addEventListener("mouseleave",()=>{X.style.backgroundColor="transparent"}),X.addEventListener("click",()=>{te(),v()}),X},y=()=>{const G=document.createElement("div");return G.style.height="1px",G.style.backgroundColor="#333",G.style.margin="6px 0",G},b=(G,te,X)=>{G.innerHTML="",G.appendChild(S("Edit annotation...",()=>A(te,X))),G.appendChild(S("Delete annotation",()=>P(te))),G.appendChild(y()),G.appendChild(S("Add vertical line here",()=>f())),G.appendChild(S("Add horizontal line here",()=>x())),G.appendChild(S("Add text note here",()=>N()))},w=G=>{G.innerHTML="",G.appendChild(S("Add vertical line here",()=>f())),G.appendChild(S("Add horizontal line here",()=>x())),G.appendChild(S("Add text note here",()=>N()))};let d=null;const g=G=>{if(!F)return;d=t.hitTest(G);const te=o.getBoundingClientRect(),X=G.clientX-te.left,Q=G.clientY-te.top,ne=u.hitTest(X,Q);ne?b(F,ne.annotationIndex,ne.annotation):w(F),F.style.display="block",F.style.left=`${G.clientX}px`,F.style.top=`${G.clientY}px`,requestAnimationFrame(()=>{if(!F||F.style.display!=="block")return;const H=F.getBoundingClientRect();let O=G.clientX,se=G.clientY;H.right>window.innerWidth&&(O=Math.max(0,G.clientX-H.width)),H.bottom>window.innerHeight&&(se=Math.max(0,G.clientY-H.height)),(O!==G.clientX||se!==G.clientY)&&(F.style.left=`${O}px`,F.style.top=`${se}px`)})},v=()=>{F&&(F.style.display="none",d=null)},M=()=>{var ne,H;const G=t.options;let te=(ne=G.xAxis)==null?void 0:ne.min,X=(H=G.xAxis)==null?void 0:H.max;if(te===void 0||X===void 0){const O=G.series??[];let se=Number.POSITIVE_INFINITY,ce=Number.NEGATIVE_INFINITY;for(const le of O)if(le.type!=="pie")if(le.type==="candlestick"){const me=le.data;for(const ge of me){const we=Xd(ge);we<se&&(se=we),we>ce&&(ce=we)}}else{const me=le.data;for(const ge of me){const we=$d(ge);we<se&&(se=we),we>ce&&(ce=we)}}te===void 0&&(te=Number.isFinite(se)?se:0),X===void 0&&(X=Number.isFinite(ce)?ce:100)}const Q=t.getZoomRange();if(Q){const O=X-te,se=te+Q.start/100*O,ce=te+Q.end/100*O;return{min:se,max:ce}}return{min:te,max:X}},I=()=>{var Q,ne;const G=t.options;let te=(Q=G.yAxis)==null?void 0:Q.min,X=(ne=G.yAxis)==null?void 0:ne.max;if(te===void 0||X===void 0){const H=G.series??[];let O=Number.POSITIVE_INFINITY,se=Number.NEGATIVE_INFINITY;for(const ce of H)if(ce.type!=="pie")if(ce.type==="candlestick"){const le=ce.data;for(const me of le){const ge=Jr(me)?me[3]:me.low,we=Jr(me)?me[4]:me.high;ge<O&&(O=ge),we>se&&(se=we)}}else{const le=ce.data;for(const me of le){const ge=Wd(me);ge<O&&(O=ge),ge>se&&(se=ge)}}te===void 0&&(te=Number.isFinite(O)?O:0),X===void 0&&(X=Number.isFinite(se)?se:100)}return{min:te,max:X}},T=G=>{const te=o.getBoundingClientRect(),X=t.options.grid??Et,Q=te.width-(X.left??Et.left)-(X.right??Et.right),ne=M(),H=Q>0?G/Q:0;return ne.min+H*(ne.max-ne.min)},E=(G,te)=>{const X=o.getBoundingClientRect(),Q=t.options.grid??Et,ne=X.width-(Q.left??Et.left)-(Q.right??Et.right),H=X.height-(Q.top??Et.top)-(Q.bottom??Et.bottom),O=ne>0?G/ne:0,se=H>0?te/H:0;return{x:O,y:se}},f=()=>{if(!d)return;const{match:G,isInGrid:te,gridX:X}=d;let Q;if(G)Q=G.value[0];else if(te)Q=T(X);else return;p.showCreate("lineX",{type:"lineX",x:Q,layer:"aboveSeries",style:{color:"#ffa500",lineWidth:2}},ne=>{const O=[...l(),ne];C(O),m(O)},()=>{})},x=()=>{if(!d)return;const{match:G,isInGrid:te,gridY:X}=d;let Q;if(G)Q=G.value[1];else if(te){const ne=o.getBoundingClientRect(),H=t.options.grid??Et,O=ne.height-(H.top??Et.top)-(H.bottom??Et.bottom),se=I(),ce=O>0?1-X/O:.5;Q=se.min+ce*(se.max-se.min)}else return;p.showCreate("lineY",{type:"lineY",y:Q,layer:"aboveSeries",style:{color:"#ffa500",lineWidth:2}},ne=>{const O=[...l(),ne];C(O),m(O)},()=>{})},N=()=>{if(!d)return;const{match:G,isInGrid:te,gridX:X,gridY:Q}=d;let ne,H,O;if(G)ne="data",H=G.value[0],O=G.value[1];else if(te){const se=E(X,Q);ne="plot",H=se.x,O=se.y}else return;p.showCreate("text",{type:"text",position:{space:ne,x:H,y:O},text:"Note",layer:"aboveSeries",style:{color:"#00d4ff"}},se=>{const le=[...l(),se];C(le),m(le)},()=>{})},A=(G,te)=>{p.showEdit(te,X=>{const ne=l().map((H,O)=>O===G?{...H,...X}:H);C(ne),m(ne)},()=>{})},P=G=>{const X=l().filter((Q,ne)=>ne!==G);C(X),m(X)},L=G=>{if(c||G.button===2)return;const te=o.getBoundingClientRect(),X=G.clientX-te.left,Q=G.clientY-te.top,ne=u.hitTest(X,Q);ne&&(G.preventDefault(),h.startDrag(ne.annotationIndex,ne.annotation,G.clientX,G.clientY))},B=G=>{c||!r||(G.preventDefault(),G.stopPropagation(),g(G))},V=G=>{c||F&&!F.contains(G.target)&&v()},_=G=>{c||G.key==="Escape"&&F&&F.style.display==="block"&&v()},re=()=>{c||F&&F.style.display==="block"&&v()},Y=G=>{const te=l(),X={type:"lineX",x:G,layer:"aboveSeries",style:{color:"#ffa500",lineWidth:2,opacity:.9}},Q=[...te,X];C(Q),m(Q)},W=(G,te,X,Q="data")=>{const ne=l(),H={type:"text",position:{space:Q,x:G,y:te},text:X,layer:"aboveSeries",style:{color:"#00d4ff",opacity:1}},O=[...ne,H];C(O),m(O)},Z=()=>{if(a<=0)return!1;a--;const G=s[a];return G?(C(G.annotations),!0):!1},oe=()=>{if(a>=s.length-1)return!1;a++;const G=s[a];return G?(C(G.annotations),!0):!1},ee=()=>{const G=l();return JSON.stringify(G,null,2)},q=()=>l(),de=()=>{c||(c=!0,o.removeEventListener("pointerdown",L),o.removeEventListener("contextmenu",B),document.removeEventListener("click",V),document.removeEventListener("keydown",_),window.removeEventListener("scroll",re,!0),window.removeEventListener("resize",re),F==null||F.remove(),F=null,u.dispose(),h.dispose(),p.dispose(),s=[])};return r&&(F=R(),o.addEventListener("contextmenu",B),document.addEventListener("click",V),document.addEventListener("keydown",_),window.addEventListener("scroll",re,!0),window.addEventListener("resize",re)),o.addEventListener("pointerdown",L),{addVerticalLine:Y,addTextNote:W,undo:Z,redo:oe,exportJSON:ee,getAnnotations:q,dispose:de}}const Qr=120,Hd=1e3/60,qd=1.5,gn=new Map;function sr(){const e=Symbol("RenderScheduler"),t={id:e,running:!1};return gn.set(e,{rafId:null,callback:null,lastFrameTime:0,dirty:!1,frameHandler:null,frameTimestamps:new Float64Array(Qr),frameTimestampIndex:0,frameTimestampCount:0,totalFrames:0,totalDroppedFrames:0,consecutiveDroppedFrames:0,lastDropTimestamp:0,startTime:performance.now()}),t}function co(e,t){if(!t)throw new Error("Render callback is required");const n=gn.get(e.id);if(!n)throw new Error("Invalid scheduler state. Use createRenderScheduler() to create a new state.");if(e.running)throw new Error("RenderScheduler is already running. Call stopRenderScheduler() before starting again.");n.callback=t,n.lastFrameTime=performance.now(),n.dirty=!0;const i=e.id,r=o=>{const s=gn.get(i);if(!s||!s.callback)return;s.rafId=null;const a=performance.now();s.frameTimestamps[s.frameTimestampIndex]=a,s.frameTimestampIndex=(s.frameTimestampIndex+1)%Qr,s.frameTimestampCount<Qr&&s.frameTimestampCount++,s.totalFrames++;let c=o-s.lastFrameTime;const u=100;if(c>u&&(c=u),s.lastFrameTime>0&&c>Hd*qd?(s.totalDroppedFrames++,s.consecutiveDroppedFrames++,s.lastDropTimestamp=a):s.lastFrameTime>0&&(s.consecutiveDroppedFrames=0),s.lastFrameTime=o,s.dirty){s.dirty=!1,s.callback(c);const p=gn.get(i);p&&p.callback&&p.dirty&&(p.rafId=requestAnimationFrame(r))}};return n.frameHandler=r,n.rafId=requestAnimationFrame(r),{id:e.id,running:!0}}function va(e){const t=gn.get(e.id);if(!t)throw new Error("Invalid scheduler state. Use createRenderScheduler() to create a new state.");return t.callback=null,t.frameHandler=null,t.rafId!==null&&(cancelAnimationFrame(t.rafId),t.rafId=null),{id:e.id,running:!1}}function wa(e){const t=gn.get(e.id);if(!t)throw new Error("Invalid scheduler state. Use createRenderScheduler() to create a new state.");t.dirty=!0,t.callback!==null&&t.rafId===null&&(t.lastFrameTime=performance.now(),t.frameHandler&&(t.rafId=requestAnimationFrame(t.frameHandler)))}function Ca(e){const t=gn.get(e.id);return t&&(t.rafId!==null&&(cancelAnimationFrame(t.rafId),t.rafId=null),t.callback=null,t.frameHandler=null,gn.delete(e.id)),sr()}function Zd(e){const t=sr();return co(t,e)}class jd{get running(){return this._state.running}constructor(){this._state=sr()}start(t){this._state=co(this._state,t)}stop(){this._state=va(this._state)}requestRender(){wa(this._state)}destroy(){this._state=Ca(this._state)}}const Kd="1.0.0",Jd=Ud;exports.ChartGPU=Jd;exports.GPUContext=nr;exports.OptionResolver=Cd;exports.RenderScheduler=jd;exports.candlestickDefaults=Dt;exports.clearScreen=qs;exports.connectCharts=_d;exports.createAnnotationAuthoring=Yd;exports.createCategoryScale=xf;exports.createChart=xa;exports.createGPUContext=eo;exports.createGPUContextAsync=Ba;exports.createLinearScale=an;exports.createRenderScheduler=sr;exports.createRenderSchedulerAsync=Zd;exports.darkTheme=ya;exports.defaultOptions=bt;exports.destroyGPUContext=Zs;exports.destroyRenderScheduler=Ca;exports.getCanvasTexture=no;exports.getTheme=Xi;exports.initializeGPUContext=to;exports.lightTheme=ga;exports.requestRender=wa;exports.resolveOptions=ao;exports.startRenderScheduler=co;exports.stopRenderScheduler=va;exports.version=Kd;
|
|
1270
|
+
//# sourceMappingURL=index.cjs.map
|