From 4a9983bdef455be0d29d3cf42ee88661c21e7446 Mon Sep 17 00:00:00 2001 From: Othman Beqqal Date: Tue, 5 May 2026 13:28:16 +0200 Subject: [PATCH 1/3] Ajout de connect_chart --- .DS_Store | Bin 0 -> 8196 bytes .Rbuildignore | 2 ++ .gitignore | 1 + R/chartgpu.R | 9 ++++-- examples/chartgpu.R | 1 + examples/chartgpu_connect_charts.R | 23 +++++++++++++++ inst/.DS_Store | Bin 0 -> 6148 bytes inst/htmlwidgets/chartgpu.js | 2 +- srcjs/widgets/chartgpu.js | 43 ++++++++++++++--------------- 9 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 .DS_Store create mode 100644 examples/chartgpu_connect_charts.R create mode 100644 inst/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7d46b097a527ffcfb7bce23e5f2fa474dead445e GIT binary patch literal 8196 zcmeHM&2Jk;6n~SrWZk66x{XVyK(gvfrKTqI1F1r&j*|$?M`PJhNob2%+Y@J#&5pIZ zj$5KgK7+)8BL|NB0i1f|!jUTnF8l)=IB|vF%&gsAe;h%Px+BfJw=?fIZ{|1qW_D~M zVx?~D9ikN?GLWS-=TS^ZvR&q}G!xcjAsO&Qx5y)ldSyp6$E=fzgn@*Cgn@*Cgn@*C z^S}VkY?+KH=e}-D%7lT0fmf0Nxj*EPr7VWBucg{LP^c>aWD3Abg(>gA<&-(GqLxXSFpw}X&VanT z8`Q$BJwT4!-y4o-piPET3Ayl(O3;YrX_L07MjKS6GF4~?!HC^=)9e~OzZ3d@(dam~AFQqY#%5+y7han)=8SpcY3)Gt zYJnAW{gUN9mQOoEIE{gBH6Gc#S2ve8gd144%RL3KTO1}&KC|7H=#@m*ZTSjY(+x)2 zNY~Ak)6;vm@2%$U++RCe&7I!Ay|$XWd*|J=v$T=Tzx`gde&igx;%kf@iG`aOUDD6P z@*8NwdE3pCa6atU!F>KO&B2V)7v~o)EiRdv%U3eXnQS(D_4SoEu3dYxZeD3v&7-y_ zN4g;#;gy^&-?f{x-9FJI_0?S$ zm!3a$tOj?s-I53baV#xmZ_)F86FIEQ14Xv1z*9uEZP#gD@#gKp9~eS{bNfO_;TeNR8q3;KnAr$6a$mSR`gb#{~8W$&{G z>_b*&pR*=AU^Y9{_?f{XzZLcu3g$x@F7ipua~~8^O%N#v(Uvr9%9NNQkH5f1N&6VP1iT5se^Zct;Tn2v&iOgi{?J zq}H7p=22V*+kr(*Izrh7`W8?^Js0Q@;V(wV%H#$R?O|c0hbcJ4UKGcu8lTgQSTl^!wgc;9k! zj9F&zMsjKlXI=nGfOpBf3t!_sfVEf;i(@^=wL6)FmCVJkOJi8gNNXY*tj5qFIZ5Y% zfmuC>6?y;Pn*RI$c^GOkhJ=BHf&YjBmfEas;`CBqAd`Gx|EC=Cm&h{7FO|NQ>LUk* uG?De{Iu1Gf!w`BdY%7McuO(WL{`VgOEfy8ux>%SOHdGaTKsCm{VJvTjo1u1z3S!Qh?S6 ziB9NQEDY+U0~>t=K&)U|8^-jqNE~U=vsf6!9yDR7h=wZc5knX{=B2IkEEWb09fTek zuVY6R_Jktz=$Mzf9E4|(TULM-_^tq*{m|;P{~ygi|LY=dSOHexe<~mre{G?!@w_>cNt+;`%4fB!$M9*Sj5Ho1}BA{j9h86f#1wH_v(p@nC literal 0 HcmV?d00001 diff --git a/inst/htmlwidgets/chartgpu.js b/inst/htmlwidgets/chartgpu.js index e5131ef..9a4feab 100644 --- a/inst/htmlwidgets/chartgpu.js +++ b/inst/htmlwidgets/chartgpu.js @@ -1 +1 @@ -(()=>{"use strict";HTMLWidgets;const e=Symbol("GPUContext.ownsDevice"),t=t=>t[e]??!0;function n(e){if(!e.canvas)throw new Error("GPUContext: Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.canvasContext)throw new Error("GPUContext: not initialized. Call initializeGPUContext() first.");return e.canvasContext.getCurrentTexture()}class i{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=function(t,n){const i=(null==n?void 0:n.devicePixelRatio)??(typeof window<"u"?window.devicePixelRatio:1),r=Number.isFinite(i)&&i>0?i:1,o=(null==n?void 0:n.alphaMode)??"opaque",a=(null==n?void 0:n.powerPreference)??"high-performance",s=!(null==n||!n.device||null==n||!n.adapter),l=!s;return{adapter:s?n.adapter:null,device:s?n.device:null,initialized:!1,canvas:t||null,canvasContext:null,preferredFormat:null,devicePixelRatio:r,alphaMode:o,powerPreference:a,[e]:l}}(t,n)}async initialize(){this._state=await async function(n){var i,r,o;if(n.initialized)throw new Error("GPUContext: already initialized. Call destroyGPUContext() before reinitializing.");const a=Number.isFinite(n.devicePixelRatio)&&n.devicePixelRatio>0?n.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 s=null,l=null,u=t(n);try{if(n.adapter&&n.device){if(l=n.adapter,s=n.device,u=!1,"function"!=typeof(null==(i=navigator.gpu)?void 0:i.getPreferredCanvasFormat))throw new Error("GPUContext: Shared device requires navigator.gpu.getPreferredCanvasFormat() for canvas format selection, but it is not available in this environment. Use a browser with full WebGPU support.");const e=navigator.gpu.getPreferredCanvasFormat();if("bgra8unorm"!==e&&"rgba8unorm"!==e)throw new Error(`GPUContext: Shared device preferred canvas format is not supported by ChartGPU. Received navigator.gpu.getPreferredCanvasFormat()="${e}". Supported formats: "bgra8unorm", "rgba8unorm".`);const t=s.limits.maxBufferSize;if(t<33554432)throw new Error(`GPUContext: Injected device.limits.maxBufferSize is insufficient. Required >= 33554432 bytes, actual=${t} bytes.`);const r=s.limits.maxStorageBufferBindingSize;if(r<33554432)throw new Error(`GPUContext: Injected device.limits.maxStorageBufferBindingSize is insufficient. Required >= 33554432 bytes, actual=${r} bytes.`)}else{const e=await navigator.gpu.requestAdapter({powerPreference:n.powerPreference});if(!e)throw new Error("GPUContext: Failed to request WebGPU adapter. No compatible adapter found. This may occur if no GPU is available or WebGPU is disabled.");const t=await e.requestDevice();if(!t)throw new Error("GPUContext: Failed to request WebGPU device from adapter.");l=e,s=t,u=!0,s.addEventListener("uncapturederror",e=>{console.error("WebGPU uncaptured error:",e.error)})}let t=null,c=null;if(n.canvas){const e=n.canvas.getContext("webgpu");if(!e){if(u&&s)try{s.destroy()}catch(e){console.warn("Error destroying device during canvas setup failure:",e)}throw new Error("GPUContext: Failed to get WebGPU context from canvas.")}const{width:i,height:l}=function(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}}(n.canvas),d=a,f=Math.floor(i*d),m=Math.floor(l*d),p=s.limits.maxTextureDimension2D;if(!u&&(f>p||m>p)){const e=Math.max(f,m);throw new Error(`GPUContext: Injected device.limits.maxTextureDimension2D is insufficient. Required >= ${e} (for ${f}x${m} at devicePixelRatio=${d}), actual=${p}.`)}const h=Math.max(1,Math.min(f,p)),g=Math.max(1,Math.min(m,p));n.canvas.width=h,n.canvas.height=g,c=(null==(o=(r=navigator.gpu).getPreferredCanvasFormat)?void 0:o.call(r))||"bgra8unorm",e.configure({device:s,format:c,alphaMode:n.alphaMode}),t=e}return{adapter:l,device:s,initialized:!0,canvas:n.canvas,canvasContext:t,preferredFormat:c,devicePixelRatio:a,alphaMode:n.alphaMode,powerPreference:n.powerPreference,[e]:u}}catch(e){if(u&&s)try{s.destroy()}catch(e){console.warn("Error destroying device during initialization failure:",e)}throw e instanceof Error?e:new Error(`Failed to initialize GPUContext: ${String(e)}`)}}(this._state)}static async create(e,t){const n=new i(e,t);return await n.initialize(),n}getCanvasTexture(){return n(this._state)}clearScreen(e,t,i,r){!function(e,t,i,r,o){if(t<0||t>1||i<0||i>1||r<0||r>1||o<0||o>1)throw new Error("GPUContext: Color components must be in the range [0.0, 1.0]");if(!e.canvas)throw new Error("GPUContext: Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.device||!e.canvasContext)throw new Error("GPUContext: not initialized. Call initializeGPUContext() first.");const a=n(e),s=e.device.createCommandEncoder();s.beginRenderPass({colorAttachments:[{view:a.createView(),clearValue:{r:t,g:i,b:r,a:o},loadOp:"clear",storeOp:"store"}]}).end(),e.device.queue.submit([s.finish()])}(this._state,e,t,i,r)}destroy(){this._state=function(n){if(n.canvasContext)try{n.canvasContext.unconfigure()}catch(e){console.warn("Error unconfiguring GPU canvas context:",e)}if(!1!==t(n)&&n.device)try{n.device.destroy()}catch(e){console.warn("Error destroying GPU device:",e)}return{adapter:null,device:null,initialized:!1,canvas:n.canvas,canvasContext:null,preferredFormat:null,devicePixelRatio:n.devicePixelRatio,alphaMode:n.alphaMode,powerPreference:n.powerPreference,[e]:!1}}(this._state)}}function r(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"x"in e&&"y"in e&&"object"==typeof e.x&&"object"==typeof e.y&&"length"in e.x&&"length"in e.y}function o(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function a(e){return Array.isArray(e)}function s(e){if(r(e))return Math.min(e.x.length,e.y.length);if(o(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 l(e,t){if(r(e))return e.x[t];if(o(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return e[2*t]}const n=e[t];return null==n||"object"!=typeof n?NaN:a(n)?n[0]:n.x}function u(e,t){if(r(e))return e.y[t];if(o(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return e[2*t+1]}const n=e[t];return null==n||"object"!=typeof n?NaN:a(n)?n[1]:n.y}function c(e,t){var n;if(r(e))return null==(n=e.size)?void 0:n[t];if(o(e))return;const i=e[t];return null!=i&&"object"==typeof i?a(i)?i[2]:i.size:void 0}function d(e,t,n,i,l,u){const c=s(n)-i,d=Math.min(l,c);if(d<=0)return;const f=t+2*d;if(f>e.length)throw new Error(`packXYInto: output buffer too small (need ${f} floats, have ${e.length})`);if(r(n))for(let r=0;rn&&(n=r),sa&&(a=s))}}else if(o(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");const r=e,o=Math.floor(r.length/2);for(let e=0;en&&(n=o),sa&&(a=s))}}else{const r=e.length;for(let o=0;on&&(n=r),sa&&(a=s))}}return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(a)?(t===n&&(n=t+1),i===a&&(a=i+1),{xMin:t,xMax:n,yMin:i,yMax:a}):null}function m(e){return!!Array.isArray(e)&&e.includes(null)}function p(e){if(Array.isArray(e))return e.filter(e=>{if(null==e||"object"!=typeof e)return!1;const t=a(e)?e[0]:e.x,n=a(e)?e[1]:e.y;return Number.isFinite(t)&&Number.isFinite(n)});const t=s(e),n=[];for(let i=0;i>>0;for(let e=0;e>>0;return n>>>0}function v(e){return b(2166136261,new Uint32Array(e.buffer,e.byteOffset,e.byteLength/4))}function y(e){return Array.isArray(e)}function x(e,t){const n=Math.floor(t);if(e instanceof Float32Array){const t=e.length>>>1;if(n<=0||0===t)return new Float32Array(0);if(t<=n)return e;const i=function(e,t){const n=e.length>>>1,i=n-1;if(t<=0||0===n)return new Int32Array(0);if(1===t)return new Int32Array([0]);if(2===t)return n>=2?new Int32Array([0,i]):new Int32Array([0]);if(n<=t){const e=new Int32Array(n);for(let t=0;t=c&&(t=Math.min(t,i-1),c=Math.min(t+1,i));const d=Math.floor(o*(n+1))+1,f=Math.min(Math.floor(o*(n+2))+1,i);let m=l,p=u;if(d0&&(m=t/i,p=n/i)}const h=e[2*a+0],g=e[2*a+1];let b=-1,v=t;for(let n=t;nb&&(b=r,v=n)}r[s++]=v,a=v}return r}(e,n),r=new Float32Array(2*i.length);for(let t=0;t=2?new Int32Array([0,i]):new Int32Array([0]);if(n<=t){const e=new Int32Array(n);for(let t=0;t=l&&(t=Math.min(t,i-1),l=Math.min(t+1,i));const d=Math.floor(o*(n+1))+1,f=Math.min(Math.floor(o*(n+2))+1,i);let m=u,p=c;if(d0&&(m=t/i,p=n/i)}const h=e[a],g=y(h)?h[0]:h.x,b=y(h)?h[1]:h.y;let v=-1,x=t;for(let n=t;nv&&(v=o,x=n)}r[s++]=x,a=x}return r}(e,n),o=new Array(r.length);for(let t=0;t=2){const t=l(e,0),n=u(e,0),r=c(e,0),o=l(e,i-1),a=u(e,i-1),s=c(e,i-1);return[void 0!==r?[t,n,r]:[t,n],void 0!==s?[o,a,s]:[o,a]]}{const t=l(e,0),n=u(e,0),i=c(e,0);return void 0!==i?[[t,n,i]]:[[t,n]]}}const o=i-1,a=new Array(r);{const t=l(e,0),n=u(e,0),i=c(e,0);a[0]=void 0!==i?[t,n,i]:[t,n];const s=l(e,o),d=u(e,o),f=c(e,o);a[r-1]=void 0!==f?[s,d,f]:[s,d]}const d=(i-2)/(r-2);for(let t=0;t=r&&(i=Math.min(i,o-1),r=Math.min(i+1,o));let s=null;if("average"===n){let t=0,n=0,o=0,a=0,d=0;for(let s=i;s0){const e=t/a,i=n/a;s=d>0?[e,i,o/d]:[e,i]}}else{let t="max"===n?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,o=i;for(let a=i;at&&(t=i,o=a):i0)||r<=i)return e;switch(t){case"lttb":return e instanceof Float32Array?x(e,i):function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&ArrayBuffer.isView(e)}(e)||function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"x"in e&&"y"in e&&"object"==typeof e.x&&"object"==typeof e.y&&"length"in e.x&&"length"in e.y}(e)?x(M(e),i):x(e.filter(e=>null!==e),i);case"average":return F(e,i,"average");case"max":return F(e,i,"max");case"min":return F(e,i,"min");default:return e}}function C(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],2===n)return r;const o=function(e){return Array.isArray(e)}(e[0]),a=(i-2)/(n-2);if(o){const t=e;for(let e=0;e=o&&(n=Math.min(n,i-2),o=Math.min(n+1,i-1));const s=t[n],l=t[o-1],u=s[0],c=s[1],d=l[2];let f=-1/0,m=1/0;for(let e=n;ef&&(f=r),i=o&&(n=Math.min(n,i-2),o=Math.min(n+1,i-1));const s=t[n],l=t[o-1],u=s.timestamp,c=s.open,d=l.close;let f=-1/0,m=1/0;for(let e=n;ef&&(f=i),r>>1;l(e,r)>>1;l(e,r)<=t?n=r+1:i=r}return n}function T(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"x"in e&&"y"in e&&"object"==typeof e.x&&"object"==typeof e.y&&"length"in e.x&&"length"in e.y}function D(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function U(e,t,n){const i=s(e);if(0===i||!Number.isFinite(t)||!Number.isFinite(n))return e;if(R(e)){const r=E(e,t),o=B(e,n);return r<=0&&o>=i?e:function(e,t,n){const i=s(e),r=Math.max(0,Math.min(t,i)),o=Math.max(r,Math.min(n,i));if(0===r&&o===i)return e;if(o<=r){if(T(e))return{x:[],y:[],...e.size?{size:[]}:{}};if(D(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData");return new(0,e.constructor)(0)}return[]}if(T(e)){const t={x: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),y: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)};if(e.size){const n=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);t.size=n}return t}if(D(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData");return e.subarray(2*r,2*o)}return e.slice(r,o)}(e,r,o)}const r=[];for(let o=0;o=t&&i<=n){const t=u(e,o);r.push([i,t])}}return r}function k(e,t,n){const i=s(e);if(0===i)return{start:0,end:0};if(!Number.isFinite(t)||!Number.isFinite(n))return{start:0,end:i};if(!R(e))return{start:0,end:i};const r=E(e,t),o=B(e,n),a=S(r,0,i),l=S(o,0,i);return l<=a?{start:a,end:a}:{start:a,end:l}}function G(e,t,n){const i=e.length;if(0===i||!Number.isFinite(t)||!Number.isFinite(n))return e;const r=function(e){const t=P.get(e);if(void 0!==t)return t;let n=Number.NEGATIVE_INFINITY;for(let t=0;t0&&A(e[0]);if(r){const r=o?function(e,t){let n=0,i=e.length;for(;n>>1;e[r][0]>>1;e[r].timestamp>>1;e[r][0]<=t?n=r+1:i=r}return n}(e,n):function(e,t){let n=0,i=e.length;for(;n>>1;e[r].timestamp<=t?n=r+1:i=r}return n}(e,n);return r<=0&&a>=i?e:a<=r?[]:e.slice(r,a)}const a=[];for(let r=0;r=t&&o<=n&&a.push(i)}return a}const z=e=>Math.min(1,Math.max(0,e)),V=e=>Math.min(255,Math.max(0,e)),L=e=>{const t=Number.parseInt(e,16);return Number.isFinite(t)?t:0},W=e=>{const t=Number.parseInt(e,16);return Number.isFinite(t)?t:0},O=e=>{const t=e.trim();if(0===t.length)return null;if(t.endsWith("%")){const e=Number.parseFloat(t.slice(0,-1));return Number.isFinite(e)?V(e/100*255):null}const n=Number.parseFloat(t);return Number.isFinite(n)?V(n):null},_=e=>{if("string"!=typeof e)return null;const t=e.trim();if(0===t.length)return null;const n=(e=>{const t=e.trim();if(!t.startsWith("#"))return null;const n=t.slice(1);return 3===n.length?[17*L(n[0])/255,17*L(n[1])/255,17*L(n[2])/255,1]:4===n.length?[17*L(n[0])/255,17*L(n[1])/255,17*L(n[2])/255,17*L(n[3])/255]:6===n.length?[W(n.slice(0,2))/255,W(n.slice(2,4))/255,W(n.slice(4,6))/255,1]:8===n.length?[W(n.slice(0,2))/255,W(n.slice(2,4))/255,W(n.slice(4,6))/255,W(n.slice(6,8))/255]:null})(t);return n||((e=>{const t=e.trim(),n=/^(rgba?|RGBA?)\(\s*([^\)]*)\s*\)$/.exec(t);if(!n)return null;const i=n[1].toLowerCase(),r=n[2].split(",").map(e=>e.trim());if("rgb"===i){if(3!==r.length)return null;const e=O(r[0]),t=O(r[1]),n=O(r[2]);return null==e||null==t||null==n?null:[e/255,t/255,n/255,1]}if("rgba"===i){if(4!==r.length)return null;const e=O(r[0]),t=O(r[1]),n=O(r[2]),i=(e=>{const t=e.trim();if(0===t.length)return null;if(t.endsWith("%")){const e=Number.parseFloat(t.slice(0,-1));return Number.isFinite(e)?z(e/100):null}const n=Number.parseFloat(t);return Number.isFinite(n)?z(n):null})(r[3]);return null==e||null==t||null==n||null==i?null:[e/255,t/255,n/255,i]}return null})(t)||null)},Y=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0,X=e=>{throw new Error(`RenderCoordinator: unreachable value: ${String(e)}`)},$=e=>Math.min(1,Math.max(0,e)),H=(e,t)=>(e+1)/2*t,q=(e,t)=>(1-e)/2*t,j=864e5,Z=30*j,J=365*j,K=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Q=(e,t)=>{if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"!=typeof e)return null;const n=e.trim();if(0===n.length)return null;if(n.endsWith("%")){const e=Number.parseFloat(n.slice(0,-1));return Number.isFinite(e)?e/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},ee=(e,t)=>{if(null==e)return{inner:0,outer:.7*t};if((e=>Array.isArray(e))(e)){const n=Q(e[0],t),i=Q(e[1],t),r=Math.max(0,Number.isFinite(n)?n:0),o=Math.max(r,Number.isFinite(i)?i:.7*t);return{inner:r,outer:Math.min(t,o)}}const n=Q(e,t),i=Math.max(0,Number.isFinite(n)?n:.7*t);return{inner:0,outer:Math.min(t,i)}},te=e=>String(Math.trunc(e)).padStart(2,"0"),ne=(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(),a=n.getHours(),s=n.getMinutes();return t{if("name"===i)return t.name??"";const r=t[i];return null==r?"":function(e,t){if(!Number.isFinite(e))return"";if(null==t)return String(e);const n=Math.min(20,Math.max(0,Math.floor(t)));return e.toFixed(n)}(r,n)})}function pe(e){switch(e){case"center":return"middle";case"end":return"end";default:return"start"}}function he(e,t){let n=0,i=s(e);for(;n>>1;l(e,r)=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom}const be=e=>Math.min(1,Math.max(0,e)),ve=e=>{if("string"!=typeof e)return"";const t=e.trim();return t.length>0?t:""},ye=e=>Array.isArray(e),xe=(e,t)=>{const n=(e=>{if(ye(e)){const t=e[2];return"number"==typeof t&&Number.isFinite(t)?t:null}const t=e.size;return"number"==typeof t&&Number.isFinite(t)?t:null})(t);if(null!=n)return Math.max(0,n);const i=e.symbolSize;if("number"==typeof i)return Number.isFinite(i)?Math.max(0,i):4;if("function"==typeof i){const e=((e,t)=>{try{const n=e(t);return"number"==typeof n&&Number.isFinite(n)?n:null}catch{return null}})(i,(e=>ye(e)?e:[e.x,e.y,e.size])(t));return null==e?4:Math.max(0,e)}return 4};function we(e,t){const n=function(e){const t=new Map,n=new Array(e.length),i=new Array(e.length);let r=0;for(let o=0;oe-t);let n=Number.POSITIVE_INFINITY;for(let e=1;e0&&i0?n:1}(e),o=function(e,t,n){if(Number.isFinite(n)&&n>0){const e=t.scale(0),i=t.scale(0+n),r=Math.abs(i-e);if(Number.isFinite(r)&&r>0)return r}const i=[];for(let n=0;ne-t);let r=Number.POSITIVE_INFINITY;for(let e=1;e0&&t0?r:0}(e,t,r),a=(e=>{let t,n,i;for(let r=0;r0?d/f:0;let p=0;const h=a.barWidth;if("number"==typeof h)p=Math.max(0,h),p=Math.min(p,m);else if("string"==typeof h){const e=(e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null})(h);p=null==e?0:m*be(e)}p>0||(p=m);const g=p*u;return{categoryStep:r,categoryWidthPx:o,barWidthPx:p,gapPx:g,clusterWidthPx:i*p+Math.max(0,i-1)*g,clusterSlots:n}}const Me=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;in&&(n=i))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t)0&&Number.isFinite(e)?Math.round(e/t):Number.isFinite(i)&&i>0&&Number.isFinite(n)?Math.round(n/i):Math.round(1e6*n)}function Ne(e,t,n,i,r,o=20){var a;if(!Number.isFinite(t)||!Number.isFinite(n))return null;const d=Number.isFinite(o)?Math.max(0,o):20,f=d*d,m=i.invert(t);if(!Number.isFinite(m))return null;let p=-1,h=-1,g=null,b=Number.POSITIVE_INFINITY;const v=[],y=[];for(let t=0;t0){const o=we(v,i);if(o.barWidthPx>0&&o.clusterWidthPx>=0){const d=function(e,t){let n=0;for(let i=0;in&&(n=o)}}return Math.max(0,n)}(v,r),{baselineDomain:f,baselinePx:m}=function(e,t,n){const i=t.invert(n),r=t.invert(0),o=Math.min(i,r),a=Math.max(i,r);let s;s=Number.isFinite(o)&&Number.isFinite(a)?o<=0&&0<=a?0:o>0?o:a<0?a:Me(e):Me(e);let l=t.scale(s);return Number.isFinite(l)||(s=Me(e),l=t.scale(s)),Number.isFinite(l)||(s=0,l=t.scale(0)),{baselineDomain:s,baselinePx:l}}(v,r,d),{clusterSlots:p,barWidthPx:h,gapPx:g,clusterWidthPx:b,categoryWidthPx:x,categoryStep:w}=o,M=new Map;let F=null;for(let e=0;e=0?(y=n.posSum,S=y+s,n.posSum=S):(y=n.negSum,S=y+s,n.negSum=S)}else y=f,S=s;const A=""!==C?r.scale(y):m,I=r.scale(S);if(!Number.isFinite(A)||!Number.isFinite(I))continue;const P={left:p,right:v,top:Math.min(A,I),bottom:Math.max(A,I)};ge(t,n,P)&&(null===F||P.topF.seriesIndex)&&(F={seriesIndex:a,dataIndex:e,top:P.top})}}if(F){const t=null==(a=e[F.seriesIndex])?void 0:a.data;if(t){const e=l(t,F.dataIndex),n=u(t,F.dataIndex),i=c(t,F.dataIndex),r=void 0!==i?[e,n,i]:[e,n];return{seriesIndex:F.seriesIndex,dataIndex:F.dataIndex,point:r,distance:0}}}}}const x=[],w=[];for(let t=0;tb)break;let N=f;if(M){const t=c(v,o),n=d+xe(M,void 0!==t?[e,s,t]:[e,s]);N=n*n}if(!(F>N)&&(F=0;o--){const e=l(v,o),s=u(v,o);if(!Number.isFinite(e)||!Number.isFinite(s))continue;const m=i.scale(e),y=r.scale(s);if(!Number.isFinite(m)||!Number.isFinite(y))continue;const x=m-t,w=y-n,F=x*x+w*w;if(x*x>b)break;let N=f;if(M){const t=c(v,o),n=d+xe(M,void 0!==t?[e,s,t]:[e,s]);N=n*n}if(!(F>N)&&(FN)&&(F0&&h>0&&m.horizontal.color!==m.vertical.color)e.gridRenderer.prepare(a,{lineCount:{horizontal:p,vertical:0},color:m.horizontal.color}),e.gridRenderer.prepare(a,{lineCount:{horizontal:0,vertical:h},color:m.vertical.color,append:!0});else{const t=p>0?m.horizontal.color:m.vertical.color;e.gridRenderer.prepare(a,{lineCount:{horizontal:p,vertical:h},color:t})}if(l&&(e.xAxisRenderer.prepare(i.xAxis,r,"x",a,i.theme.axisLineColor,i.theme.axisTickColor,s),e.yAxisRenderer.prepare(i.yAxis,o,"y",a,i.theme.axisLineColor,i.theme.axisTickColor,5)),u.hasPointer&&u.isInGrid){const t={showX:!0,showY:"sync"!==u.source,color:f(i.theme.axisLineColor,.6),lineWidth:1};e.crosshairRenderer.prepare(u.x,u.y,a,t),e.crosshairRenderer.setVisible(!0)}else e.crosshairRenderer.setVisible(!1);if("mouse"===u.source&&u.hasPointer&&u.isInGrid)if(c){const t=Ne(d,u.gridX,u.gridY,c.xScale,c.yScale);if(t){const{x:r,y:o}=(e=>(e=>Array.isArray(e))(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y})(t.point),s=c.xScale.scale(r),l=c.yScale.scale(o);if(Number.isFinite(s)&&Number.isFinite(l)){const r=a.left+s,o=a.top+l,u=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=S(Math.floor(r),0,Math.max(0,t)),u=S(Math.floor(a),0,Math.max(0,n)),c=S(Math.ceil(o),0,Math.max(0,t)),d=S(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(a),c={centerDeviceX:r*a.devicePixelRatio,centerDeviceY:o*a.devicePixelRatio,devicePixelRatio:a.devicePixelRatio,canvasWidth:a.canvasWidth,canvasHeight:a.canvasHeight,scissor:u},d=(null==(n=i.series[t.seriesIndex])?void 0:n.color)??"#888";e.highlightRenderer.prepare(c,d,4),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 Se(e,t,n){const i=_(e??n)??_(n)??[1,1,1,1],r=null==t?1:$(t);return[$(i[0]),$(i[1]),$(i[2]),$(i[3]*r)]}function Ae(e,t){const n=_(e)??[0,0,0,1],i=$(n[3]*$(t));return`rgba(${Math.round(255*$(n[0]))}, ${Math.round(255*$(n[1]))}, ${Math.round(255*$(n[2]))}, ${i})`}function Ie(e,t,n){return e.replace(/\{(x|y|value|name)\}/g,(e,i)=>{if("name"===i)return t.name??"";const r=t[i];return null==r?"":function(e,t){if(!Number.isFinite(e))return"";if(null==t)return String(e);const n=Math.min(20,Math.max(0,Math.floor(t)));return e.toFixed(n)}(r,n)})}function Pe(e){switch(e){case"center":return"middle";case"end":return"end";default:return"start"}}function Re(e){return Math.max(0,Math.min(1,e))}function Ee(e){return"area"===e.type||"line"===e.type&&!!e.areaStyle}const Be="// grid.wgsl\n// Minimal grid line shader:\n// - Vertex input: vec2 position in clip-space coordinates\n// - Uniforms: identity transform + solid RGBA color\n\nstruct VSUniforms {\n transform: mat4x4,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct FSUniforms {\n color: vec4,\n};\n\n@group(0) @binding(1) var fsUniforms: FSUniforms;\n\nstruct VSIn {\n @location(0) position: vec2,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn) -> VSOut {\n var out: VSOut;\n out.clipPosition = vsUniforms.transform * vec4(in.position, 0.0, 1.0);\n return out;\n}\n\n@fragment\nfn fsMain() -> @location(0) vec4 {\n return fsUniforms.color;\n}\n",Te=(e,t,n)=>{if(n&&n.device!==e)throw new Error("getStageModule(pipelineCache): cache.device must match the provided GPUDevice.");return"module"in t?{module:t.module,entryPoint:t.entryPoint||"",constants:t.constants}:{module:De(e,t.code,t.label,n),entryPoint:t.entryPoint||"",constants:t.constants}};function De(e,t,n,i){if("string"!=typeof t||0===t.length)throw new Error("createShaderModule(code): WGSL code must be a non-empty string.");if(i){if(i.device!==e)throw new Error("createShaderModule(pipelineCache): cache.device must match the provided GPUDevice.");return i.getOrCreateShaderModule(t,n)}return e.createShaderModule({code:t,label:n})}function Ue(e,t,n){if(n&&n.device!==e)throw new Error("createRenderPipeline(pipelineCache): cache.device must match the provided GPUDevice.");const i=Te(e,t.vertex,n),r=i.entryPoint||"vsMain";let o;if(t.fragment){const i=Te(e,t.fragment,n),r=i.entryPoint||"fsMain";let a;if(t.fragment.targets)a=[...t.fragment.targets];else{const e=t.fragment.formats;if(!e)throw new Error("createRenderPipeline(fragment): provide either `fragment.targets` or `fragment.formats` when a fragment stage is present.");if("string"==typeof e)a=[{format:e,blend:t.fragment.blend,writeMask:t.fragment.writeMask}];else{a=new Array(e.length);for(let n=0;n{if(!Number.isFinite(e)||e<0)throw new Error(`alignTo(value): value must be a finite non-negative number. Received: ${String(e)}`);if(!(e=>Number.isInteger(e)&&e>0&&!(e&e-1))(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)})(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:null==n?void 0:n.label,size:r,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST})}function ze(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(0!==i.size){if(3&i.offset||3&i.size)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 Ve=[1,1,1,.8],Le=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0;function We(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=(null==t?void 0:t.sampleCount)??1,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),l=Ge(e,64,{label:"axisRenderer/vsUniforms"}),u=Ge(e,16,{label:"axisRenderer/fsUniformsLine"}),c=Ge(e,16,{label:"axisRenderer/fsUniformsTick"}),d=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}},{binding:1,resource:{buffer:u}}]}),f=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}},{binding:1,resource:{buffer:c}}]}),m=Ue(e,{label:"axisRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:Be,label:"grid.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:Be,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:o}},a);let p=null,h=0;const g=()=>{if(n)throw new Error("AxisRenderer is disposed.")};return{prepare:(t,n,i,r,o,a,s)=>{if(g(),"x"!==i&&"y"!==i)throw new Error("AxisRenderer.prepare: orientation must be 'x' or 'y'.");const d=((e,t,n,i,r)=>{const{left:o,right:a,top:s,bottom:l,canvasWidth:u,canvasHeight:c}=i,d=Number.isFinite(i.devicePixelRatio)&&i.devicePixelRatio>0?i.devicePixelRatio:1;if(!(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))(i))throw new Error("AxisRenderer.prepare: gridArea dimensions must be finite numbers.");if(u<=0||c<=0)throw new Error("AxisRenderer.prepare: canvas dimensions must be positive.");if(o<0||a<0||s<0||l<0)throw new Error("AxisRenderer.prepare: gridArea margins must be non-negative.");const f=o*d/u*2-1,m=(u-a*d)/u*2-1,p=1-s*d/c*2,h=1-(c-l*d)/c*2,g=e.tickLength??6;if(!Number.isFinite(g)||g<0)throw new Error("AxisRenderer.prepare: tickLength must be a finite non-negative number.");const b=r??5,v=Math.max(1,Math.floor(b));if(!Number.isFinite(b)||v<1)throw new Error("AxisRenderer.prepare: tickCount must be a finite number >= 1.");const y=g*d,x=y/u*2,w=y/c*2,M=((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 e=n;n=i,i=e}return{min:n,max:i}})(Le(e.min)??("x"===n?t.invert(f):t.invert(h)),Le(e.max)??("x"===n?t.invert(m):t.invert(p))),F=M.min,N=M.max,C=new Float32Array(2*(1+v)*2);let S=0;if("x"===n){C[S++]=f,C[S++]=h,C[S++]=m,C[S++]=h;const e=h,n=e-w;for(let i=0;i{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})());const b=o??"rgba(255,255,255,0.8)",v=a??b,y=_(b)??Ve,x=_(v)??y,w=new ArrayBuffer(16);new Float32Array(w).set([y[0],y[1],y[2],y[3]]),ze(e,u,w);const M=new ArrayBuffer(16);new Float32Array(M).set([x[0],x[1],x[2],x[3]]),ze(e,c,M)},render:e=>{g(),0!==h&&p&&(e.setPipeline(m),e.setVertexBuffer(0,p),e.setBindGroup(0,d),e.draw(Math.min(2,h)),h>2&&(e.setBindGroup(0,f),e.draw(h-2,1,2,0)))},dispose:()=>{if(!n){n=!0;try{l.destroy()}catch{}try{u.destroy()}catch{}try{c.destroy()}catch{}if(p)try{p.destroy()}catch{}p=null,h=0}}}}const Oe=[1,1,1,.15];const _e='// area.wgsl\n// Minimal area-fill shader (triangle-strip):\n// - Vertex input: vec2 position in data coords\n// - Uniforms: clip-space transform + baseline value + solid RGBA color\n// - Topology: triangle-strip\n// - CPU duplicates vertices as p0,p0,p1,p1,... and we use vertex_index parity:\n// even index -> "top" vertex (original y)\n// odd index -> "baseline" vertex (uniform baseline)\n\nstruct VSUniforms {\n transform: mat4x4,\n baseline: f32,\n // Pad to 16-byte multiple (uniform buffer layout requirements).\n _pad0: vec3,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct FSUniforms {\n color: vec4,\n};\n\n@group(0) @binding(1) var fsUniforms: FSUniforms;\n\nstruct VSIn {\n @location(0) position: vec2,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n var out: VSOut;\n let useBaseline = (vertexIndex & 1u) == 1u;\n let y = select(in.position.y, vsUniforms.baseline, useBaseline);\n let pos = vec2(in.position.x, y);\n out.clipPosition = vsUniforms.transform * vec4(pos, 0.0, 1.0);\n return out;\n}\n\n@fragment\nfn fsMain() -> @location(0) vec4 {\n return fsUniforms.color;\n}\n\n',Ye=e=>Math.min(1,Math.max(0,e)),Xe=(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),a=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(a)?a:0}};function $e(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,c=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),d=Ge(e,96,{label:"areaRenderer/vsUniforms"}),m=Ge(e,16,{label:"areaRenderer/fsUniforms"}),p=new ArrayBuffer(96),h=new Float32Array(p),g=new Float32Array(4),b=e.createBindGroup({layout:c,entries:[{binding:0,resource:{buffer:d}},{binding:1,resource:{buffer:m}}]}),v=Ue(e,{label:"areaRenderer/pipeline",bindGroupLayouts:[c],vertex:{code:_e,label:"area.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:_e,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:o}},a);let y=null,x=0;const w=()=>{if(n)throw new Error("AreaRenderer is disposed.")};return{prepare:(t,n,i,r,o)=>{w();const a=(e=>{const t=s(e),n=new Float32Array(2*t*2);let i=0;for(let r=0;r0&&e.queue.writeBuffer(y,0,a.buffer,0,a.byteLength),x=a.length/2;const v=f(n),{xMin:M,xMax:F,yMin:N,yMax:C}=v??{xMin:0,xMax:1,yMin:0,yMax:1},{a:S,b:A}=Xe(i,M,F),{a:I,b:P}=Xe(r,N,C);((t,n,i,r,o)=>{((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})(h,t,n,i,r),h[16]=o,h[17]=0,h[18]=0,h[19]=0,h[20]=0,h[21]=0,h[22]=0,h[23]=0,ze(e,d,p)})(S,A,I,P,Number.isFinite(o??Number.NaN)?o:Number.isFinite(N)?N:0);const[R,E,B,T]=(e=>_(e)??[0,0,0,1])(t.areaStyle.color),D=Ye(t.areaStyle.opacity);g[0]=R,g[1]=E,g[2]=B,g[3]=Ye(T*D),ze(e,m,g)},render:e=>{w(),y&&!(x<4)&&(e.setPipeline(v),e.setBindGroup(0,b),e.setVertexBuffer(0,y),e.draw(x))},dispose:()=>{if(!n){if(n=!0,y)try{y.destroy()}catch{}y=null,x=0;try{d.destroy()}catch{}try{m.destroy()}catch{}}}}}const He='// line.wgsl — Screen-space quad expansion with SDF-based anti-aliasing.\n//\n// Each "instance" draws one line segment (point[i] → point[i+1]).\n// 6 vertices per instance (2 triangles = 1 quad per segment).\n//\n// The vertex shader:\n// 1. Reads endpoints from a storage buffer.\n// 2. Transforms both to clip space using the mat4x4 transform.\n// 3. Converts clip→screen (NDC * canvasSize * 0.5).\n// 4. Computes the perpendicular direction in screen space.\n// 5. Offsets vertices by ±(halfWidth + AA_PADDING) along the perpendicular.\n// 6. Converts back to clip space.\n// 7. Outputs `acrossDevice` varying for SDF-based AA.\n//\n// The fragment shader applies smoothstep AA on the distance-from-edge.\n\nconst AA_PADDING: f32 = 1.5;\n\nstruct VSUniforms {\n transform : mat4x4, // 64 bytes: data-coord → clip-space\n canvasSize : vec2, // 8 bytes: device pixels (width, height)\n devicePixelRatio: f32, // 4 bytes\n lineWidthCssPx : f32, // 4 bytes: line width in CSS pixels\n};\n// Total: 80 bytes (aligned to 16).\n\n@group(0) @binding(0) var vsUniforms : VSUniforms;\n\nstruct FSUniforms {\n color : vec4,\n};\n\n@group(0) @binding(1) var fsUniforms : FSUniforms;\n\n@group(0) @binding(2) var points : array>;\n\nstruct VSOut {\n @builtin(position) clipPosition : vec4,\n @location(0) acrossDevice : f32,\n @location(1) @interpolate(flat) widthDevice : f32,\n};\n\n// Returns UV for the 6 vertices of a quad (2 triangles):\n// uv.x: 0 → endpoint A, 1 → endpoint B\n// uv.y: 0 → +side, 1 → −side\nfn quadUv(vid : u32) -> vec2 {\n switch (vid) {\n case 0u: { return vec2(0.0, 0.0); }\n case 1u: { return vec2(1.0, 0.0); }\n case 2u: { return vec2(0.0, 1.0); }\n case 3u: { return vec2(0.0, 1.0); }\n case 4u: { return vec2(1.0, 0.0); }\n default: { return vec2(1.0, 1.0); }\n }\n}\n\n@vertex\nfn vsMain(\n @builtin(vertex_index) vid : u32,\n @builtin(instance_index) iid : u32,\n) -> VSOut {\n let uv = quadUv(vid);\n\n // Read segment endpoints in data coordinates.\n let pA_data = points[iid];\n let pB_data = points[iid + 1u];\n\n // ── Gap detection ──────────────────────────────────────────────\n // Null entries in the data array are packed as NaN by the CPU.\n // Collapse the quad to a degenerate point so the rasterizer discards it.\n // WGSL has no isnan(); use the IEEE 754 property that NaN != NaN.\n if (pA_data.x != pA_data.x || pA_data.y != pA_data.y ||\n pB_data.x != pB_data.x || pB_data.y != pB_data.y) {\n var out: VSOut;\n out.clipPosition = vec4(0.0, 0.0, 0.0, 0.0);\n out.acrossDevice = 0.0;\n out.widthDevice = 0.0;\n return out;\n }\n\n // Transform to clip space.\n let clipA = vsUniforms.transform * vec4(pA_data, 0.0, 1.0);\n let clipB = vsUniforms.transform * vec4(pB_data, 0.0, 1.0);\n\n // Convert clip → screen (device pixels). \n // screen = (ndc * 0.5 + 0.5) * canvasSize, but Y is flipped.\n let ndcA = clipA.xy / clipA.w;\n let ndcB = clipB.xy / clipB.w;\n let screenA = vec2(\n (ndcA.x * 0.5 + 0.5) * vsUniforms.canvasSize.x,\n (1.0 - (ndcA.y * 0.5 + 0.5)) * vsUniforms.canvasSize.y,\n );\n let screenB = vec2(\n (ndcB.x * 0.5 + 0.5) * vsUniforms.canvasSize.x,\n (1.0 - (ndcB.y * 0.5 + 0.5)) * vsUniforms.canvasSize.y,\n );\n\n // Segment direction and perpendicular in screen space.\n let delta = screenB - screenA;\n let segLen = length(delta);\n\n // Degenerate segment: collapse quad to a degenerate triangle.\n if (segLen < 1e-6) {\n var out : VSOut;\n out.clipPosition = clipA;\n out.acrossDevice = 0.0;\n out.widthDevice = 0.0;\n return out;\n }\n\n let dir = delta / segLen;\n // Perpendicular: rotate 90° CW → (dy, -dx).\n let perp = vec2(dir.y, -dir.x);\n\n // Compute line width in device pixels + AA padding.\n let dpr = max(vsUniforms.devicePixelRatio, 1e-6);\n let widthDevice = max(1.0, vsUniforms.lineWidthCssPx * dpr);\n let halfExtent = widthDevice * 0.5 + AA_PADDING;\n\n // Select endpoint: uv.x=0 → A, uv.x=1 → B.\n let baseScreen = mix(screenA, screenB, uv.x);\n\n // Offset perpendicular: uv.y selects +side (0) vs −side (1).\n let side = mix(1.0, -1.0, uv.y);\n let screenPos = baseScreen + perp * halfExtent * side;\n\n // acrossDevice: 0 at −side edge, widthDevice at +side edge.\n // Map from [−halfExtent, +halfExtent] to [0, widthDevice + 2*AA_PADDING].\n let totalExtent = 2.0 * halfExtent;\n let acrossDevice = (side * halfExtent + halfExtent) / totalExtent * totalExtent;\n // Simplified: acrossDevice = halfExtent * (1 + side) = halfExtent + halfExtent * side\n // But for the fragment shader we want [0, totalExtent]:\n // Let\'s define it properly:\n // At side=+1: screenPos is at +halfExtent from center → acrossDevice = totalExtent\n // At side=-1: screenPos is at -halfExtent from center → acrossDevice = 0\n let acrossDeviceVal = halfExtent * (1.0 + side);\n\n // Convert screen → clip.\n let clipX = (screenPos.x / vsUniforms.canvasSize.x) * 2.0 - 1.0;\n let clipY = 1.0 - (screenPos.y / vsUniforms.canvasSize.y) * 2.0;\n\n var out : VSOut;\n out.clipPosition = vec4(clipX, clipY, 0.0, 1.0);\n out.acrossDevice = acrossDeviceVal;\n out.widthDevice = widthDevice;\n return out;\n}\n\n@fragment\nfn fsMain(in : VSOut) -> @location(0) vec4 {\n let totalExtent = in.widthDevice + 2.0 * AA_PADDING;\n let edgeDist = min(in.acrossDevice, totalExtent - in.acrossDevice);\n\n // Smooth step from 0 to AA zone for anti-aliased edges.\n let aa = max(fwidth(in.acrossDevice), 1e-3) * 1.25;\n let edgeCoverage = smoothstep(0.0, aa, edgeDist);\n\n // Also fade out in the AA_PADDING region (beyond the nominal half-width).\n // The padding zone is [0, AA_PADDING] at each edge.\n // Distance from the nominal edge = edgeDist - AA_PADDING (negative means inside).\n // Actually, remap: the nominal line occupies [AA_PADDING, AA_PADDING + widthDevice].\n let nominalDist = min(in.acrossDevice - AA_PADDING, (AA_PADDING + in.widthDevice) - in.acrossDevice);\n let paddingCoverage = smoothstep(0.0, aa, nominalDist);\n\n // Combine: paddingCoverage handles the SDF fade, edgeCoverage handles the outer trim.\n // For thin lines (< 1 device px), paddingCoverage alone provides the desired fade.\n let coverage = min(edgeCoverage, paddingCoverage);\n\n var color = fsUniforms.color;\n color = vec4(color.rgb, color.a * coverage);\n return color;\n}\n',qe=e=>Math.min(1,Math.max(0,e)),je=(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),a=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(a)?a:0}};function Ze(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,l=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),u=Ge(e,80,{label:"lineRenderer/vsUniforms"}),c=Ge(e,16,{label:"lineRenderer/fsUniforms"}),d=new ArrayBuffer(80),m=new Float32Array(d),p=new Float32Array(4);let h=null;const g=Ue(e,{label:"lineRenderer/pipeline",bindGroupLayouts:[l],vertex:{code:He,label:"line.wgsl",buffers:[]},fragment:{code:He,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:"triangle-list",cullMode:"none"},multisample:{count:o}},a);let b=0;const v=()=>{if(n)throw new Error("LineRenderer is disposed.")};return{prepare:(t,n,i,r,o=0,a=1,g=1,y=1)=>{v(),b=s(t.data);const x=f(t.data),{xMin:w,xMax:M,yMin:F,yMax:N}=x??{xMin:0,xMax:1,yMin:0,yMax:1},{a:C,b:S}=je(i,w,M),{a:A,b:I}=je(r,F,N);((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})(m,C,S+C*o,A,I);const P=Number.isFinite(a)&&a>0?a:1,R=Number.isFinite(g)&&g>0?g:1,E=Number.isFinite(y)&&y>0?y:1,B=Number.isFinite(t.lineStyle.width)&&t.lineStyle.width>0?t.lineStyle.width:2;m[16]=R,m[17]=E,m[18]=P,m[19]=B,ze(e,u,d);const[T,D,U,k]=(e=>_(e)??[0,0,0,1])(t.color),G=qe(t.lineStyle.opacity);p[0]=T,p[1]=D,p[2]=U,p[3]=qe(k*G),ze(e,c,p),h=e.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:u}},{binding:1,resource:{buffer:c}},{binding:2,resource:{buffer:n}}]})},render:e=>{v(),h&&!(b<2)&&(e.setPipeline(g),e.setBindGroup(0,h),e.draw(6,b-1))},dispose:()=>{if(!n){n=!0,h=null,b=0;try{u.destroy()}catch{}try{c.destroy()}catch{}}}}}const Je="// scatter.wgsl\n// Instanced anti-aliased circle shader (SDF):\n// - Per-instance vertex input:\n// - center = vec2 point center (transformed by VSUniforms.transform)\n// - radiusPx = f32 circle radius in pixels\n// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS\n// - Uniforms:\n// - @group(0) @binding(0): VSUniforms { transform, viewportPx }\n// - @group(0) @binding(1): FSUniforms { color }\n//\n// Notes:\n// - `viewportPx` is the current render target size in pixels (width, height).\n// - The quad is expanded in clip space using `radiusPx` and `viewportPx`.\n\nstruct VSUniforms {\n transform: mat4x4,\n viewportPx: vec2,\n // Pad to 16-byte alignment (mat4x4 is 64B; vec2 adds 8B; pad to 80B).\n _pad0: vec2,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct FSUniforms {\n color: vec4,\n};\n\n@group(0) @binding(1) var fsUniforms: FSUniforms;\n\nstruct VSIn {\n @location(0) center: vec2,\n @location(1) radiusPx: f32,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n @location(0) localPx: vec2,\n @location(1) radiusPx: f32,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fixed local corners for 2 triangles (triangle-list).\n // `localNdc` is a quad in [-1, 1]^2; we convert it to pixel offsets via radiusPx.\n let localNdc = array, 6>(\n vec2(-1.0, -1.0),\n vec2( 1.0, -1.0),\n vec2(-1.0, 1.0),\n vec2(-1.0, 1.0),\n vec2( 1.0, -1.0),\n vec2( 1.0, 1.0)\n );\n\n let corner = localNdc[vertexIndex];\n let localPx = corner * in.radiusPx;\n\n // Convert pixel offset to clip-space offset.\n // Clip space spans [-1, 1] across the viewport, so px -> clip is (2 / viewportPx).\n let localClip = localPx * (2.0 / vsUniforms.viewportPx);\n\n let centerClip = (vsUniforms.transform * vec4(in.center, 0.0, 1.0)).xy;\n\n var out: VSOut;\n out.clipPosition = vec4(centerClip + localClip, 0.0, 1.0);\n out.localPx = localPx;\n out.radiusPx = in.radiusPx;\n return out;\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n // Signed distance to the circle boundary (negative inside).\n let dist = length(in.localPx) - in.radiusPx;\n\n // Analytic-ish AA: smooth edge based on derivative of dist in screen space.\n let w = fwidth(dist);\n let a = 1.0 - smoothstep(0.0, w, dist);\n\n // Discard fully outside to avoid unnecessary blending work.\n if (a <= 0.0) {\n discard;\n }\n\n return vec4(fsUniforms.color.rgb, fsUniforms.color.a * a);\n}\n\n",Ke=(e,t,n)=>Math.min(n,Math.max(t,0|e)),Qe=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},et=(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),a=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(a)?a:0}};function tt(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,d=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),m=Ge(e,80,{label:"scatterRenderer/vsUniforms"}),p=Ge(e,16,{label:"scatterRenderer/fsUniforms"}),h=new ArrayBuffer(80),g=new Float32Array(h),b=new Float32Array(4),v=e.createBindGroup({layout:d,entries:[{binding:0,resource:{buffer:m}},{binding:1,resource:{buffer:p}}]}),y=Ue(e,{label:"scatterRenderer/pipeline",bindGroupLayouts:[d],vertex:{code:Je,label:"scatter.wgsl",buffers:[{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32",offset:8}]}]},fragment:{code:Je,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:o}},a);let x=null,w=0,M=new ArrayBuffer(0),F=new Float32Array(M),N=0,C=0,S=[1,1],A=null;const I=()=>{if(n)throw new Error("ScatterRenderer is disposed.")},P=(t,n,i,r,o,a)=>{const s=Number.isFinite(o)&&o>0?o:1,l=Number.isFinite(a)&&a>0?a:1;((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})(g,t,n,i,r),g[16]=s,g[17]=l,g[18]=0,g[19]=0,ze(e,m,h),S=[s,l]};return{prepare:(t,n,i,r,o)=>{I();const a=f(n),{xMin:d,xMax:m,yMin:h,yMax:g}=a??{xMin:0,xMax:1,yMin:0,yMax:1},{a:v,b:y}=et(i,d,m),{a:R,b:E}=et(r,h,g);o?(N=o.canvasWidth,C=o.canvasHeight,P(v,y,R,E,o.canvasWidth,o.canvasHeight),A=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=Ke(Math.floor(r),0,Math.max(0,t)),u=Ke(Math.floor(a),0,Math.max(0,n)),c=Ke(Math.ceil(o),0,Math.max(0,t)),d=Ke(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(o)):(P(v,y,R,E,S[0],S[1]),A=null);const[B,T,D,U]=(e=>_(e)??[0,0,0,1])(t.color);b[0]=B,b[1]=T,b[2]=D,b[3]=(e=>Math.min(1,Math.max(0,e)))(U),ze(e,p,b);const k=(null==o?void 0:o.devicePixelRatio)??1,G=k>0&&Number.isFinite(k),z=t.symbolSize,V=[0,0,void 0],L="function"==typeof z?(e,t,n)=>{V[0]=e,V[1]=t,V[2]=n;const i=z(V);return"number"==typeof i&&Number.isFinite(i)?i:4}:"number"==typeof z&&Number.isFinite(z)?(e,t,n)=>z:(e,t,n)=>4,W=s(n);(e=>{if(e<=F.length)return;const t=Math.max(8,Qe(e));M=new ArrayBuffer(4*t),F=new Float32Array(M)})(4*W);const O=F;let Y=0;for(let e=0;e0&&(O[Y+0]=t,O[Y+1]=i,O[Y+2]=s,O[Y+3]=0,Y+=4)}w=Y/4;const X=Math.max(4,16*w);if(!x||x.size0&&e.queue.writeBuffer(x,0,M,0,16*w)},render:e=>{I(),x&&0!==w&&(A&&N>0&&C>0&&e.setScissorRect(A.x,A.y,A.w,A.h),e.setPipeline(y),e.setBindGroup(0,v),e.setVertexBuffer(0,x),e.draw(6,w),A&&N>0&&C>0&&e.setScissorRect(0,0,N,C))},dispose:()=>{if(!n){if(n=!0,x)try{x.destroy()}catch{}x=null,w=0;try{m.destroy()}catch{}try{p.destroy()}catch{}N=0,C=0,S=[1,1],A=null}}}}const nt="struct RenderUniforms {\n plotOriginPx: vec2,\n plotSizePx: vec2,\n binSizePx: u32,\n binCountX: u32,\n binCountY: u32,\n normalization: u32,\n _pad: vec2,\n};\n\n@group(0) @binding(0) var u: RenderUniforms;\n@group(0) @binding(1) var bins: array;\n@group(0) @binding(2) var maxBuf: array;\n@group(0) @binding(3) var lutTex: texture_2d;\n\nstruct VsOut {\n @builtin(position) position: vec4f,\n};\n\n@vertex\nfn vsMain(@builtin(vertex_index) vid: u32) -> VsOut {\n // Fullscreen triangle (covers clip space).\n // (0,0)->(-1,-1), (2,0)->(3,-1), (0,2)->(-1,3)\n var pos = array(\n vec2f(-1.0, -1.0),\n vec2f(3.0, -1.0),\n vec2f(-1.0, 3.0)\n );\n var out: VsOut;\n out.position = vec4f(pos[vid], 0.0, 1.0);\n return out;\n}\n\nfn applyNormalization(count: f32, maxCount: f32, mode: u32) -> f32 {\n if (maxCount <= 0.0) {\n return 0.0;\n }\n let t = clamp(count / maxCount, 0.0, 1.0);\n if (mode == 1u) { // sqrt\n return sqrt(t);\n }\n if (mode == 2u) { // log\n // log1p(count) / log1p(max)\n return clamp(log(1.0 + count) / max(1e-9, log(1.0 + maxCount)), 0.0, 1.0);\n }\n return t; // linear\n}\n\n@fragment\nfn fsMain(@builtin(position) pos: vec4f) -> @location(0) vec4f {\n // pos.xy is framebuffer pixel coords (device px) with origin top-left.\n let x = pos.x;\n let y = pos.y;\n\n let left = f32(u.plotOriginPx.x);\n let top = f32(u.plotOriginPx.y);\n // plot scissor also applied on CPU; keep a guard anyway.\n if (x < left || y < top) {\n return vec4f(0.0);\n }\n\n let localX = u32((x - left) / f32(u.binSizePx));\n let localY = u32((y - top) / f32(u.binSizePx));\n if (localX >= u.binCountX || localY >= u.binCountY) {\n return vec4f(0.0);\n }\n\n let idx = localY * u.binCountX + localX;\n let c = f32(bins[idx]);\n let maxC = f32(maxBuf[0]);\n\n let t = applyNormalization(c, maxC, u.normalization);\n let lutX = i32(round(t * 255.0));\n let lut = textureLoad(lutTex, vec2(lutX, 0), 0);\n return vec4f(lut.rgb, 1.0);\n}\n\n",it=e=>Math.min(1,Math.max(0,e)),rt=(e,t,n)=>Math.min(n,Math.max(t,0|e)),ot=(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),a=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(a)?a:0}},at=(e,t,n)=>e+(t-e)*n,st=(e,t,n)=>[at(e[0],t[0],n),at(e[1],t[1],n),at(e[2],t[2],n),at(e[3],t[3],n)],lt=e=>_(e)??[0,0,0,1],ut=e=>"plasma"===e?["#0d0887","#6a00a8","#b12a90","#e16462","#fca636","#f0f921"]:"inferno"===e?["#000004","#420a68","#932667","#dd513a","#fca50a","#fcffa4"]:["#440154","#3b528b","#21918c","#5ec962","#fde725"],ct=new Uint32Array([0]).buffer;function dt(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=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"}}]}),l=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"}}]}),u=Ge(e,128,{label:"scatterDensity/computeUniforms"}),c=new ArrayBuffer(128),d=new Float32Array(c,0,20),f=new Uint32Array(c),m=Ge(e,48,{label:"scatterDensity/renderUniforms"}),p=new ArrayBuffer(48),h=new Uint32Array(p),g=De(e,"struct ComputeUniforms {\n transform: mat4x4,\n viewportPx: vec2f,\n _pad0: vec2f,\n plotOriginPx: vec2,\n plotSizePx: vec2,\n binSizePx: u32,\n binCountX: u32,\n binCountY: u32,\n visibleStart: u32,\n visibleEnd: u32,\n normalization: u32,\n _pad1: vec2,\n};\n\n@group(0) @binding(0) var u: ComputeUniforms;\n@group(0) @binding(1) var points: array;\n@group(0) @binding(2) var bins: array>;\n\nstruct MaxBuffer {\n value: atomic,\n};\n@group(0) @binding(3) var maxBuf: MaxBuffer;\n\nfn clipToDevicePx(clip: vec2f) -> vec2f {\n // clip in [-1,1] -> device pixel in [0, viewport]\n return vec2f(\n (clip.x * 0.5 + 0.5) * u.viewportPx.x,\n (-clip.y * 0.5 + 0.5) * u.viewportPx.y\n );\n}\n\n@compute @workgroup_size(256)\nfn binPoints(@builtin(global_invocation_id) gid: vec3) {\n let idx = u.visibleStart + gid.x;\n if (idx >= u.visibleEnd) {\n return;\n }\n\n let p = points[idx];\n let clip4 = u.transform * vec4f(p.x, p.y, 0.0, 1.0);\n let clip = clip4.xy / max(1e-9, clip4.w);\n let px = clipToDevicePx(clip);\n\n // Scissor bounds in device px\n let left = f32(u.plotOriginPx.x);\n let top = f32(u.plotOriginPx.y);\n let right = left + f32(u.plotSizePx.x);\n let bottom = top + f32(u.plotSizePx.y);\n\n if (px.x < left || px.x >= right || px.y < top || px.y >= bottom) {\n return;\n }\n\n let localX = u32((px.x - left) / f32(u.binSizePx));\n let localY = u32((px.y - top) / f32(u.binSizePx));\n if (localX >= u.binCountX || localY >= u.binCountY) {\n return;\n }\n\n let binIndex = localY * u.binCountX + localX;\n atomicAdd(&bins[binIndex], 1u);\n}\n\n@compute @workgroup_size(256)\nfn reduceMax(@builtin(global_invocation_id) gid: vec3) {\n let binTotal = u.binCountX * u.binCountY;\n let i = gid.x;\n if (i >= binTotal) {\n return;\n }\n\n let v = atomicLoad(&bins[i]);\n atomicMax(&maxBuf.value, v);\n}\n\n","scatterDensityBinning.wgsl",a),b=e.createPipelineLayout({bindGroupLayouts:[s]}),v=ke(e,{label:"scatterDensity/binPointsPipeline",layout:b,compute:{module:g,entryPoint:"binPoints"}},a),y=ke(e,{label:"scatterDensity/reduceMaxPipeline",layout:b,compute:{module:g,entryPoint:"reduceMax"}},a),x=Ue(e,{label:"scatterDensity/renderPipeline",bindGroupLayouts:[l],vertex:{code:nt,label:"scatterDensityColormap.wgsl"},fragment:{code:nt,label:"scatterDensityColormap.wgsl",formats:i,blend:void 0},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:o}},a);let w=null,M=null,F=0,N=null,C=null,S="",A=null,I=null,P=null,R=-1,E=0,B=0,T=0,D=0,U=0,k=null,G=0,z=0,V=2,L=!0,W=!1,O=new Uint32Array(0);const _=()=>{if(n)throw new Error("ScatterDensityRenderer is disposed.")};return{prepare:(t,n,i,r,o,a,g,b,v)=>{_(),W=!0;const y=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=rt(Math.floor(r),0,Math.max(0,t)),u=rt(Math.floor(a),0,Math.max(0,n)),c=rt(Math.ceil(o),0,Math.max(0,t)),d=rt(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(b),x=b.devicePixelRatio,Y=Number.isFinite(t.binSize)?Math.max(1e-6,t.binSize):2,X=Math.max(1,Math.round(Y*(Number.isFinite(x)&&x>0?x:1))),$=Math.max(1,Math.ceil(y.w/X)),H=Math.max(1,Math.ceil(y.h/X));((t,n)=>{const i=Math.max(1,0|t)*Math.max(1,0|n);if(w&&M&&i<=F)return;const r=Math.max(1,i);if(F=Math.max(256,(e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))})(r)),w){try{w.destroy()}catch{}w=null}if(M){try{M.destroy()}catch{}M=null}w=e.createBuffer({label:"scatterDensity/binsBuffer",size:4*F,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),M=e.createBuffer({label:"scatterDensity/maxBuffer",size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),O=new Uint32Array(F),A=null,I=null,L=!0})($,H),(t=>{const n=(e=>{if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return"custom"}})(t.densityColormap);if(N||(N=e.createTexture({label:"scatterDensity/lutTexture",size:{width:256,height:1,depthOrArrayLayers:1},format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),C=N.createView(),S=""),n===S)return;const i=(e=>{const t=("string"==typeof e?ut(e):Array.isArray(e)&&e.length>0?e:ut("viridis")).map(lt),n=Math.max(2,t.length),i=new Uint8Array(new ArrayBuffer(1024));for(let e=0;e<256;e++){const r=e/255*(n-1),o=Math.min(n-2,Math.max(0,Math.floor(r))),a=r-o,s=st(t[o],t[o+1],a);i[4*e+0]=rt(Math.round(255*it(s[0])),0,255),i[4*e+1]=rt(Math.round(255*it(s[1])),0,255),i[4*e+2]=rt(Math.round(255*it(s[2])),0,255),i[4*e+3]=rt(Math.round(255*it(s[3])),0,255)}return i})(t.densityColormap);e.queue.writeTexture({texture:N},i,{bytesPerRow:1024,rowsPerImage:1},{width:256,height:1,depthOrArrayLayers:1}),S=n})(t);const q=(e=>"sqrt"===e?1:"log"===e?2:0)(t.densityNormalization);P!==n&&(P=n,A=null,I=null,L=!0),R!==i&&(R=i,L=!0),(E!==r||B!==o)&&(E=r,B=o,L=!0),(T!==X||D!==$||U!==H)&&(T=X,D=$,U=H,L=!0),(!k||k.x!==y.x||k.y!==y.y||k.w!==y.w||k.h!==y.h)&&(k=y,L=!0),(G!==b.canvasWidth||z!==b.canvasHeight)&&(G=b.canvasWidth,z=b.canvasHeight,L=!0),V!==q&&(V=q,L=!0);const j=v,Z=(null==j?void 0:j.xMin)??0,J=(null==j?void 0:j.xMax)??1,K=(null==j?void 0:j.yMin)??0,Q=(null==j?void 0:j.yMax)??1,{a:ee,b:te}=ot(a,Z,J),{a:ne,b:ie}=ot(g,K,Q);((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})(d,ee,te,ne,ie),d[16]=b.canvasWidth>0?b.canvasWidth:1,d[17]=b.canvasHeight>0?b.canvasHeight:1,d[18]=0,d[19]=0,f[20]=y.x>>>0,f[21]=y.y>>>0,f[22]=y.w>>>0,f[23]=y.h>>>0,f[24]=X>>>0,f[25]=$>>>0,f[26]=H>>>0,f[27]=(0|Math.max(0,r))>>>0,f[28]=(0|Math.max(0,o))>>>0,f[29]=q>>>0,ze(e,u,c),h[0]=y.x>>>0,h[1]=y.y>>>0,h[2]=y.w>>>0,h[3]=y.h>>>0,h[4]=X>>>0,h[5]=$>>>0,h[6]=H>>>0,h[7]=q>>>0,ze(e,m,p),!w||!M||!C||!P||(A||(A=e.createBindGroup({label:"scatterDensity/computeBindGroup",layout:s,entries:[{binding:0,resource:{buffer:u}},{binding:1,resource:{buffer:P}},{binding:2,resource:{buffer:w}},{binding:3,resource:{buffer:M}}]})),I||(I=e.createBindGroup({label:"scatterDensity/renderBindGroup",layout:l,entries:[{binding:0,resource:{buffer:m}},{binding:1,resource:{buffer:w}},{binding:2,resource:{buffer:M}},{binding:3,resource:C}]})))},encodeCompute:t=>{if(_(),!W||!L)return;if(!w||!M||!A||R<=0)return void(L=!1);if(!k||k.w<=0||k.h<=0)return void(L=!1);e.queue.writeBuffer(w,0,O.buffer,0,4*F),e.queue.writeBuffer(M,0,ct);const n=D*U|0,i=Math.max(0,B-E|0),r=t.beginComputePass({label:"scatterDensity/computePass"});r.setBindGroup(0,A),r.setPipeline(v);const o=Math.ceil(i/256);o>0&&r.dispatchWorkgroups(o),r.setPipeline(y);const a=Math.ceil(n/256);a>0&&r.dispatchWorkgroups(a),r.end(),L=!1},render:e=>{_(),W&&(!I||!k||!C||k.w<=0||k.h<=0||(e.setScissorRect(k.x,k.y,k.w,k.h),e.setPipeline(x),e.setBindGroup(0,I),e.draw(3),G>0&&z>0&&e.setScissorRect(0,0,G,z)))},dispose:()=>{if(!n){n=!0;try{u.destroy()}catch{}try{m.destroy()}catch{}if(w)try{w.destroy()}catch{}if(M)try{M.destroy()}catch{}if(w=null,M=null,F=0,N)try{N.destroy()}catch{}N=null,C=null,A=null,I=null,P=null}}}}const ft="// pie.wgsl\n// Instanced anti-aliased pie-slice shader (instanced quad + SDF mask).\n//\n// - Per-instance vertex input:\n// - center = vec2 slice center (transformed by VSUniforms.transform)\n// - startAngleRad = f32 start angle in radians\n// - endAngleRad = f32 end angle in radians\n// - radiiPx = vec2(innerRadiusPx, outerRadiusPx) in *device pixels*\n// - color = vec4 RGBA color in [0..1]\n//\n// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS\n//\n// - Uniforms:\n// - @group(0) @binding(0): VSUniforms { transform, viewportPx }\n//\n// Notes:\n// - The quad is expanded in clip space using `radiusPx` and `viewportPx`.\n// - Fragment uses an SDF mask for the circle boundary + an angular wedge mask.\n// - Fully outside fragments are discarded to avoid unnecessary blending work.\n//\n// Conventions: matches other shaders in this repo (vsMain/fsMain, group 0 bindings,\n// and explicit uniform padding/alignment where needed).\n\nconst PI: f32 = 3.141592653589793;\nconst TAU: f32 = 6.283185307179586; // 2*pi\n\nstruct VSUniforms {\n transform: mat4x4,\n viewportPx: vec2,\n // Pad to 16-byte alignment (mat4x4 is 64B; vec2 adds 8B; pad to 80B).\n _pad0: vec2,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct VSIn {\n @location(0) center: vec2,\n @location(1) startAngleRad: f32,\n @location(2) endAngleRad: f32,\n @location(3) radiiPx: vec2, // (innerPx, outerPx)\n @location(4) color: vec4,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n @location(0) localPx: vec2,\n @location(1) startAngleRad: f32,\n @location(2) endAngleRad: f32,\n @location(3) radiiPx: vec2,\n @location(4) color: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fixed local corners for 2 triangles (triangle-list).\n // `localNdc` is a quad in [-1, 1]^2; we convert it to pixel offsets via radiusPx.\n let localNdc = array, 6>(\n vec2(-1.0, -1.0),\n vec2( 1.0, -1.0),\n vec2(-1.0, 1.0),\n vec2(-1.0, 1.0),\n vec2( 1.0, -1.0),\n vec2( 1.0, 1.0)\n );\n\n let corner = localNdc[vertexIndex];\n let outerPx = in.radiiPx.y;\n let localPx = corner * outerPx;\n\n // Convert pixel offset to clip-space offset.\n // Clip space spans [-1, 1] across the viewport, so px -> clip is (2 / viewportPx).\n let localClip = localPx * (2.0 / vsUniforms.viewportPx);\n\n let centerClip = (vsUniforms.transform * vec4(in.center, 0.0, 1.0)).xy;\n\n var out: VSOut;\n out.clipPosition = vec4(centerClip + localClip, 0.0, 1.0);\n out.localPx = localPx;\n out.startAngleRad = in.startAngleRad;\n out.endAngleRad = in.endAngleRad;\n out.radiiPx = in.radiiPx;\n out.color = in.color;\n return out;\n}\n\nfn wrapToTau(theta: f32) -> f32 {\n // Maps theta to [0, TAU). (Input often comes from atan2 in [-PI, PI].)\n return select(theta, theta + TAU, theta < 0.0);\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n let p = in.localPx;\n let r = length(p);\n\n let innerPx = in.radiiPx.x;\n let outerPx = in.radiiPx.y;\n\n // --- Radial mask: ring between inner and outer radii (inner==0 => pie) ---\n // Positive inside the ring, negative outside.\n let radialDist = min(r - innerPx, outerPx - r);\n let radialW = fwidth(radialDist);\n let radialA = smoothstep(-radialW, radialW, radialDist);\n\n if (radialA <= 0.0) {\n discard;\n }\n\n // Compute fragment angle in [0, TAU).\n let angle = wrapToTau(atan2(p.y, p.x));\n\n // --- Angular mask: wedge between start/end angles with wrap ---\n let start = in.startAngleRad;\n let end = in.endAngleRad;\n\n // Compute span in [0, 2π) with wrap.\n var span = end - start;\n span = span + select(0.0, TAU, span < 0.0);\n\n // Compute rel in [0, 2π) with wrap.\n var rel = angle - start;\n rel = rel + select(0.0, TAU, rel < 0.0);\n\n let inside = rel <= span;\n\n // Signed angular distance (in radians) to nearest boundary.\n // - Inside: +min(rel, span-rel)\n // - Outside: -min(rel-span, 2π-rel)\n let dIn = min(rel, max(span - rel, 0.0));\n let dOutA = max(rel - span, 0.0);\n let dOutB = max(TAU - rel, 0.0);\n let dOut = min(dOutA, dOutB);\n\n let signedAngleDist = select(-dOut, dIn, inside);\n\n // Convert to approximate pixel distance to the boundary ray.\n // (For small angles, perpendicular distance to a ray ≈ r * angle.)\n let angleDistPx = signedAngleDist * max(r, 1.0);\n\n let angW = fwidth(angleDistPx);\n let angularA = smoothstep(-angW, angW, angleDistPx);\n\n let aOut = radialA * angularA;\n if (aOut <= 0.0) {\n discard;\n }\n\n return vec4(in.color.rgb, in.color.a * aOut);\n}\n\n",mt=2*Math.PI,pt=e=>Math.min(1,Math.max(0,e)),ht=(e,t,n)=>Math.min(n,Math.max(t,0|e)),gt=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},bt=e=>{if(!Number.isFinite(e))return 0;const t=e%mt;return t<0?t+mt:t},vt=(e,t)=>{const n=_(e);if(n)return[n[0],n[1],n[2],pt(n[3])];const i=_(t);return i?[i[0],i[1],i[2],pt(i[3])]:[0,0,0,1]},yt=(e,t)=>{if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"!=typeof e)return null;const n=e.trim();if(0===n.length)return null;if(n.endsWith("%")){const e=Number.parseFloat(n.slice(0,-1));return Number.isFinite(e)?e/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},xt=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);function wt(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),l=Ge(e,80,{label:"pieRenderer/vsUniforms"}),u=new ArrayBuffer(80),c=new Float32Array(u),d=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}}]}),f=Ue(e,{label:"pieRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:ft,label:"pie.wgsl",buffers:[{arrayStride:40,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:ft,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:o}},a);let m=null,p=0,h=new ArrayBuffer(0),g=new Float32Array(h),b=0,v=0,y=null;const x=()=>{if(n)throw new Error("PieRenderer is disposed.")};return{prepare:(t,n)=>{x();const i=n.devicePixelRatio,r=i>0&&Number.isFinite(i)?i:1;b=n.canvasWidth,v=n.canvasHeight,((t,n)=>{const i=Number.isFinite(t)&&t>0?t:1,r=Number.isFinite(n)&&n>0?n:1;c.set(xt,0),c[16]=i,c[17]=r,c[18]=0,c[19]=0,ze(e,l,u)})(n.canvasWidth,n.canvasHeight),y=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=ht(Math.floor(r),0,Math.max(0,t)),u=ht(Math.floor(a),0,Math.max(0,n)),c=ht(Math.ceil(o),0,Math.max(0,t)),d=ht(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(n);const o=n.canvasWidth/r,a=n.canvasHeight/r;if(!(o>0&&a>0))return void(p=0);const s=o-n.left-n.right,d=a-n.top-n.bottom;if(!(s>0&&d>0))return void(p=0);const f=.5*Math.min(s,d);if(!(f>0))return void(p=0);const w=((e,t,n)=>{const i=(null==e?void 0:e[0])??"50%",r=(null==e?void 0:e[1])??"50%",o=yt(i,t),a=yt(r,n);return{x:Number.isFinite(o)?o:.5*t,y:Number.isFinite(a)?a:.5*n}})(t.center,s,d),M=(n.left+w.x)/o*2-1,F=1-(n.top+w.y)/a*2;if(!Number.isFinite(M)||!Number.isFinite(F))return void(p=0);const N=((e,t)=>{if(null==e)return{inner:0,outer:.7*t};if((e=>Array.isArray(e))(e)){const n=yt(e[0],t),i=yt(e[1],t),r=Math.max(0,Number.isFinite(n)?n:0),o=Math.max(r,Number.isFinite(i)?i:.7*t);return{inner:r,outer:Math.min(t,o)}}const n=yt(e,t),i=Math.max(0,Number.isFinite(n)?n:.7*t);return{inner:0,outer:Math.min(t,i)}})(t.radius,f),C=Math.max(0,Math.min(N.inner,N.outer)),S=C*r,A=Math.max(C,N.outer)*r;if(!(A>0))return void(p=0);let I=0,P=0;for(let e=0;e0&&!1!==n.visible&&(I+=i,P++)}if(!(I>0)||0===P)return void(p=0);(e=>{if(e<=g.length)return;const t=Math.max(8,gt(e));h=new ArrayBuffer(4*t),g=new Float32Array(h)})(10*P);const R=g,E="number"==typeof t.startAngle&&Number.isFinite(t.startAngle)?t.startAngle:90;let B=bt(E*Math.PI/180),T=0,D=0,U=0;for(let e=0;e0))continue;const o=B,a=1===P?B+mt:bt(B+r);B=bt(B+r);const[s,l,u,c]=vt(n.color,t.color);R[D+0]=M,R[D+1]=F,R[D+2]=o,R[D+3]=a,R[D+4]=S,R[D+5]=A,R[D+6]=s,R[D+7]=l,R[D+8]=u,R[D+9]=c,D+=10}p=D/10;const k=Math.max(4,40*p);if(!m||m.size0&&e.queue.writeBuffer(m,0,h,0,40*p)},render:e=>{x(),m&&0!==p&&(y&&b>0&&v>0&&e.setScissorRect(y.x,y.y,y.w,y.h),e.setPipeline(f),e.setBindGroup(0,d),e.setVertexBuffer(0,m),e.draw(6,p),y&&b>0&&v>0&&e.setScissorRect(0,0,b,v))},dispose:()=>{if(!n){if(n=!0,m)try{m.destroy()}catch{}m=null,p=0;try{l.destroy()}catch{}b=0,v=0,y=null}}}}const Mt="// candlestick.wgsl\n// Instanced candlestick shader (bodies + wicks):\n// - Per-instance vertex input:\n// - xClip, openClip, closeClip, lowClip, highClip, bodyWidthClip (6 floats)\n// - bodyColor rgba (4 floats)\n// - Draw call: draw(18, instanceCount) using triangle-list expansion in VS\n// - vertices 0-5: body quad (2 triangles)\n// - vertices 6-11: upper wick (2 triangles)\n// - vertices 12-17: lower wick (2 triangles)\n// - Uniforms:\n// - @group(0) @binding(0): VSUniforms { transform, wickWidthClip }\n\nstruct VSUniforms {\n transform: mat4x4,\n wickWidthClip: f32,\n _pad0: f32,\n _pad1: f32,\n _pad2: f32,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct VSIn {\n @location(0) xClip: f32,\n @location(1) openClip: f32,\n @location(2) closeClip: f32,\n @location(3) lowClip: f32,\n @location(4) highClip: f32,\n @location(5) bodyWidthClip: f32,\n @location(6) bodyColor: vec4,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n @location(0) color: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Compute body bounds\n let bodyTop = max(in.openClip, in.closeClip);\n let bodyBottom = min(in.openClip, in.closeClip);\n let bodyLeft = in.xClip - in.bodyWidthClip * 0.5;\n let bodyRight = in.xClip + in.bodyWidthClip * 0.5;\n\n // Wick bounds\n let wickLeft = in.xClip - vsUniforms.wickWidthClip * 0.5;\n let wickRight = in.xClip + vsUniforms.wickWidthClip * 0.5;\n\n var pos: vec2;\n\n if (vertexIndex < 6u) {\n // Body quad (vertices 0-5)\n let corners = array, 6>(\n vec2(0.0, 0.0),\n vec2(1.0, 0.0),\n vec2(0.0, 1.0),\n vec2(0.0, 1.0),\n vec2(1.0, 0.0),\n vec2(1.0, 1.0)\n );\n let corner = corners[vertexIndex];\n let bodyMin = vec2(bodyLeft, bodyBottom);\n let bodyMax = vec2(bodyRight, bodyTop);\n pos = bodyMin + corner * (bodyMax - bodyMin);\n } else if (vertexIndex < 12u) {\n // Upper wick (vertices 6-11): from bodyTop to highClip\n let idx = vertexIndex - 6u;\n let corners = array, 6>(\n vec2(0.0, 0.0),\n vec2(1.0, 0.0),\n vec2(0.0, 1.0),\n vec2(0.0, 1.0),\n vec2(1.0, 0.0),\n vec2(1.0, 1.0)\n );\n let corner = corners[idx];\n let wickMin = vec2(wickLeft, bodyTop);\n let wickMax = vec2(wickRight, in.highClip);\n pos = wickMin + corner * (wickMax - wickMin);\n } else {\n // Lower wick (vertices 12-17): from lowClip to bodyBottom\n let idx = vertexIndex - 12u;\n let corners = array, 6>(\n vec2(0.0, 0.0),\n vec2(1.0, 0.0),\n vec2(0.0, 1.0),\n vec2(0.0, 1.0),\n vec2(1.0, 0.0),\n vec2(1.0, 1.0)\n );\n let corner = corners[idx];\n let wickMin = vec2(wickLeft, in.lowClip);\n let wickMax = vec2(wickRight, bodyBottom);\n pos = wickMin + corner * (wickMax - wickMin);\n }\n\n var out: VSOut;\n out.clipPosition = vsUniforms.transform * vec4(pos, 0.0, 1.0);\n out.color = in.bodyColor;\n return out;\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n return in.color;\n}\n",Ft=10,Nt=(e,t,n)=>Math.min(n,Math.max(t,0|e)),Ct=e=>_(e)??[0,0,0,1],St=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},At=e=>(e=>Array.isArray(e))(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};function It(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),l=Ge(e,80,{label:"candlestickRenderer/vsUniforms"});ze(e,l,(()=>{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})());const u=new ArrayBuffer(80),c=new Float32Array(u),d=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}}]}),f=Ue(e,{label:"candlestickRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:Mt,label:"candlestick.wgsl",buffers:[{arrayStride:40,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:Mt,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:o}},a);let m=null,p=0,h=new ArrayBuffer(0),g=new Float32Array(h),b=0,v=0,y=null,x=!1,w=null,M=0,F=new ArrayBuffer(0),N=new Float32Array(F);const C=()=>{if(n)throw new Error("CandlestickRenderer is disposed.")};return{prepare:(t,n,i,r,o,a)=>{if(C(),0===n.length)return p=0,void(M=0);const s=(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?{plotWidthCss:r,plotHeightCss:o}:null})(o);if(!s)return p=0,void(M=0);const d=(e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:a,devicePixelRatio:s}=e,l=t*s/o*2-1,u=(o-n*s)/o*2-1,c=1-i*s/a*2,d=1-(a-r*s)/a*2;return{left:l,right:u,top:c,bottom:d,width:u-l,height:c-d}})(o),f=s.plotWidthCss>0?d.width/s.plotWidthCss:0;b=o.canvasWidth,v=o.canvasHeight,y=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=Nt(Math.floor(r),0,Math.max(0,t)),u=Nt(Math.floor(a),0,Math.max(0,n)),c=Nt(Math.ceil(o),0,Math.max(0,t)),d=Nt(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(o);const S=(e=>{const t=[];for(let n=0;ne-t);let n=Number.POSITIVE_INFINITY;for(let e=1;e0&&i0?n:1})(n),A=((e,t,n,i)=>{if(Number.isFinite(t)&&t>0){const n=e.scale(0),i=e.scale(0+t),r=Math.abs(i-n);if(Number.isFinite(r)&&r>0)return r}const r=Math.abs(n.width);return r>0?r/Math.max(1,Math.floor(i)):0})(i,S,d,n.length);let I=0;const P=t.barWidth;if("number"==typeof P)I=Math.max(0,P)*f;else if("string"==typeof P){const e=(e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null})(P);I=null==e?0:A*(e=>Math.min(1,Math.max(0,e)))(e)}const R=t.barMinWidth*f,E=t.barMaxWidth*f;I=Math.min(Math.max(I,R),E);const B=t.itemStyle.borderWidth??1,T=Math.max(0,B)*f;c.set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,T,0,0,0]),ze(e,l,u);const D=Ct(t.itemStyle.upColor),U=Ct(t.itemStyle.downColor),k=Ct(t.itemStyle.upBorderColor),G=Ct(t.itemStyle.downBorderColor),z=a?Ct(a):[0,0,0,1];x="hollow"===t.style,(e=>{if(e<=g.length)return;const t=Math.max(8,St(e));h=new ArrayBuffer(4*t),g=new Float32Array(h)})(n.length*Ft);const V=g;let L=0;x&&(e=>{if(e<=N.length)return;const t=Math.max(8,St(e));F=new ArrayBuffer(4*t),N=new Float32Array(F)})(n.length*Ft);const W=N;let O=0;for(let e=0;ea;if(x){const e=g?k:G;if(V[L+0]=c,V[L+1]=d,V[L+2]=m,V[L+3]=p,V[L+4]=h,V[L+5]=I,V[L+6]=e[0],V[L+7]=e[1],V[L+8]=e[2],V[L+9]=e[3],L+=Ft,g){const e=t.itemStyle.borderWidth*f,n=Math.max(0,I-2*e);W[O+0]=c,W[O+1]=d,W[O+2]=m,W[O+3]=p,W[O+4]=h,W[O+5]=n,W[O+6]=z[0],W[O+7]=z[1],W[O+8]=z[2],W[O+9]=z[3],O+=Ft}}else{const e=g?D:U;V[L+0]=c,V[L+1]=d,V[L+2]=m,V[L+3]=p,V[L+4]=h,V[L+5]=I,V[L+6]=e[0],V[L+7]=e[1],V[L+8]=e[2],V[L+9]=e[3],L+=Ft}}p=L/Ft,M=O/Ft;const _=Math.max(4,40*p);if(!m||m.size<_){const t=Math.max(Math.max(4,St(_)),m?m.size:0);if(m)try{m.destroy()}catch{}m=e.createBuffer({label:"candlestickRenderer/instanceBuffer",size:t,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}if(p>0&&e.queue.writeBuffer(m,0,h,0,40*p),x&&M>0){const t=Math.max(4,40*M);if(!w||w.size{C(),m&&0!==p&&(y&&b>0&&v>0&&e.setScissorRect(y.x,y.y,y.w,y.h),e.setPipeline(f),e.setBindGroup(0,d),e.setVertexBuffer(0,m),e.draw(18,p),x&&w&&M>0&&(e.setVertexBuffer(0,w),e.draw(6,M)),y&&b>0&&v>0&&e.setScissorRect(0,0,b,v))},dispose:()=>{if(!n){if(n=!0,m)try{m.destroy()}catch{}if(m=null,p=0,w)try{w.destroy()}catch{}w=null,M=0;try{l.destroy()}catch{}b=0,v=0,y=null}}}}const Pt="// bar.wgsl\n// Instanced bar/rect shader:\n// - Per-instance vertex input:\n// - rect = vec4(x, y, width, height) in CLIP space\n// - color = vec4(r, g, b, a) in [0..1]\n// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS\n// - Uniforms:\n// - @group(0) @binding(0): VSUniforms { transform }\n\nstruct VSUniforms {\n transform: mat4x4,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct VSIn {\n // rect.xy = origin, rect.zw = size (width, height)\n @location(0) rect: vec4,\n @location(1) color: vec4,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n @location(0) color: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fixed local corners for 2 triangles (triangle-list).\n let corners = array, 6>(\n vec2(0.0, 0.0),\n vec2(1.0, 0.0),\n vec2(0.0, 1.0),\n vec2(0.0, 1.0),\n vec2(1.0, 0.0),\n vec2(1.0, 1.0)\n );\n\n // Normalize negative width/height by computing min/max extents.\n let p0 = in.rect.xy;\n let p1 = in.rect.xy + in.rect.zw;\n let rectMin = min(p0, p1);\n let rectMax = max(p0, p1);\n let rectSize = rectMax - rectMin;\n\n let corner = corners[vertexIndex];\n let pos = rectMin + corner * rectSize;\n\n var out: VSOut;\n out.clipPosition = vsUniforms.transform * vec4(pos, 0.0, 1.0);\n out.color = in.color;\n return out;\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n return in.color;\n}\n\n",Rt=e=>Math.min(1,Math.max(0,e)),Et=e=>_(e)??[0,0,0,1],Bt=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},Tt=e=>{if("string"!=typeof e)return"";const t=e.trim();return t.length>0?t:""};const Dt="\nstruct VSOut { @builtin(position) pos: vec4f };\n\n@vertex\nfn vsMain(@builtin(vertex_index) i: u32) -> VSOut {\n var positions = array(\n vec2f(-1.0, -1.0),\n vec2f( 3.0, -1.0),\n vec2f(-1.0, 3.0)\n );\n var o: VSOut;\n o.pos = vec4f(positions[i], 0.0, 1.0);\n return o;\n}\n\n// Using textureLoad (no filtering) for pixel-exact blit into the MSAA overlay pass.\n@group(0) @binding(0) var srcTex: texture_2d;\n\n@fragment\nfn fsMain(@builtin(position) pos: vec4f) -> @location(0) vec4f {\n let xy = vec2(pos.xy);\n return textureLoad(srcTex, xy, 0);\n}\n";function Ut(e){if(e)try{e.destroy()}catch{}}const kt="// crosshair.wgsl\n// Minimal crosshair line shader:\n// - Vertex input: vec2 position in clip-space coordinates\n// - VS uniform: transform mat4 (identity)\n// - FS uniform: solid RGBA color\n\nstruct VSUniforms {\n transform: mat4x4,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct FSUniforms {\n color: vec4,\n};\n\n@group(0) @binding(1) var fsUniforms: FSUniforms;\n\nstruct VSIn {\n @location(0) position: vec2,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn) -> VSOut {\n var out: VSOut;\n out.clipPosition = vsUniforms.transform * vec4(in.position, 0.0, 1.0);\n return out;\n}\n\n@fragment\nfn fsMain() -> @location(0) vec4 {\n return fsUniforms.color;\n}\n\n";const Gt=[1,1,1,.8],zt=(e,t,n)=>Math.min(n,Math.max(t,0|e)),Vt=(e,t)=>e/t*2-1,Lt=(e,t)=>1-e/t*2,Wt=(e,t)=>{e.push(t[0],t[1],t[2],t[3])},Ot=(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[];if(!Number.isFinite(10))return[];const r=Math.ceil((i-n)/10);if(!Number.isFinite(r)||r<=0)return[];const o=[];let a=n;for(;ae&&o.push([e,t]),a+=10}return o};function _t(e,t){let n=!1,i=!0;const r=(null==t?void 0:t.targetFormat)??"bgra8unorm",o=(null==t?void 0:t.sampleCount)??1,a=Number.isFinite(o)?Math.max(1,Math.floor(o)):1,s=null==t?void 0:t.pipelineCache,l=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),u=Ge(e,64,{label:"crosshairRenderer/vsUniforms"}),c=Ge(e,16,{label:"crosshairRenderer/fsUniforms"}),d=e.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:u}},{binding:1,resource:{buffer:c}}]}),f=Ue(e,{label:"crosshairRenderer/pipeline",bindGroupLayouts:[l],vertex:{code:kt,label:"crosshair.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:kt,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:a}},s),m=function(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=(e=>e+3&-4)(Math.max(4,Math.floor(t))),i=e.limits.maxBufferSize;if(n>i)throw new Error(`createStreamBuffer(maxSize): requested size ${n} bytes exceeds device.limits.maxBufferSize (${i}).`);const r=n>>>2,o=t=>({buffer:e.createBuffer({label:t,size:n,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),mirror:new Uint32Array(r)}),a=[o("streamBuffer/a"),o("streamBuffer/b")];let s=!1,l=0,u=0;const c=()=>{if(s)throw new Error("createStreamBuffer: StreamBuffer is disposed.")},d=(t,n,i)=>{const r=a[t],o=r.mirror;if(i<0||i>n.length)throw new Error("createStreamBuffer.write: internal error (invalid usedWords).");if(0===i)return;const s=i<<2;e.queue.writeBuffer(r.buffer,0,n.buffer,n.byteOffset,s),o.set(n.subarray(0,i),0)};return{write:t=>{if(c(),1&t.length)throw new Error("createStreamBuffer.write: data length must be even (vec2 vertices).");const i=t.byteLength;if(i>n)throw new Error(`createStreamBuffer.write: data.byteLength (${i}) exceeds capacity (${n}). Increase maxSize.`);const r=t.length>>>1;if(0===i)return void(u=r);const o=(e=>{if(3&e.byteOffset)throw new Error("createStreamBuffer.write: data.byteOffset must be 4-byte aligned.");return new Uint32Array(e.buffer,e.byteOffset,e.byteLength>>>2)})(t),s=1-l;((t,n,i)=>{const r=a[t],o=r.mirror;if(i<0||i>n.length)throw new Error("createStreamBuffer.write: internal error (invalid usedWords).");const s=i<<2;if(s>0&&s<=1024)return void d(t,n,i);const l=[];let u=0,c=0,f=0;for(;f=i)break;const e=f;for(f++;f128||c>16384)return void d(t,n,i)}for(let t=0;t(c(),a[l].buffer),getVertexCount:()=>(c(),u),dispose:()=>{if(!s){s=!0,u=0;for(const e of a)try{e.buffer.destroy()}catch{}}}}}(e,65536);let p=0,h=0,g=0,b={x:0,y:0,w:0,h:0};const v=()=>{if(n)throw new Error("CrosshairRenderer is disposed.")};return{prepare:(t,n,i,r)=>{if(v(),"boolean"!=typeof r.showX||"boolean"!=typeof r.showY)throw new Error("CrosshairRenderer.prepare: showX/showY must be boolean.");if("string"!=typeof r.color)throw new Error("CrosshairRenderer.prepare: color must be a string.");if(!Number.isFinite(r.lineWidth)||r.lineWidth<0)throw new Error("CrosshairRenderer.prepare: lineWidth must be a finite non-negative number.");const{vertices:o,scissor:a}=((e,t,n,i)=>{if(!Number.isFinite(e)||!Number.isFinite(t))throw new Error("CrosshairRenderer.prepare: x and y must be finite numbers.");if(!(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))(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,a=Number.isFinite(n.devicePixelRatio)&&n.devicePixelRatio>0?n.devicePixelRatio:1,s=n.left*a,l=r-n.right*a,u=n.top*a,c=o-n.bottom*a,d=zt(Math.floor(s),0,Math.max(0,r)),f=zt(Math.floor(u),0,Math.max(0,o)),m=zt(Math.ceil(l),0,Math.max(0,r)),p=zt(Math.ceil(c),0,Math.max(0,o)),h=Math.max(0,m-d),g=Math.max(0,p-f),b=e*a,v=t*a,y=((e,t)=>{if(!Number.isFinite(e)||e<0)throw new Error("CrosshairRenderer.prepare: lineWidth must be a finite non-negative number.");if(0===e)return[];const n=e*t,i=Math.max(1,Math.min(8,Math.round(n))),r=(i-1)/2,o=[];for(let e=0;e0&&F<=8192,C=e=>{const t=Vt(e,r),n=Lt(u,o),i=Lt(c,o);Wt(x,[t,n,t,i])},S=e=>{const t=Lt(e,o),n=Vt(s,r),i=Vt(l,r);Wt(x,[n,t,i,t])};if(i.showX)for(let e=0;e{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})());const s=_(r.color)??Gt,l=new ArrayBuffer(16);new Float32Array(l).set([s[0],s[1],s[2],s[3]]),ze(e,c,l),h=i.canvasWidth,g=i.canvasHeight,b=a},render:e=>{v(),i&&0!==p&&(h<=0||g<=0||(e.setScissorRect(b.x,b.y,b.w,b.h),e.setPipeline(f),e.setBindGroup(0,d),e.setVertexBuffer(0,m.getBuffer()),e.draw(p),e.setScissorRect(0,0,h,g)))},setVisible:e=>{v(),i=!!e},dispose:()=>{if(!n){n=!0;try{u.destroy()}catch{}try{c.destroy()}catch{}m.dispose(),p=0,h=0,g=0,b={x:0,y:0,w:0,h:0}}}}}const Yt="// highlight.wgsl\n// Draws an anti-aliased ring highlight around a point.\n//\n// Contract:\n// - `@builtin(position)` in the fragment stage is framebuffer-space pixels.\n// - The renderer supplies `center` and ring sizes in *device pixels*.\n\nstruct Uniforms {\n center: vec2,\n radius: f32,\n thickness: f32,\n color: vec4,\n outlineColor: vec4,\n};\n\n@group(0) @binding(0) var u: Uniforms;\n\nstruct VSOut {\n @builtin(position) position: vec4,\n};\n\n@vertex\nfn vsMain(@builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fullscreen triangle.\n // Covers clip-space [-1,1] with 3 verts: (-1,-1), (3,-1), (-1,3)\n let positions = array, 3>(\n vec2(-1.0, -1.0),\n vec2(3.0, -1.0),\n vec2(-1.0, 3.0)\n );\n\n var out: VSOut;\n out.position = vec4(positions[vertexIndex], 0.0, 1.0);\n return out;\n}\n\nfn ringCoverage(distancePx: f32, radiusPx: f32, thicknessPx: f32) -> f32 {\n let aa = 1.0; // ~1px antialias band (device pixels)\n let halfT = max(0.5, thicknessPx * 0.5);\n let a0 = smoothstep(radiusPx - halfT - aa, radiusPx - halfT + aa, distancePx);\n let a1 = smoothstep(radiusPx + halfT - aa, radiusPx + halfT + aa, distancePx);\n return clamp(a0 - a1, 0.0, 1.0);\n}\n\n@fragment\nfn fsMain(@builtin(position) fragPos: vec4) -> @location(0) vec4 {\n let d = distance(fragPos.xy, u.center);\n\n let ring = ringCoverage(d, u.radius, u.thickness);\n let outline = ringCoverage(d, u.radius, u.thickness + 2.0);\n\n let cover = max(ring, outline);\n if (cover <= 0.0) {\n discard;\n }\n\n // Blend between outline and ring color based on relative coverage,\n // then apply total coverage as alpha.\n let t = clamp(select(0.0, ring / cover, cover > 0.0), 0.0, 1.0);\n let rgb = mix(u.outlineColor.rgb, u.color.rgb, t);\n let a = mix(u.outlineColor.a, u.color.a, t) * cover;\n return vec4(rgb, a);\n}\n\n",Xt=[1,1,1,1],$t=e=>Math.min(1,Math.max(0,e)),Ht=(e,t,n)=>Math.min(n,Math.max(t,0|e));const qt='// Reference line renderer (axis-aligned, instanced quads).\n//\n// Coordinate conventions:\n// - Instance position is provided in CANVAS-LOCAL CSS pixels (same coordinate space as pointer events).\n// - Plot rect is provided in DEVICE pixels (computed from grid margins + DPR).\n// - Line width and dash lengths are provided in CSS pixels and converted in-shader using DPR.\n//\n// Scissoring/clipping:\n// - The render coordinator is expected to set a scissor rect for the plot area before drawing.\n// - This shader simply draws full-height/full-width quads; clipping is handled by scissor.\n//\n// Dash semantics:\n// - lineDash is a repeating on/off sequence in CSS pixels, starting with "on" at t=0.\n// - Up to 8 dash entries are supported per line (truncated on CPU).\n//\n// Performance:\n// - Vertex stage expands each instance into a quad (2 triangles, 6 vertices).\n// - We intentionally avoid snapping to integer device pixels to prevent visible stepping/jiggle\n// while zooming; edge AA is handled in the fragment stage.\n\nstruct VSUniforms {\n canvasSize : vec2, // device pixels (canvas.width, canvas.height)\n plotOrigin : vec2, // device pixels (plotLeft, plotTop)\n plotSize : vec2, // device pixels (plotWidth, plotHeight)\n devicePixelRatio : f32,\n _pad0 : f32,\n};\n\n@group(0) @binding(0) var u : VSUniforms;\n\nstruct VSIn {\n // axisPos.x = axis (0 = vertical, 1 = horizontal)\n // axisPos.y = position in CANVAS-LOCAL CSS pixels (x for vertical, y for horizontal)\n @location(0) axisPos : vec2,\n\n // widthDashCount.x = lineWidth in CSS px\n // widthDashCount.y = dashCount (float, cast to u32)\n @location(1) widthDashCount : vec2,\n\n // dashMeta.x = dashTotal (CSS px)\n // dashMeta.y = reserved (unused)\n @location(2) dashMeta : vec2,\n\n @location(3) dash0_3 : vec4,\n @location(4) dash4_7 : vec4,\n\n // Premultiplied or straight alpha is fine; blending is handled by pipeline state.\n @location(5) color : vec4,\n};\n\nstruct VSOut {\n @builtin(position) position : vec4,\n\n // Distance along the line in CSS pixels (0..plotLengthCss).\n @location(0) alongCss : f32,\n\n // Packed dash metadata to avoid extra varyings.\n // dashInfo.x = dashCount (float, cast to u32)\n // dashInfo.y = dashTotal (CSS px)\n @location(1) @interpolate(flat) dashInfo : vec2,\n\n @location(2) @interpolate(flat) dash0_3 : vec4,\n @location(3) @interpolate(flat) dash4_7 : vec4,\n @location(4) @interpolate(flat) color : vec4,\n\n // Axis-aligned quad anti-aliasing (device pixels).\n // acrossDevice ranges [0..widthDevice] across the stroke thickness.\n @location(5) acrossDevice : f32,\n @location(6) @interpolate(flat) widthDevice : f32,\n};\n\nfn quadUv(vid : u32) -> vec2 {\n // Two triangles covering [0,1]x[0,1].\n // 0: (0,0) 1:(1,0) 2:(0,1) 3:(0,1) 4:(1,0) 5:(1,1)\n switch (vid) {\n case 0u: { return vec2(0.0, 0.0); }\n case 1u: { return vec2(1.0, 0.0); }\n case 2u: { return vec2(0.0, 1.0); }\n case 3u: { return vec2(0.0, 1.0); }\n case 4u: { return vec2(1.0, 0.0); }\n default: { return vec2(1.0, 1.0); }\n }\n}\n\n@vertex\nfn vsMain(in : VSIn, @builtin(vertex_index) vid : u32) -> VSOut {\n let uv = quadUv(vid);\n let dpr = max(1e-6, u.devicePixelRatio);\n // IMPORTANT: Do NOT snap reference lines to integer device pixels.\n // Snapping looks crisp at rest but causes visible "jiggle" / stepping while zooming because\n // the line position is continuously changing (data-space → screen-space), and rounding\n // quantizes that motion to adjacent pixels. We rely on analytic AA in the fragment stage\n // to keep strokes stable and reasonably crisp across DPRs.\n\n let axis = in.axisPos.x;\n let posCss = in.axisPos.y;\n let widthCss = max(0.0, in.widthDashCount.x);\n let widthDevice = max(1.0, widthCss * dpr);\n\n var xDevice : f32;\n var yDevice : f32;\n var alongCss : f32;\n var acrossDevice : f32;\n\n if (axis < 0.5) {\n // Vertical line at x = posCss (canvas-local CSS px), spanning plot height.\n let centerX = posCss * dpr;\n let startX = centerX - 0.5 * widthDevice;\n xDevice = startX + uv.x * widthDevice;\n yDevice = u.plotOrigin.y + uv.y * u.plotSize.y;\n alongCss = (uv.y * u.plotSize.y) / dpr;\n acrossDevice = uv.x * widthDevice;\n } else {\n // Horizontal line at y = posCss (canvas-local CSS px), spanning plot width.\n let centerY = posCss * dpr;\n let startY = centerY - 0.5 * widthDevice;\n xDevice = u.plotOrigin.x + uv.x * u.plotSize.x;\n yDevice = startY + uv.y * widthDevice;\n alongCss = (uv.x * u.plotSize.x) / dpr;\n acrossDevice = uv.y * widthDevice;\n }\n\n let clipX = (xDevice / u.canvasSize.x) * 2.0 - 1.0;\n let clipY = 1.0 - (yDevice / u.canvasSize.y) * 2.0;\n\n var out : VSOut;\n out.position = vec4(clipX, clipY, 0.0, 1.0);\n out.alongCss = alongCss;\n out.dashInfo = vec2(in.widthDashCount.y, in.dashMeta.x);\n out.dash0_3 = in.dash0_3;\n out.dash4_7 = in.dash4_7;\n out.color = in.color;\n out.acrossDevice = acrossDevice;\n out.widthDevice = widthDevice;\n return out;\n}\n\nfn dashValue(i : u32, d0 : vec4, d1 : vec4) -> f32 {\n switch (i) {\n case 0u: { return d0.x; }\n case 1u: { return d0.y; }\n case 2u: { return d0.z; }\n case 3u: { return d0.w; }\n case 4u: { return d1.x; }\n case 5u: { return d1.y; }\n case 6u: { return d1.z; }\n default: { return d1.w; }\n }\n}\n\n@fragment\nfn fsMain(in : VSOut) -> @location(0) vec4 {\n // Analytic edge anti-aliasing for axis-aligned quads (reduces shimmering during zoom).\n // This is a lightweight alternative to full MSAA for thin strokes.\n let edgeDist = min(in.acrossDevice, in.widthDevice - in.acrossDevice);\n // Slightly widen AA to reduce temporal shimmer on moving 1-2px strokes.\n // Keep conservative so lines remain reasonably crisp.\n let aa = max(fwidth(in.acrossDevice), 1e-3) * 1.25;\n let edgeCoverage = smoothstep(0.0, aa, edgeDist);\n var color = in.color;\n color.a = color.a * edgeCoverage;\n\n let dashCount = u32(round(in.dashInfo.x));\n let dashTotal = in.dashInfo.y;\n\n // IMPORTANT: derivative ops (fwidth) must execute in uniform control flow.\n // So compute the dash parameterization unconditionally (using a safe total) BEFORE any early-return.\n let dashTotalSafe = max(dashTotal, 1.0);\n let t = in.alongCss - floor(in.alongCss / dashTotalSafe) * dashTotalSafe;\n // Anti-alias dash edges along the line axis (CSS pixels).\n // This reduces shimmer during zoom for dashed reference lines without requiring MSAA.\n let dashAa = max(fwidth(t), 1e-3);\n\n // Solid line (no dash pattern).\n if (dashCount == 0u || dashTotal <= 0.0) {\n return color;\n }\n\n var acc = 0.0;\n var on = true;\n\n for (var i : u32 = 0u; i < 8u; i = i + 1u) {\n if (i >= dashCount) { break; }\n let seg = dashValue(i, in.dash0_3, in.dash4_7);\n if (seg <= 0.0) { continue; }\n\n if (t < acc + seg) {\n // IMPORTANT: Avoid `discard` for off segments.\n // Discard can cause temporal popping on moving dashed edges; prefer a smooth alpha mask.\n //\n // Fade in/out near dash boundaries for smooth edges. This produces coverage in [0..1]\n // within the current segment, going to 0 at segment boundaries.\n let inFromStart = smoothstep(0.0, dashAa, t - acc);\n let inFromEnd = smoothstep(0.0, dashAa, (acc + seg) - t);\n let segCoverage = min(inFromStart, inFromEnd);\n\n // On segments contribute alpha; off segments contribute 0 alpha (no discard).\n let dashMask = select(0.0, segCoverage, on);\n color.a = color.a * dashMask;\n return color;\n }\n\n acc = acc + seg;\n on = !on;\n }\n\n // Defensive fallback if the dash list is degenerate.\n // If we didn\'t find a segment (shouldn\'t happen), default to transparent (safer than solid).\n color.a = 0.0;\n return color;\n}\n',jt=e=>{if(!e||0===e.length)return{dashCount:0,dashTotal:0,values:new Array(8).fill(0)};const t=[];for(let n=0;n0&&t.push(i)}if(0===t.length)return{dashCount:0,dashTotal:0,values:new Array(8).fill(0)};const n=t.length%2==1?t.concat(t):t,i=Math.min(8,n.length),r=new Array(8).fill(0);let o=0;for(let e=0;e{if(n)throw new Error("ReferenceLineRenderer is disposed.")};return{prepare:(t,n)=>{if(p(),!Array.isArray(n))throw new Error("ReferenceLineRenderer.prepare: lines must be an array.");if(!(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))(t))throw new Error("ReferenceLineRenderer.prepare: gridArea dimensions must be finite numbers.");if(t.canvasWidth<=0||t.canvasHeight<=0)throw new Error("ReferenceLineRenderer.prepare: canvas dimensions must be positive.");if(t.left<0||t.right<0||t.top<0||t.bottom<0)throw new Error("ReferenceLineRenderer.prepare: gridArea margins must be non-negative.");const i=Number.isFinite(t.devicePixelRatio)&&t.devicePixelRatio>0?t.devicePixelRatio:1,r=t.left*i,o=t.top*i,a=t.canvasWidth-t.right*i-r,s=t.canvasHeight-t.bottom*i-o;if(!(a>0&&s>0))return void(m=0);const u=new Float32Array(8);if(u[0]=t.canvasWidth,u[1]=t.canvasHeight,u[2]=r,u[3]=o,u[4]=a,u[5]=s,u[6]=i,u[7]=0,ze(e,l,u),0===n.length)return void(m=0);if(!d||f{if(p(),0===m||!d)return;const i=Number.isFinite(t)?Math.max(0,Math.floor(t)):0,r=Math.max(0,m-i),o=null==n?r:Number.isFinite(n)?Math.max(0,Math.min(r,Math.floor(n))):r;0!==o&&(e.setPipeline(c),e.setBindGroup(0,u),e.setVertexBuffer(0,d),e.draw(6,o,0,i))},dispose:()=>{if(!n){n=!0;try{l.destroy()}catch{}if(d)try{d.destroy()}catch{}d=null,f=0,m=0}}}}const Jt="// annotationMarker.wgsl\n// Instanced annotation marker shader (circle SDF with optional stroke).\n//\n// Coordinate contract:\n// - Instance center is CANVAS-LOCAL CSS pixels (xCssPx, yCssPx)\n// - Instance size is diameter in CSS pixels (sizeCssPx)\n// - Uniform provides render target size in *device* pixels and DPR for CSS→device conversion.\n//\n// Draw call: draw(6, instanceCount) using triangle-list quad expansion in VS.\n\nstruct VSUniforms {\n viewportPx: vec2, // render target size in device pixels (width, height)\n dpr: f32, // device pixel ratio (CSS px -> device px)\n _pad0: f32,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct VSIn {\n // Center in CANVAS-LOCAL CSS pixels.\n @location(0) centerCssPx: vec2,\n // Marker diameter in CSS pixels.\n @location(1) sizeCssPx: f32,\n // Stroke width in CSS pixels (0 disables stroke).\n @location(2) strokeWidthCssPx: f32,\n // Colors are straight-alpha RGBA in 0..1.\n @location(3) fillRgba: vec4,\n @location(4) strokeRgba: vec4,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n // Local quad coordinates in [-1, 1]^2 (used for circle SDF).\n @location(0) local: vec2,\n // Half-size in device pixels (radius in screen space).\n @location(1) halfSizePx: f32,\n @location(2) strokeWidthPx: f32,\n @location(3) fillRgba: vec4,\n @location(4) strokeRgba: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fixed local corners for 2 triangles (triangle-list).\n let localCorners = array, 6>(\n vec2(-1.0, -1.0),\n vec2( 1.0, -1.0),\n vec2(-1.0, 1.0),\n vec2(-1.0, 1.0),\n vec2( 1.0, -1.0),\n vec2( 1.0, 1.0)\n );\n\n let corner = localCorners[vertexIndex];\n\n let dpr = select(1.0, vsUniforms.dpr, vsUniforms.dpr > 0.0);\n let centerPx = in.centerCssPx * dpr;\n let halfSizePx = 0.5 * max(0.0, in.sizeCssPx) * dpr;\n let strokeWidthPx = max(0.0, in.strokeWidthCssPx) * dpr;\n\n let posPx = centerPx + corner * halfSizePx;\n\n // Convert device pixels to clip-space with origin at top-left:\n // x: [0..w] -> [-1..1], y: [0..h] -> [1..-1]\n let clipX = (posPx.x / vsUniforms.viewportPx.x) * 2.0 - 1.0;\n let clipY = 1.0 - (posPx.y / vsUniforms.viewportPx.y) * 2.0;\n\n var out: VSOut;\n out.clipPosition = vec4(clipX, clipY, 0.0, 1.0);\n out.local = corner;\n out.halfSizePx = halfSizePx;\n out.strokeWidthPx = strokeWidthPx;\n out.fillRgba = in.fillRgba;\n out.strokeRgba = in.strokeRgba;\n return out;\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n if (in.halfSizePx <= 0.0) {\n discard;\n }\n\n // Circle SDF in normalized space: dist == 1 at the circle boundary.\n let dist = length(in.local);\n let aa = max(1e-6, fwidth(dist));\n\n // Coverage inside the circle.\n let outerCoverage = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, dist);\n if (outerCoverage <= 0.0) {\n discard;\n }\n\n // Optional stroke: compute inner radius in normalized units.\n let strokeNorm = clamp(in.strokeWidthPx / max(1e-6, in.halfSizePx), 0.0, 1.0);\n let inner = max(0.0, 1.0 - strokeNorm);\n let innerCoverage = 1.0 - smoothstep(inner - aa, inner + aa, dist);\n\n let fillCoverage = clamp(innerCoverage, 0.0, 1.0);\n let strokeCoverage = clamp(outerCoverage - innerCoverage, 0.0, 1.0);\n\n let fillA = clamp(in.fillRgba.a, 0.0, 1.0) * fillCoverage;\n let strokeA = clamp(in.strokeRgba.a, 0.0, 1.0) * strokeCoverage;\n let outA = fillA + strokeA;\n if (outA <= 0.0) {\n discard;\n }\n\n // Straight-alpha output: compute a weighted average RGB for correct blending.\n let rgb = (in.fillRgba.rgb * fillA + in.strokeRgba.rgb * strokeA) / outA;\n return vec4(rgb, outA);\n}\n\n",Kt=e=>Math.min(1,Math.max(0,e)),Qt=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))};function en(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=(null==t?void 0:t.sampleCount)??1,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),l=Ge(e,16,{label:"annotationMarkerRenderer/vsUniforms"}),u=new Float32Array(4),c=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}}]}),d=Ue(e,{label:"annotationMarkerRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:Jt,label:"annotationMarker.wgsl",buffers:[{arrayStride:48,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:Jt,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}},a);let f=null,m=0,p=new ArrayBuffer(0),h=new Float32Array(p);const g=()=>{if(n)throw new Error("AnnotationMarkerRenderer is disposed.")};return{prepare:({canvasWidth:t,canvasHeight:n,devicePixelRatio:i,instances:r})=>{if(g(),!Number.isFinite(t)||!Number.isFinite(n)||t<=0||n<=0)throw new Error("AnnotationMarkerRenderer.prepare: canvasWidth/canvasHeight must be positive finite numbers.");if(!Array.isArray(r))throw new Error("AnnotationMarkerRenderer.prepare: instances must be an array.");((t,n,i)=>{const r=Number.isFinite(t)&&t>0?t:1,o=Number.isFinite(n)&&n>0?n:1,a=Number.isFinite(i)&&i>0?i:1;u[0]=r,u[1]=o,u[2]=a,u[3]=0,ze(e,l,u)})(t,n,i),(e=>{if(e<=h.length)return;const t=Math.max(32,Qt(e));p=new ArrayBuffer(4*t),h=new Float32Array(p)})(12*r.length);const o=h;let a=0;for(let e=0;e{if(g(),!f||0===m)return;const i=Number.isFinite(t)?Math.max(0,Math.floor(t)):0,r=Math.max(0,m-i),o=null==n?r:Number.isFinite(n)?Math.max(0,Math.min(r,Math.floor(n))):r;0!==o&&(e.setPipeline(d),e.setBindGroup(0,c),e.setVertexBuffer(0,f),e.draw(6,o,0,i))},dispose:()=>{if(!n){if(n=!0,f)try{f.destroy()}catch{}f=null,m=0;try{l.destroy()}catch{}}}}}const tn=(e,t,n)=>Math.min(n,Math.max(t,e));const nn=(e,t,n)=>Math.min(n,Math.max(t,e)),rn=e=>nn(e,0,1),on=e=>Object.is(e,-0)?0:e;const an=new WeakMap,sn=e=>{const t="object"==typeof e&&null!==e?e:null;if(t&&an.has(t))return an.get(t);let n=!1;const i=s(e);for(let t=0;t{let n=0,i=s(e);for(;n>>1;l(e,r){const n=[];for(let t=0;te.s),t),r=i.barWidthPx,o=i.gapPx,a=i.clusterWidthPx;if(!(Number.isFinite(r)&&r>0))return null;const s=new Map;for(let e=0;e0&&Number.isFinite(s)){let e=-1;const o=e=>{if(!Number.isFinite(e))return!1;const n=e+s;return t>=n-h&&t{if(e<0||e>=p)return null;const t=l(m,e);if(!Number.isFinite(t))return null;const i=n.scale(t);return Number.isFinite(i)?i:null};for(let n=o-1;n>=0;n--){const i=a(n);if(null===i)continue;const o=i+s,l=o+r;if(l+h<=t)break;t>=o-h&&tt)break;t=0){const t=l(m,e),n=u(m,e),r=c(m,e),o=void 0!==r?[t,n,r]:[t,n];d.push({seriesIndex:i,dataIndex:e,point:o});continue}}}}let h=-1,g=null,b=o;const v=(e,t)=>{if(!Number.isFinite(t)||!(t{const i=l(m,e);if(!Number.isFinite(i))return null;const r=n.scale(i);if(!Number.isFinite(r))return null;const o=r-t;return o*o};for(;i>=0||r=0&&null===o(i);)i--;for(;r=p)break;const e=i>=0?o(i)??Number.POSITIVE_INFINITY:Number.POSITIVE_INFINITY,t=rb&&t>b)break;e<=t?(i>=0&&e<=b&&v(i,e),i--,rArray.isArray(e),dn=e=>cn(e)?e[0]:e.timestamp,fn=new WeakMap;function mn(e,t,n,i){if(0===t.length)return 0;const r=(e=>{const t=fn.get(e);if(void 0!==t)return t;const n=[];for(let t=0;te-t);let i=Number.POSITIVE_INFINITY;for(let e=1;e0&&t0?i:1;return fn.set(e,r),r})(t);let o=0;if(Number.isFinite(r)&&r>0){let e=null;for(let n=0;n0&&(o=a)}}(!(o>0)||!Number.isFinite(o))&&(o=(Number.isFinite(i??Number.NaN)?i:0)/Math.max(1,t.length));let a=0;const s=e.barWidth;if("number"==typeof s)a=Number.isFinite(s)?Math.max(0,s):0;else if("string"==typeof s){const e=(e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null})(s);a=null==e?0:o*(e=>Math.min(1,Math.max(0,e)))(e)}const l=Number.isFinite(e.barMinWidth)?Math.max(0,e.barMinWidth):0,u=Number.isFinite(e.barMaxWidth)?Math.max(0,e.barMaxWidth):Number.POSITIVE_INFINITY,c=Math.max(l,u);return a=Math.min(Math.max(a,l),c),Number.isFinite(a)?a:0}const pn=new WeakMap,hn=e=>{const t=pn.get(e);if(void 0!==t)return t;let n=Number.NEGATIVE_INFINITY;for(let t=0;t{let n=0,i=e.length;for(;n>>1;dn(e[r])0))return null;const a=i.invert(t);if(!Number.isFinite(a))return null;const s=o/2;let l=null,u=Number.POSITIVE_INFINITY;const c=(e,t,n,i)=>{if(Number.isFinite(i)){if(i{const t=(e=>cn(e)?e[1]:e.open)(e),i=(e=>cn(e)?e[2]:e.close)(e);if(!Number.isFinite(t)||!Number.isFinite(i))return!1;const o=r.scale(t),a=r.scale(i);if(!Number.isFinite(o)||!Number.isFinite(a))return!1;const s=Math.min(o,a),l=Math.max(o,a);return n>=s&&n<=l};for(let n=0;ns||d(o)&&c(n,e,o,u)}continue}const l=gn(r,a);for(let e=l-1;e>=0;e--){const o=r[e],a=dn(o),l=i.scale(a);if(!Number.isFinite(l))continue;if(ls||d(o)&&c(n,e,o,u)}for(let e=l;et+s)break;const u=Math.abs(t-l);u>s||d(o)&&c(n,e,o,u)}}return l}const vn=2*Math.PI,yn=e=>{if(!Number.isFinite(e))return 0;const t=e%vn;return t<0?t+vn:t};function xn(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,a=Number.isFinite(r.outer)?Math.max(0,r.outer):0;if(!(a>0))return null;const s=e-i.x,l=i.y-t,u=Math.hypot(s,l);if(!Number.isFinite(u)||u<=o||u>a)return null;const c=yn(Math.atan2(l,s)),d=n.series,f=d.data;let m=0,p=0;for(let e=0;e0&&!1!==t.visible&&(m+=n,p++)}if(!(m>0)||0===p)return null;const h="number"==typeof d.startAngle&&Number.isFinite(d.startAngle)?d.startAngle:90;let g=yn(h*Math.PI/180),b=0,v=0;for(let e=0;e0))continue;const o=g,a=1===p?g+vn:yn(g+r);g=yn(g+r);let s=a-o;s<0&&(s+=vn);let l=c-o;if(l<0&&(l+=vn),l<=s)return{seriesIndex:n.seriesIndex,dataIndex:e,slice:t}}return null}const wn=(e,t)=>{if(!Number.isFinite(t))throw new Error(`${e} must be a finite number. Received: ${String(t)}`)};function Mn(){let e=0,t=1,n=0,i=1;const r={domain:(n,i)=>(wn("domain min",n),wn("domain max",i),e=n,t=i,r),range:(e,t)=>(wn("range min",e),wn("range max",t),n=e,i=t,r),scale:r=>Number.isFinite(r)?e===t?(n+i)/2:n+(r-e)/(t-e)*(i-n):Number.NaN,invert:r=>Number.isFinite(r)?e===t?e:n===i?(e+t)/2:e+(r-n)/(i-n)*(t-e):Number.NaN};return r}function Fn(e,t){const n=getComputedStyle(e),i=n.position,r=n.overflow,o=(null==t?void 0:t.clip)??!1,a="static"===i,s=!o&&("hidden"===r||"scroll"===r||"auto"===r),l=a?e.style.position:null,u=s?e.style.overflow:null;a&&(e.style.position="relative"),s&&(e.style.overflow="visible");const c=document.createElement("div");c.style.position="absolute",c.style.inset="0",c.style.pointerEvents="none",c.style.overflow=o?"hidden":"visible",c.style.zIndex="10",e.appendChild(c);let d=!1;return{clear:()=>{d||c.replaceChildren()},addLabel:(e,t,n,i)=>{if(d)return document.createElement("span");const r=document.createElement("span");r.textContent=e,r.style.position="absolute",r.style.left=`${t}px`,r.style.top=`${n}px`,r.style.pointerEvents="none",r.style.userSelect="none",r.style.whiteSpace="nowrap",r.style.lineHeight="1",null!=(null==i?void 0:i.fontSize)&&(r.style.fontSize=`${i.fontSize}px`),null!=(null==i?void 0:i.color)&&(r.style.color=i.color);const o=(null==i?void 0:i.rotation)??0,a=(null==i?void 0:i.anchor)??"start",{translateX:s,originX:l}=(e=>{switch(e){case"start":return{translateX:"0%",originX:"0%"};case"middle":return{translateX:"-50%",originX:"50%"};case"end":return{translateX:"-100%",originX:"100%"}}})(a);return r.style.transformOrigin=`${l} 50%`,r.style.transform=`translateX(${s}) translateY(-50%) rotate(${o}deg)`,c.appendChild(r),r},dispose:()=>{if(!d){d=!0;try{c.remove()}finally{null!==l&&(e.style.position=l),null!==u&&(e.style.overflow=u)}}}}}const Nn=(e,t)=>{var n;return(null==(n=e.name)?void 0:n.trim())||`Series ${t+1}`},Cn=(e,t,n)=>{var i;const r=null==(i=e.color)?void 0:i.trim();if(r)return r;const o=n.colorPalette;return o.length>0?o[t%o.length]??"#000000":"#000000"},Sn=(e,t)=>(null==e?void 0:e.trim())||`Slice ${t+1}`,An=(e,t,n,i)=>{const r=null==e?void 0:e.trim();if(r)return r;const o=i.colorPalette,a=o.length;return a>0?o[(t+n)%a]??"#000000":"#000000"},In=(e,t,n)=>nn?n:e;function Pn(e){const t="static"===getComputedStyle(e).position,n=t?e.style.position:null;t&&(e.style.position="relative");const i=document.createElement("div");i.style.position="absolute",i.style.left="0",i.style.top="0",i.style.pointerEvents="none",i.style.userSelect="none",i.style.boxSizing="border-box",i.style.zIndex="var(--chartgpu-tooltip-z, 10)",i.style.padding="var(--chartgpu-tooltip-padding, 6px 8px)",i.style.borderRadius="var(--chartgpu-tooltip-radius, 8px)",i.style.borderStyle="solid",i.style.borderWidth="var(--chartgpu-tooltip-border-width, 1px)",i.style.borderColor="var(--chartgpu-tooltip-border, rgba(224,224,224,0.35))",i.style.boxShadow="var(--chartgpu-tooltip-shadow, 0 6px 18px rgba(0,0,0,0.35))",i.style.maxWidth="var(--chartgpu-tooltip-max-width, min(320px, 100%))",i.style.overflow="hidden",i.style.fontFamily='var(--chartgpu-tooltip-font-family, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji")',i.style.fontSize="var(--chartgpu-tooltip-font-size, 12px)",i.style.lineHeight="var(--chartgpu-tooltip-line-height, 1.2)",i.style.color="var(--chartgpu-tooltip-color, #e0e0e0)",i.style.background="var(--chartgpu-tooltip-bg, rgba(26,26,46,0.95))",i.style.whiteSpace="normal",i.style.opacity="0",i.style.transitionProperty="opacity",i.style.transitionDuration="140ms",i.style.transitionTimingFunction="ease",i.style.willChange="opacity",i.style.display="none",i.style.visibility="hidden",i.setAttribute("role","tooltip"),e.appendChild(i);let r=!1,o=0,a=null,s=null;const l=()=>{null!=a&&(window.clearTimeout(a),a=null),null!=s&&(window.cancelAnimationFrame(s),s=null)};return{show:(t,n,a)=>{if(r)return;o+=1,l();const u="none"===i.style.display||"hidden"===i.style.visibility;i.innerHTML=a,i.style.display="block",i.style.visibility="hidden";const{width:c,height:d}=(()=>{const e=i.style.visibility;i.style.visibility="hidden";const t=i.offsetWidth,n=i.offsetHeight;return i.style.visibility=e,{width:t,height:n}})(),f=e.clientWidth,m=e.clientHeight;let p=t+12,h=n+12;if(p+c>f-8&&(p=t-12-c),h+d>m-8&&(h=n-12-d),p=In(p,8,f-8-c),h=In(h,8,m-8-d),i.style.left=`${p}px`,i.style.top=`${h}px`,i.style.visibility="visible",u){i.style.opacity="0";const e=o;s=window.requestAnimationFrame(()=>{s=null,!r&&e===o&&(i.style.opacity="1")})}else i.style.opacity="1"},hide:()=>{if(r)return;if(o+=1,l(),"none"===i.style.display||"hidden"===i.style.visibility)return i.style.opacity="0",i.style.visibility="hidden",void(i.style.display="none");i.style.opacity="0";const e=o;a=window.setTimeout(()=>{a=null,!r&&e===o&&(i.style.visibility="hidden",i.style.display="none")},190)},dispose:()=>{if(!r){r=!0;try{l(),i.remove()}finally{null!==n&&(e.style.position=n)}}}}}function Rn(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function En(e){if(!Number.isFinite(e))return"—";const t=(Object.is(e,-0)?0:e).toFixed(2).replace(/\.?0+$/,"");return"-0"===t?"0":t}function Bn(e){const t=e.seriesName.trim();return t.length>0?t:`Series ${e.seriesIndex+1}`}function Tn(e){const t=e.trim();return 0===t.length?"#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 Dn(e){return 5===e.length}function Un(e,t){const n=Rn(Bn(e)),i=Rn(t);return['
','',``,`${n}`,"",`${i}`,"
"].join("")}function kn(e){const[,t,n,i,r]=e.value,o=Rn(Bn(e)),a=Rn(Tn(e.color)),s=En(t),l=En(r),u=En(i),c=En(n),d=n>t,f=d?"▲":"▼",m=d?"#22c55e":"#ef4444",p=function(e,t){if(!Number.isFinite(e)||!Number.isFinite(t)||0===e)return"—";const n=(t-e)/e*100;return Number.isFinite(n)?`${n>0?"+":""}${n.toFixed(2)}%`:"—"}(t,n),h=Rn(`O: ${s} H: ${l} L: ${u} C: ${c}`),g=Rn(f),b=Rn(p),v=Rn(m);return['
','
',``,`${o}`,"
",`
${h}
`,'
',`${g}`,`${b}`,"
","
"].join("")}function Gn(e){return Dn(e.value)?function(e){return kn(e)}(e):Un(e,En(e.value[1]))}function zn(e){return 0===e.length?"":`
${Rn(`x: ${En(e[0].value[0])}`)}
${e.map(e=>Dn(e.value)?kn(e):Un(e,En(e.value[1]))).join('
')}`}const Vn=e=>Number.isFinite(e)?e:0;function Ln(){const e=new Map;return{animate:function(t,n,i,r,o,a){const s=Symbol("Animation");if(Array.isArray(t)||Array.isArray(n)){if(!Array.isArray(t)||!Array.isArray(n))throw new Error('Array animation requires both "from" and "to" to be arrays');if(t.length!==n.length)throw new Error(`Array animation length mismatch: from.length=${t.length}, to.length=${n.length}`);const l=new Array(t.length);return e.set(s,{kind:"array",from:t,to:n,duration:i,easing:r,onUpdate:o,onComplete:a,startTime:null,out:l}),s}return e.set(s,{kind:"scalar",from:t,to:n,duration:i,easing:r,onUpdate:o,onComplete:a,startTime:null}),s},cancel:function(t){e.delete(t)},cancelAll:function(){e.clear()},update:function(t){var n;const i=(e=>Number.isFinite(e)?e:null)(t);if(null===i)return;const r=Array.from(e.keys());for(const t of r){const r=e.get(t);if(!r)continue;const o=r.startTime??i;null===r.startTime&&e.set(t,{...r,startTime:o});const a=Vn(r.duration),s=Math.max(0,i-o),l=a<=0||s>=a,u=a<=0?1:s/a,c=l?1:r.easing(u);if("scalar"===r.kind){const n=r.from+(r.to-r.from)*c;if(r.onUpdate(n),!e.has(t))continue}else{const n=r.out.length;for(let e=0;eNumber.isNaN(e)||e<=0?0:e>=1?1:e;function On(e){return Wn(e)}function _n(e){const t=1-Wn(e);return 1-t*t*t}function Yn(e){const t=Wn(e);if(t<.5)return 4*t*t*t;const n=-2*t+2;return 1-n*n*n/2}function Xn(e){const t=Wn(e),n=7.5625,i=2.75;if(t<1/i)return n*t*t;if(t<2/i){const e=t-1.5/i;return n*e*e+.75}if(t<2.5/i){const e=t-2.25/i;return n*e*e+.9375}const r=t-2.625/i;return n*r*r+.984375}function $n(e){switch(e){case"linear":default:return On;case"cubicOut":return _n;case"cubicInOut":return Yn;case"bounceOut":return Xn}}const Hn=function(e){return typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement},qn=864e5,jn=30*qn,Zn=365*qn,Jn=e=>"number"==typeof e&&Number.isFinite(e)?e:null,Kn=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0,Qn=e=>{throw new Error(`RenderCoordinator: unreachable value: ${String(e)}`)},ei=e=>Array.isArray(e),ti=e=>{const t=s(e);if(0===t)return{x:[],y:[]};const n=new Array(t),i=new Array(t);let r,o=!1;for(let a=0;a{const n=f(t);if(!n)return e;if(!e)return n;let i=Math.min(e.xMin,n.xMin),r=Math.max(e.xMax,n.xMax),o=Math.min(e.yMin,n.yMin),a=Math.max(e.yMax,n.yMax);return i===r&&(r=i+1),o===a&&(a=o+1),{xMin:i,xMax:r,yMin:o,yMax:a}},ii=(e,t)=>{if(0===t.length)return e;let n=(null==e?void 0:e.xMin)??Number.POSITIVE_INFINITY,i=(null==e?void 0:e.xMax)??Number.NEGATIVE_INFINITY,r=(null==e?void 0:e.yMin)??Number.POSITIVE_INFINITY,o=(null==e?void 0:e.yMax)??Number.NEGATIVE_INFINITY;for(let e=0;ei&&(i=s),lo&&(o=u))}return Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(o)?(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o}):e},ri=(e,t)=>{let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(let a=0;ai&&(i=e.xMax),e.yMino&&(o=e.yMax);continue}}const f=c.rawBounds;if(f){const e=f;if(Number.isFinite(e.xMin)&&Number.isFinite(e.xMax)&&Number.isFinite(e.yMin)&&Number.isFinite(e.yMax)){e.xMini&&(i=e.xMax),e.yMino&&(o=e.yMax);continue}}if("candlestick"===c.type){const e=c.rawData??c.data;for(let t=0;ti&&(i=e),lo&&(o=u)}else{const e=a.timestamp,t=a.low,s=a.high;if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s))continue;const l=Math.min(t,s),u=Math.max(t,s);ei&&(i=e),lo&&(o=u)}}continue}const m=c.data,p=s(m);for(let e=0;ei&&(i=t),ao&&(o=a))}}return Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(o)?(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o}):{xMin:0,xMax:1,yMin:0,yMax:1}},oi=(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 e=n;n=i,i=e}return{min:n,max:i}},ai=(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,a=n.height;if(!Number.isFinite(o)||!Number.isFinite(a))throw new Error(`RenderCoordinator: Invalid canvas dimensions: width=${o}, height=${a}. Canvas must be initialized with finite dimensions before rendering.`);const s=Math.max(1,Math.floor(o)),l=Math.max(1,Math.floor(a)),u=Number.isFinite(t.grid.left)?t.grid.left:0,c=Number.isFinite(t.grid.right)?t.grid.right:0,d=Number.isFinite(t.grid.top)?t.grid.top:0,f=Number.isFinite(t.grid.bottom)?t.grid.bottom:0;return{left:Math.max(0,u),right:Math.max(0,c),top:Math.max(0,d),bottom:Math.max(0,f),canvasWidth:s,canvasHeight:l,devicePixelRatio:r}},si=(e,t)=>{const n=_(e);if(!n)return e;const i=Math.max(0,Math.min(1,n[3]*t));return(e=>`rgba(${Math.max(0,Math.min(255,Math.round(255*e[0])))},${Math.max(0,Math.min(255,Math.round(255*e[1])))},${Math.max(0,Math.min(255,Math.round(255*e[2])))},${Math.max(0,Math.min(1,e[3]))})`)([n[0],n[1],n[2],i])},li=e=>Math.min(1,Math.max(0,e)),ui=(e,t,n)=>Math.min(n,Math.max(t,0|e)),ci=(e,t,n)=>e+(t-e)*li(n),di=(e,t,n)=>oi(ci(e.min,t.min,n),ci(e.max,t.max,n)),fi=(e,t)=>(e+1)/2*t,mi=(e,t)=>(1-e)/2*t,pi=A,hi=(e,t)=>{if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"!=typeof e)return null;const n=e.trim();if(0===n.length)return null;if(n.endsWith("%")){const e=Number.parseFloat(n.slice(0,-1));return Number.isFinite(e)?e/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},gi=(e,t,n)=>{const i=(null==e?void 0:e[0])??"50%",r=(null==e?void 0:e[1])??"50%",o=hi(i,t),a=hi(r,n);return{x:Number.isFinite(o)?o:.5*t,y:Number.isFinite(a)?a:.5*n}},bi=(e,t)=>{if(null==e)return{inner:0,outer:.7*t};if((e=>Array.isArray(e))(e)){const n=hi(e[0],t),i=hi(e[1],t),r=Math.max(0,Number.isFinite(n)?n:0),o=Math.max(r,Number.isFinite(i)?i:.7*t);return{inner:r,outer:Math.min(t,o)}}const n=hi(e,t),i=Math.max(0,Number.isFinite(n)?n:.7*t);return{inner:0,outer:Math.min(t,i)}},vi=e=>String(Math.trunc(e)).padStart(2,"0"),yi=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],xi=(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(),a=n.getHours(),s=n.getMinutes();return t{const i=Math.max(1,Math.floor(n)),r=new Array(i);for(let n=0;n{const n=ri(e.series,t),i=Kn(e.xAxis.min)??n.xMin,r=Kn(e.xAxis.max)??n.xMax;return oi(i,r)},Fi=(e,t,n)=>{const i=Kn(e.yAxis.min),r=Kn(e.yAxis.max);if(void 0!==i&&void 0!==r)return oi(i,r);let o;o="visible"===(e.yAxis.autoBounds??"visible")&&n?n:ri(e.series,t);const a=i??o.yMin,s=r??o.yMax;return oi(a,s)},Ni=(e,t)=>{if(!t)return{...e,spanFraction:1};const n=e.max-e.min;if(!Number.isFinite(n)||0===n)return{...e,spanFraction:1};const i=t.start,r=t.end,o=e.min+i/100*n,a=e.min+r/100*n,s=oi(o,a),l=(r-i)/100,u=Number.isFinite(l)?Math.max(0,Math.min(1,l)):1;return{min:s.min,max:s.max,spanFraction:u}},Ci=e=>{if(!1===e||null==e)return null;const t=!0===e?{}:e;if(!t)return null;const n=t.duration??300,i=t.delay??0;return{durationMs:Number.isFinite(n)?Math.max(0,n):300,delayMs:Number.isFinite(i)?Math.max(0,i):0,easing:$n(t.easing)}},Si=(e,t,n,i,r)=>{const o=e.point,a=pi(o)?o[0]:o.timestamp,s=pi(o)?o[1]:o.open,l=pi(o)?o[2]:o.close;if(!Number.isFinite(a)||!Number.isFinite(s)||!Number.isFinite(l))return null;const u=(s+l)/2,c=t.scale(a),d=n.scale(u);if(!Number.isFinite(c)||!Number.isFinite(d))return null;const f=i.left+c,m=i.top+d,p=Hn(r)?r.offsetLeft+f:f,h=Hn(r)?r.offsetTop+m:m;return Number.isFinite(p)&&Number.isFinite(h)?{x:p,y:h}:null},Ai=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;in&&(n=i))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t){const t=e.target.closest("[data-series-index]");if(t){const e=parseInt(t.dataset.seriesIndex,10);if(!isNaN(e)){const i=t.dataset.sliceIndex;if(void 0!==i){const t=parseInt(i,10);if(!isNaN(t))return void n(e,t)}n(e)}}}),a.addEventListener("keydown",e=>{if("Enter"===e.key||" "===e.key){const t=e.target.closest("[data-series-index]");if(t){e.preventDefault();const i=parseInt(t.dataset.seriesIndex,10);if(!isNaN(i)){const e=t.dataset.sliceIndex;if(void 0!==e){const t=parseInt(e,10);if(!isNaN(t))return void n(i,t)}n(i)}}}})),(e=>{switch(o.style.top="",o.style.right="",o.style.bottom="",o.style.left="",o.style.maxWidth="",a.style.flexDirection="",a.style.flexWrap="",a.style.alignItems="",e){case"right":return o.style.top="8px",o.style.right="8px",o.style.maxWidth="40%",a.style.flexDirection="column",a.style.flexWrap="nowrap",void(a.style.alignItems="flex-start");case"left":return o.style.top="8px",o.style.left="8px",o.style.maxWidth="40%",a.style.flexDirection="column",a.style.flexWrap="nowrap",void(a.style.alignItems="flex-start");case"top":return o.style.top="8px",o.style.left="8px",o.style.right="8px",a.style.flexDirection="row",a.style.flexWrap="wrap",void(a.style.alignItems="center");case"bottom":o.style.bottom="8px",o.style.left="8px",o.style.right="8px",a.style.flexDirection="row",a.style.flexWrap="wrap",a.style.alignItems="center"}})(t),e.appendChild(o);let s=!1;return{update:(e,t)=>{if(s)return;o.style.color=t.textColor,o.style.background=t.backgroundColor,o.style.borderColor=t.axisLineColor,o.style.fontFamily=t.fontFamily,o.style.fontSize=`${t.fontSize}px`;const i=[];for(let r=0;r{if(!s){s=!0;try{o.remove()}finally{null!==r&&(e.style.position=r)}}}}}(x,null==(r=t.legend)?void 0:r.position,(e,t)=>{if(P)return;const n=R.series;if(e<0||e>=n.length)return;const i=n[e];if(!i)return;if(void 0!==t&&"pie"===i.type){const r=i.data;if(t<0||t>=r.length)return;const o=r.map((e,n)=>n===t?{...e,visible:!1===e.visible}:e),a=n.map((t,n)=>n===e?{...t,data:o}:t);return void wn({...R,series:a})}const r=n.map((t,n)=>n===e?{...t,visible:!1===t.visible}:t);wn({...R,series:r})}):null,A=(()=>{if(typeof document>"u")return null;try{return document.createElement("canvas").getContext("2d")}catch{return null}})(),I=A?new Map:null;let P=!1,R=t,E=t.series.length,B="pending",T=0;const D=Ln();let z=null,V=!1;const L=Ln();let W=null,O=1,$=null;const j={cartesianDataBySeriesIndex:[],pieDataBySeriesIndex:[]},Z=()=>{j.cartesianDataBySeriesIndex.length=0,j.pieDataBySeriesIndex.length=0},J=(e,t,n,i,r)=>{if(0===n)return r??[];const o=r&&r.length===n?r:(()=>{const e=new Array(n);for(let i=0;i{var r,o;const a=e.data,s=t.data;if(a.length!==s.length)return t;const l=s.length,u=i&&i.length===l?i:(()=>{const e=new Array(l);for(let t=0;t{if(e.length!==t.length)return t;const r=new Array(t.length);for(let o=0;o2e4){r[o]=l;continue}const m=(null==i?void 0:i.cartesianDataBySeriesIndex[o])??null,p=J(u,c,d,n,m);p?(i&&(i.cartesianDataBySeriesIndex[o]=p),r[o]={...l,data:p}):r[o]=l}return r},te=new Set,fe=new Set;let he=new Array(t.series.length).fill(null),ge=new Array(t.series.length).fill(null),be=R.series,ve=R.series,ye=null;const xe=()=>{ye=(e=>{if("visible"!==(e.yAxis.autoBounds??"visible"))return!1;const t=Kn(e.yAxis.min),n=Kn(e.yAxis.max);return!(void 0!==t&&void 0!==n)})(R)?(e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;in&&(n=l)}continue}const o=r.data,a=s(o);for(let e=0;en&&(n=i))}}return Number.isFinite(t)&&Number.isFinite(n)?(t===n&&(n=t+1),{xMin:0,xMax:1,yMin:t,yMax:n}):{xMin:0,xMax:1,yMin:0,yMax:1}})(ve):null};let we=[],Me=!1,Fe=null,Te=null,De=null,ke=!1,Ve=!1;const Le=new Map;let _e=new Array(R.series.length).fill("unknown");const Ye=new Set;let Xe=x&&!1!==(null==(o=R.tooltip)?void 0:o.show)?Pn(x):null,He=null,qe=null,je=null;const Je=(e,t,n,i)=>{null==Xe||Xe.show(e,t,n)},Ke=()=>{null==Xe||Xe.hide()},Qe=()=>{He=null,qe=null,je=null,Ke()};var et,nt;et=R.series,nt=R.theme,null==F||F.update(et,nt);let it=function(e){const t=new Map;let n=!1;const i=()=>{if(n)throw new Error("DataStore is disposed.")},r=e=>{i();const n=t.get(e);if(!n)throw new Error(`Series ${e} has no data. Call setSeries(${e}, data) first.`);return n};return{setSeries:(n,r,o)=>{i();const a=(null==o?void 0:o.xOffset)??0,l=s(r),u=((e,t)=>{const n=s(e);if(0===n)return new Float32Array(0);const i=new ArrayBuffer(2*n*4),r=new Float32Array(i);return d(r,0,e,0,n,t),r})(r,a),c=v(u),f=h(u.byteLength),m=Math.max(4,f),p=t.get(n);if(p&&p.pointCount===l&&p.hash32===c)return;let b=(null==p?void 0:p.buffer)??null,y=(null==p?void 0:p.capacityBytes)??0;if(!b||m>y){const t=e.limits.maxBufferSize;if(m>t)throw new Error(`DataStore.setSeries(${n}): required buffer size ${m} exceeds device.limits.maxBufferSize (${t}).`);if(b)try{b.destroy()}catch{}const i=g(y,m);y=i>t?m:i,b=e.createBuffer({size:y,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})}u.byteLength>0&&e.queue.writeBuffer(b,0,u.buffer,u.byteOffset,u.byteLength);const x=new Float32Array(y/4);x.set(u),t.set(n,{buffer:b,capacityBytes:y,pointCount:l,hash32:c,xOffset:a,stagingBuffer:x})},appendSeries:(n,o)=>{i();const a=s(o);if(0===a)return;const l=r(n),u=l.pointCount,c=u+a,f=h(2*c*4),m=Math.max(4,f);let p=l.buffer,y=l.capacityBytes,x=l.stagingBuffer;const w=e.limits.maxBufferSize;if(m>y){if(m>w)throw new Error(`DataStore.appendSeries(${n}): required buffer size ${m} exceeds device.limits.maxBufferSize (${w}).`);try{p.destroy()}catch{}const i=g(y,m);y=i>w?m:i,p=e.createBuffer({size:y,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});const r=new Float32Array(y/4);r.set(x.subarray(0,2*u)),d(r,2*u,o,0,a,l.xOffset);const s=r.subarray(0,2*c);return s.byteLength>0&&e.queue.writeBuffer(p,0,s.buffer,s.byteOffset,s.byteLength),void t.set(n,{buffer:p,capacityBytes:y,pointCount:c,hash32:v(s),xOffset:l.xOffset,stagingBuffer:r})}d(x,2*u,o,0,a,l.xOffset);const M=x.subarray(2*u,2*c);if(M.byteLength>0){const t=2*u*4;e.queue.writeBuffer(p,t,M.buffer,M.byteOffset,M.byteLength)}const F=new Uint32Array(M.buffer,M.byteOffset,M.byteLength/4),N=b(l.hash32,F);t.set(n,{buffer:p,capacityBytes:y,pointCount:c,hash32:N,xOffset:l.xOffset,stagingBuffer:x})},removeSeries:e=>{i();const n=t.get(e);if(n){try{n.buffer.destroy()}catch{}t.delete(e)}},getSeriesBuffer:e=>r(e).buffer,getSeriesPointCount:e=>r(e).pointCount,dispose:()=>{if(!n){n=!0;for(const e of t.values())try{e.buffer.destroy()}catch{}t.clear()}}}}(a);const rt=function(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),l=Ge(e,64,{label:"gridRenderer/vsUniforms"}),u=Ge(e,16,{label:"gridRenderer/fsUniforms"}),c=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}},{binding:1,resource:{buffer:u}}]}),d=Ue(e,{label:"gridRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:Be,label:"grid.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:Be,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:o}},a);let f=null,m=null,p=[];const h=()=>{if(n)throw new Error("GridRenderer is disposed.")};return{prepare:(t,n)=>{h();const i=null!=n&&"object"==typeof n&&("lineCount"in n||"color"in n||"append"in n),r=i?n:void 0,o=i?null==r?void 0:r.lineCount:n,a=(null==o?void 0:o.horizontal)??5,s=(null==o?void 0:o.vertical)??6,u=(null==r?void 0:r.color)??"rgba(255,255,255,0.15)",c=!0===(null==r?void 0:r.append);if(a<0||s<0)throw new Error("GridRenderer.prepare: line counts must be non-negative.");if(!(Number.isFinite(t.left)&&Number.isFinite(t.right)&&Number.isFinite(t.top)&&Number.isFinite(t.bottom)&&Number.isFinite(t.canvasWidth)&&Number.isFinite(t.canvasHeight)))throw new Error("GridRenderer.prepare: gridArea dimensions must be finite numbers.");if(t.canvasWidth<=0||t.canvasHeight<=0)throw new Error("GridRenderer.prepare: canvas dimensions must be positive.");if(0===a&&0===s)return void(c||(m=null,p=[]));const d=((e,t,n)=>{const{left:i,right:r,top:o,bottom:a,canvasWidth:s,canvasHeight:l}=e,u=Number.isFinite(e.devicePixelRatio)&&e.devicePixelRatio>0?e.devicePixelRatio:1,c=i*u,d=s-r*u,f=o*u,m=l-a*u,p=d-c,h=m-f,g=new Float32Array(2*(t+n)*2);let b=0;for(let e=0;e0&&p.length>0){v=m.byteLength;const e=new Float32Array(m.length+d.length);e.set(m,0),e.set(d,m.length),m=e,p=p.concat([{vertexOffsetBytes:v,vertexCount:g,rgba:b}])}else m=d,p=[{vertexOffsetBytes:0,vertexCount:g,rgba:b}];const y=m.byteLength,x=Math.max(4,y);if(!f||f.size{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})();ze(e,l,w)},render:t=>{if(h(),0!==p.length&&f){t.setPipeline(d),t.setBindGroup(0,c);for(const n of p){const i=new ArrayBuffer(16);new Float32Array(i).set([n.rgba[0],n.rgba[1],n.rgba[2],n.rgba[3]]),ze(e,u,i),t.setVertexBuffer(0,f,n.vertexOffsetBytes),t.draw(n.vertexCount)}}},dispose:()=>{if(!n){n=!0;try{l.destroy()}catch{}try{u.destroy()}catch{}if(f)try{f.destroy()}catch{}f=null,m=null,p=[]}}}}(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),ot=We(a,{targetFormat:m,pipelineCache:y}),at=We(a,{targetFormat:m,pipelineCache:y}),st=_t(a,{targetFormat:m,pipelineCache:y});st.setVisible(!1);const lt=function(e,t){let n=!1,i=!0;const r=(null==t?void 0:t.targetFormat)??"bgra8unorm",o=(null==t?void 0:t.sampleCount)??1,a=Number.isFinite(o)?Math.max(1,Math.floor(o)):1,s=null==t?void 0:t.pipelineCache,l=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),u=Ge(e,48,{label:"highlightRenderer/uniforms"}),c=e.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:u}}]}),d=Ue(e,{label:"highlightRenderer/pipeline",bindGroupLayouts:[l],vertex:{code:Yt,label:"highlight.wgsl"},fragment:{code:Yt,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:a}},s);let f=0,m=0,p={x:0,y:0,w:0,h:0},h=!1;const g=()=>{if(n)throw new Error("HighlightRenderer is disposed.")};return{prepare:(t,n,i)=>{if(g(),!Number.isFinite(t.centerDeviceX)||!Number.isFinite(t.centerDeviceY))throw new Error("HighlightRenderer.prepare: point center must be finite.");if(!Number.isFinite(t.canvasWidth)||!Number.isFinite(t.canvasHeight)||t.canvasWidth<=0||t.canvasHeight<=0)throw new Error("HighlightRenderer.prepare: canvasWidth/canvasHeight must be positive finite numbers.");if(!(e=>Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&Number.isFinite(e.h))(t.scissor))throw new Error("HighlightRenderer.prepare: scissor must be finite.");if(!Number.isFinite(i)||i<0)throw new Error("HighlightRenderer.prepare: size must be a finite non-negative number.");const r=t.devicePixelRatio,o=i*(Number.isFinite(r)&&r>0?r:1),a=Math.max(1,1.5*o),s=Math.max(1,Math.round(Math.max(2,.25*a))),l=_(n)??Xt,c=(e=>{const t=Number.isFinite(1.25)?1.25:1;return[$t(e[0]*t),$t(e[1]*t),$t(e[2]*t),$t(e[3])]})(l),d=(e=>.2126*e[0]+.7152*e[1]+.0722*e[2])(l)>.7?[0,0,0,.9]:[1,1,1,.9],b=new ArrayBuffer(48);new Float32Array(b).set([t.centerDeviceX,t.centerDeviceY,a,s,c[0],c[1],c[2],1,d[0],d[1],d[2],d[3]]),ze(e,u,b),f=t.canvasWidth,m=t.canvasHeight;const v=Ht(Math.floor(t.scissor.x),0,Math.max(0,t.canvasWidth)),y=Ht(Math.floor(t.scissor.y),0,Math.max(0,t.canvasHeight)),x=Ht(Math.ceil(t.scissor.x+t.scissor.w),0,Math.max(0,t.canvasWidth)),w=Ht(Math.ceil(t.scissor.y+t.scissor.h),0,Math.max(0,t.canvasHeight));p={x:v,y,w:Math.max(0,x-v),h:Math.max(0,w-y)},h=!0},render:e=>{g(),i&&h&&(f<=0||m<=0||0===p.w||0===p.h||(e.setScissorRect(p.x,p.y,p.w,p.h),e.setPipeline(d),e.setBindGroup(0,c),e.draw(3),e.setScissorRect(0,0,f,m)))},setVisible:e=>{g(),i=!!e},dispose:()=>{if(!n){n=!0;try{u.destroy()}catch{}f=0,m=0,p={x:0,y:0,w:0,h:0},h=!1}}}}(a,{targetFormat:m,pipelineCache:y});lt.setVisible(!1);const ut=Zt(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),ct=en(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),ft=Zt(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),mt=en(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),pt=function(e){const{device:t,targetFormat:n}=e,i={mainColorTexture:null,mainColorView:null,mainResolveTexture:null,mainResolveView:null,overlayMsaaTexture:null,overlayMsaaView:null,overlayBlitBindGroup:null,overlayTargetsWidth:0,overlayTargetsHeight:0,overlayTargetsFormat:null},r=t.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}}]}),o=Ue(t,{label:"textureManager/overlayBlitPipeline",bindGroupLayouts:[r],vertex:{code:Dt,label:"textureManager/overlayBlit.wgsl"},fragment:{code:Dt,label:"textureManager/overlayBlit.wgsl",formats:n},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:4}},e.pipelineCache);let a=null;return{ensureTextures:function(e,o){const s=Number.isFinite(e)?Math.max(1,Math.floor(e)):1,l=Number.isFinite(o)?Math.max(1,Math.floor(o)):1;i.mainColorTexture&&i.mainResolveTexture&&i.overlayMsaaTexture&&i.overlayBlitBindGroup&&i.overlayTargetsWidth===s&&i.overlayTargetsHeight===l&&i.overlayTargetsFormat===n||(Ut(i.mainColorTexture),Ut(i.mainResolveTexture),Ut(i.overlayMsaaTexture),i.mainColorTexture=t.createTexture({label:"textureManager/mainColorTexture",size:{width:s,height:l},sampleCount:4,format:n,usage:GPUTextureUsage.RENDER_ATTACHMENT}),i.mainColorView=i.mainColorTexture.createView(),i.mainResolveTexture=t.createTexture({label:"textureManager/mainResolveTexture",size:{width:s,height:l},format:n,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),i.mainResolveView=i.mainResolveTexture.createView(),i.overlayMsaaTexture=t.createTexture({label:"textureManager/annotationOverlayMsaaTexture",size:{width:s,height:l},sampleCount:4,format:n,usage:GPUTextureUsage.RENDER_ATTACHMENT}),i.overlayMsaaView=i.overlayMsaaTexture.createView(),i.overlayBlitBindGroup=t.createBindGroup({label:"textureManager/overlayBlitBindGroup",layout:r,entries:[{binding:0,resource:i.mainResolveView}]}),i.overlayTargetsWidth=s,i.overlayTargetsHeight=l,i.overlayTargetsFormat=n,a=null)},getState:function(){return a||(a={mainColorView:i.mainColorView,mainResolveView:i.mainResolveView,overlayMsaaView:i.overlayMsaaView,overlayBlitBindGroup:i.overlayBlitBindGroup,overlayBlitPipeline:o,msaaSampleCount:4,mainSceneMsaaSampleCount:4}),a},dispose:function(){Ut(i.mainColorTexture),Ut(i.mainResolveTexture),Ut(i.overlayMsaaTexture),i.mainColorTexture=null,i.mainColorView=null,i.mainResolveTexture=null,i.mainResolveView=null,i.overlayMsaaTexture=null,i.overlayMsaaView=null,i.overlayBlitBindGroup=null,i.overlayTargetsWidth=0,i.overlayTargetsHeight=0,i.overlayTargetsFormat=null,a=null}}}({device:a,targetFormat:m,pipelineCache:y}),ht=ai(e,R),gt=Hn(e.canvas)?function(e,t){let n=!1,i=t;const r={mousemove:new Set,click:new Set,mouseleave:new Set};let o=null,a=null;const s=(t,n)=>{const o=(t=>{const n=e.getBoundingClientRect();if(0===n.width||0===n.height)return null;const r=t.clientX-n.left,o=t.clientY-n.top,a=i.left,s=i.top,l=n.width-i.left-i.right,u=n.height-i.top-i.bottom,c=r-a,d=o-s;return{x:r,y:o,gridX:c,gridY:d,plotWidthCss:l,plotHeightCss:u,isInGrid:c>=0&&c<=l&&d>=0&&d<=u,originalEvent:t}})(n);if(o)for(const e of r[t])e(o)},l=e=>{o&&e.isPrimary&&e.pointerId===o.pointerId&&(o=null)},u=e=>{n||s("mousemove",e)},c=e=>{n||(l(e),s("mouseleave",e))},d=e=>{n||(l(e),s("mouseleave",e))},f=e=>{if(!n){if(a===e.pointerId)return void(a=null);l(e),s("mouseleave",e)}},m=t=>{if(n||!t.isPrimary||"mouse"===t.pointerType&&0!==t.button)return;const i=e.getBoundingClientRect();if(0!==i.width&&0!==i.height){o={pointerId:t.pointerId,startClientX:t.clientX,startClientY:t.clientY,startTimeMs:t.timeStamp};try{e.setPointerCapture(t.pointerId)}catch{}}},p=t=>{if(n||!t.isPrimary||!o||t.pointerId!==o.pointerId)return;const i=t.timeStamp-o.startTimeMs,r=t.clientX-o.startClientX,l=t.clientY-o.startClientY,u=r*r+l*l;o=null;try{e.hasPointerCapture(t.pointerId)&&(a=t.pointerId,e.releasePointerCapture(t.pointerId))}catch{}i<=500&&u<=36&&s("click",t)};return e.addEventListener("pointermove",u,{passive:!0}),e.addEventListener("pointerleave",c,{passive:!0}),e.addEventListener("pointercancel",d,{passive:!0}),e.addEventListener("lostpointercapture",f,{passive:!0}),e.addEventListener("pointerdown",m,{passive:!0}),e.addEventListener("pointerup",p,{passive:!0}),{canvas:e,on:(e,t)=>{n||r[e].add(t)},off:(e,t)=>{r[e].delete(t)},updateGridArea:e=>{i=e},dispose:()=>{n||(n=!0,o=null,a=null,e.removeEventListener("pointermove",u),e.removeEventListener("pointerleave",c),e.removeEventListener("pointercancel",d),e.removeEventListener("lostpointercapture",f),e.removeEventListener("pointerdown",m),e.removeEventListener("pointerup",p),r.mousemove.clear(),r.click.clear(),r.mouseleave.clear())}}}(e.canvas,ht):null;let bt,vt={source:"mouse",x:0,y:0,gridX:0,gridY:0,isInGrid:!1,hasPointer:!1},yt=null;const xt=new Set;let Mt=null;const Ft=(e,t)=>{const n=null!==e&&Number.isFinite(e)?e:null;yt===n&&bt===t||(yt=n,bt=t,((e,t)=>{const n=Array.from(xt);for(const i of n)i(e,t)})(yt,bt))},Nt=()=>{var e;null==(e=null==n?void 0:n.onRequestRender)||e.call(n)},Ct=e=>!e||Number.isFinite(e.start)&&Number.isFinite(e.end)&&e.start<=0&&e.end>=100,St=()=>{null!==Fe&&(cancelAnimationFrame(Fe),Fe=null),null!==Te&&(clearTimeout(Te),Te=null),Me=!1},At=()=>{null!==De&&(clearTimeout(De),De=null)},kt=e=>{if(P)return;const t=(null==e?void 0:e.requestRenderAfter)??!0,n=(()=>{var e;if(0===Le.size)return!1;Ye.clear();const t=(null==jt?void 0:jt.getRange())??null,n=Ct(t),i=!0===R.autoScroll&&null!=jt&&null==R.xAxis.min&&null==R.xAxis.max,r=Mi(R,ge),o=t?Ni(r,t):null;let a=!1;for(const[e,t]of Le){if(0===t.length)continue;const i=R.series[e];if(i&&"pie"!==i.type){if(a=!0,"candlestick"===i.type){let n=he[e];if(!n){const t=i.rawData??i.data;n=0===t.length?[]:t.slice(),he[e]=n,ge[e]=i.rawBounds??null}for(const i of t){const t=i;n.push(...t),ge[e]=ii(ge[e],t)}}else{let r=he[e];if(!r){const t=i.rawData??i.data;r=ti(t),he[e]=r,ge[e]=i.rawBounds??f(t)}const o="line"===i.type&&"none"===i.sampling&&n&&"fullRawLine"===_e[e];for(const n of t){const t=n;if(o)try{it.appendSeries(e,t),Ye.add(e)}catch{}else"line"===i.type&&"none"!==i.sampling&&!fe.has(e)&&(fe.add(e),console.warn(`[ChartGPU] appendData() on series ${e} with sampling='${i.sampling}' causes full buffer re-upload every frame. For optimal streaming performance, use sampling='none'. See docs/internal/INCREMENTAL_APPEND_OPTIMIZATION.md for details.`));const a=s(t),d=r.x.length;for(let e=0;e=99.5){const t=e.end-e.start,n=jt;n.setRangeAnchored?n.setRangeAnchored(100-t,100,"end"):jt.setRange(100-t,100)}else{const e=Mi(R,ge),t=e.max-e.min;if(Number.isFinite(t)&&t>0){const n=(o.min-e.min)/t*100,i=(o.max-e.min)/t*100,r=Math.max(0,Math.min(100,n)),a=Math.max(0,Math.min(100,i));jt.setRange(r,a)}}}i&&(qt=void 0),fn();const d=(null==jt?void 0:jt.getRange())??null;return(null==d||Ct(d))&&(ve=be,xe()),!0})(),i=(null==jt?void 0:jt.getRange())??null,r=Ct(i),o=null!=i&&!r;let a=!1;ke?(ke=!1,At(),!i||r?(ve=be,xe()):pn(),a=!0):n&&o&&(ke=!1,At(),pn(),a=!0),(n||a)&&t&&Nt()},Gt=e=>{P||Me||(null!==Fe&&(cancelAnimationFrame(Fe),Fe=null),null!==Te&&(clearTimeout(Te),Te=null),Me=!0,Fe=requestAnimationFrame(()=>{Fe=null,P?St():(null!==Te&&(clearTimeout(Te),Te=null),Me=!1,kt())}),Te=(typeof self<"u"?self:window).setTimeout(()=>{P?St():Me&&(null!==Fe&&(cancelAnimationFrame(Fe),Fe=null),Me=!1,Te=null,kt())},16))},zt=(e,t)=>{let n,i;const r=e.getBoundingClientRect();if(!(r.width>0&&r.height>0))return null;n=r.width,i=r.height;const o=n-t.left-t.right,a=i-t.top-t.bottom;return o>0&&a>0?{plotWidthCss:o,plotHeightCss:a}:null},Vt=(e,t,n)=>{const i=R.series[e],{x:r,y:o}=(e=>ei(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y})(n);return{seriesName:(null==i?void 0:i.name)??"",seriesIndex:e,dataIndex:t,value:[r,o],color:(null==i?void 0:i.color)??"#888"}},Lt=(e,t,n)=>{const i=R.series[e];return pi(n)?{seriesName:(null==i?void 0:i.name)??"",seriesIndex:e,dataIndex:t,value:[n[0],n[1],n[2],n[3],n[4]],color:(null==i?void 0:i.color)??"#888"}:{seriesName:(null==i?void 0:i.name)??"",seriesIndex:e,dataIndex:t,value:[n.timestamp,n.open,n.close,n.low,n.high],color:(null==i?void 0:i.color)??"#888"}},Wt=(e,t,n,i,r)=>{const o=.5*Math.min(i,r);if(!(o>0))return null;for(let a=e.length-1;a>=0;a--){const s=e[a];if("pie"!==s.type||!1===s.visible)continue;const l=s,u=xn(t,n,{seriesIndex:a,series:l},gi(l.center,i,r),bi(l.radius,o));if(u)return u}return null},Ot=(e,t,n,i)=>{for(let r=e.length-1;r>=0;r--){const o=e[r];if("candlestick"!==o.type||!1===o.visible)continue;const a=o,s=mn(a,a.data,i.xScale,i.plotWidthCss),l=bn([a],t,n,i.xScale,i.yScale,s);if(l)return{params:Lt(r,l.dataIndex,l.point),match:{point:l.point},seriesIndex:r}}return null};gt&&(gt.on("mousemove",e=>{if(vt={source:"mouse",x:e.x,y:e.y,gridX:e.gridX,gridY:e.gridY,isInGrid:e.isInGrid,hasPointer:!0},e.isInGrid&&Mt){const t=Mt.xScale.invert(e.gridX);Ft(Number.isFinite(t)?t:null,"mouse")}else e.isInGrid||Ft(null,"mouse");st.setVisible(e.isInGrid),Nt()}),gt.on("mouseleave",e=>{"mouse"===vt.source&&(vt={...vt,isInGrid:!1,hasPointer:!1},st.setVisible(!1),Qe(),Ft(null,"mouse"),Nt())}));let qt,jt=null,Jt=null,Kt=null,Qt=null;const an=new Set,sn=e=>Math.min(100,Math.max(0,e)),ln=()=>{const e=(e=>{let t=null,n=null;const i=e.dataZoom??[];for(const e of i)if(e&&("inside"===e.type||"slider"===e.type)){if(Number.isFinite(e.minSpan)){const n=sn(e.minSpan);t=null==t?n:Math.max(t,n)}if(Number.isFinite(e.maxSpan)){const t=sn(e.maxSpan);n=null==n?t:Math.min(n,t)}}return{minSpan:t??void 0,maxSpan:n??void 0}})(R),t=(()=>{if("category"===R.xAxis.type)return null;let e=0;for(let t=0;t{var e;const t=(e=>{var t,n;const i=null==(t=e.dataZoom)?void 0:t.find(e=>"inside"===(null==e?void 0:e.type)),r=null==(n=e.dataZoom)?void 0:n.find(e=>"slider"===(null==e?void 0:e.type)),o=i??r;return o?{start:Number.isFinite(o.start)?o.start:0,end:Number.isFinite(o.end)?o.end:100,hasInside:!!i}:null})(R);if(!t)return null==Jt||Jt.dispose(),Jt=null,null==Kt||Kt(),Kt=null,jt=null,void(Qt=null);if(jt){const n=ln(),i=jt;null==(e=i.setSpanConstraints)||e.call(i,n.minSpan,n.maxSpan),(null==Qt||Qt.start!==t.start||Qt.end!==t.end)&&(jt.setRange(t.start,t.end),Qt={start:t.start,end:t.end})}else{const e=ln();jt=function(e,t,n){let i=0,r=100,o=null;const a=new Set;let s=(()=>{const e=Number.isFinite(null==n?void 0:n.minSpan)?n.minSpan:.5;return nn(Number.isFinite(e)?e:0,0,100)})(),l=(()=>{const e=Number.isFinite(null==n?void 0:n.maxSpan)?n.maxSpan:100;return nn(Number.isFinite(e)?e:100,0,100)})(),u=Math.min(s,l),c=Math.max(s,l);const d=(e,t,n)=>{if(n){if("string"==typeof n)switch(n){case"start":return{center:e,ratio:0};case"end":return{center:t,ratio:1};case"center":return{center:.5*(e+t),ratio:.5}}if(n&&Number.isFinite(n.center)&&Number.isFinite(n.ratio))return{center:n.center,ratio:n.ratio}}},f=(e,t,n)=>{if(!Number.isFinite(e)||!Number.isFinite(t))return;let s=e,l=t;if(s>l){const e=s;s=l,l=e}let d=l-s;if(!Number.isFinite(d)||d<0)return;const f=nn(d,u,c);if(f!==d&&(s=(null!=n&&n.anchor&&Number.isFinite(n.anchor.center)?nn(n.anchor.center,0,100):.5*(s+l))-(null!=n&&n.anchor&&Number.isFinite(n.anchor.ratio)?rn(n.anchor.ratio):.5)*f,l=s+f,d=f),d>100&&(s=0,l=100,d=100),s<0){const e=-s;s+=e,l+=e}if(l>100){const e=l-100;s-=e,l-=e}s=nn(s,0,100),l=nn(l,0,100),s=on(s),l=on(l),(s!==i||l!==r)&&(i=s,r=l,!1!==(null==n?void 0:n.emit)&&(()=>{const e={start:i,end:r};if(null!==o&&o.start===e.start&&o.end===e.end)return;o=(e=>({start:e.start,end:e.end}))(e);const t=Array.from(a);for(const e of t)e({start:i,end:r})})())};return f(e,t,{emit:!1}),{getRange:()=>({start:i,end:r}),setRange:(e,t)=>{f(e,t)},setRangeAnchored:(e,t,n)=>{f(e,t,{anchor:d(e,t,n)})},setSpanConstraints:(e,t)=>{const n="number"==typeof e&&Number.isFinite(e)?nn(e,0,100):s,o="number"==typeof t&&Number.isFinite(t)?nn(t,0,100):l;if(n===s&&o===l)return;s=n,l=o,u=Math.min(s,l),c=Math.max(s,l);const a=1e-6;f(i,r,{anchor:d(i,r,r>=100-a?"end":i<=0+a?"start":"center")})},zoomIn:(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||t<=1)return;const n=nn(e,0,100),o=r-i,a=0===o?.5:rn((n-i)/o),s=o/t,l=n-a*s;f(l,l+s,{anchor:{center:n,ratio:a}})},zoomOut:(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||t<=1)return;const n=nn(e,0,100),o=r-i,a=0===o?.5:rn((n-i)/o),s=o*t,l=n-a*s;f(l,l+s,{anchor:{center:n,ratio:a}})},pan:e=>{Number.isFinite(e)&&f(i+e,r+e)},onChange:e=>(a.add(e),()=>{a.delete(e)})}}(t.start,t.end,e),Qt={start:t.start,end:t.end},Kt=jt.onChange(e=>{Ve=!0,Nt(),P||(At(),ke=!1,De=(typeof self<"u"?self:window).setTimeout(()=>{De=null,!P&&(ke=!0,Gt())},100));const t=qt;((e,t)=>{const n=Array.from(an);for(const i of n)i(e,t)})({start:e.start,end:e.end},t),qt=void 0})}t.hasInside&>?Jt||(Jt=function(e,t){let n=!1,i=!1,r=null,o=!1,a=0;const s=typeof navigator<"u"&&navigator.maxTouchPoints>0,l=new Map;let u=0,c="";const d=()=>{u=0},f=()=>{o=!1,a=0},m=e=>{if(r=e,!i)return;const n=e.originalEvent;if(!e.isInGrid||!(e=>"mouse"===e.pointerType&&e.shiftKey&&!!(1&e.buttons))(n)&&!(e=>"mouse"===e.pointerType&&!!(4&e.buttons))(n))return void f();const s=e.plotWidthCss;if(!(s>0&&Number.isFinite(s)))return void f();if(!o)return o=!0,void(a=e.gridX);const l=e.gridX-a;if(a=e.gridX,!Number.isFinite(l)||0===l)return;const{start:u,end:c}=t.getRange(),d=c-u;if(!Number.isFinite(d)||0===d)return;const m=-l/s*d;!Number.isFinite(m)||0===m||t.pan(m)},p=e=>{r=null,f()},h=e=>{if(!i||n)return;const o=r;if(!o||!o.isInGrid)return;const a=o.plotWidthCss,s=o.plotHeightCss;if(!(a>0&&s>0))return;const l=((e,t)=>{const n=e.deltaY;if(!Number.isFinite(n)||0===n)return 0;switch(e.deltaMode){case WheelEvent.DOM_DELTA_PIXEL:return n;case WheelEvent.DOM_DELTA_LINE:return 16*n;case WheelEvent.DOM_DELTA_PAGE:return n*(Number.isFinite(t)&&t>0?t:800);default:return n}})(e,s),u=((e,t)=>{const n=e.deltaX;if(!Number.isFinite(n)||0===n)return 0;switch(e.deltaMode){case WheelEvent.DOM_DELTA_PIXEL:return n;case WheelEvent.DOM_DELTA_LINE:return 16*n;case WheelEvent.DOM_DELTA_PAGE:return n*(Number.isFinite(t)&&t>0?t:800);default:return n}})(e,a);if(Math.abs(u)>Math.abs(l)&&0!==u){const{start:n,end:i}=t.getRange(),r=i-n;if(!Number.isFinite(r)||0===r)return;const o=u/a*r;if(!Number.isFinite(o)||0===o)return;return e.preventDefault(),void t.pan(o)}if(0===l)return;const c=(e=>{const t=Math.abs(e);if(!Number.isFinite(t)||0===t)return 1;const n=Math.min(t,200);return Math.exp(.002*n)})(l);if(!(c>1))return;const{start:d,end:f}=t.getRange(),m=f-d;if(!Number.isFinite(m)||0===m)return;const p=tn(o.gridX/a,0,1),h=tn(d+p*m,0,100);e.preventDefault(),l<0?t.zoomIn(h,c):t.zoomOut(h,c)},g=t=>{!i||n||"touch"!==t.pointerType||(t.preventDefault(),!(r?r.isInGrid:((e,t)=>{const n=t.getBoundingClientRect();if(0===n.width||0===n.height)return!1;const i=e.clientX-n.left,r=e.clientY-n.top;return i>=0&&i<=n.width&&r>=0&&r<=n.height})(t,e.canvas)))||l.size>=2||(l.set(t.pointerId,{x:t.clientX,y:t.clientY}),e.canvas.setPointerCapture(t.pointerId),d())},b=o=>{if(!i||n||"touch"!==o.pointerType||!l.has(o.pointerId))return;const a=l.size;if(1===a){const e=l.get(o.pointerId);if(!e)return;const n=o.clientX-e.x;if(l.set(o.pointerId,{x:o.clientX,y:o.clientY}),!Number.isFinite(n)||0===n)return;const i=(null==r?void 0:r.plotWidthCss)??0;if(!(i>0))return;const{start:a,end:s}=t.getRange(),u=s-a;if(!Number.isFinite(u)||0===u)return;const c=-n/i*u;if(!Number.isFinite(c)||0===c)return;t.pan(c)}else if(2===a){l.set(o.pointerId,{x:o.clientX,y:o.clientY});const n=l.values(),i=n.next().value,a=n.next().value,s=Math.hypot(i.x-a.x,i.y-a.y),c=(i.x+a.x)/2;if(!Number.isFinite(s)||0===s)return;if(u>0&&Number.isFinite(u)){const n=u/s,i=e.canvas.getBoundingClientRect(),o=(null==r?void 0:r.plotWidthCss)??0;if(!(o>0)||0===i.width)return void(u=s);const a=r?r.x-r.gridX:0,l=c-i.left-a,d=tn(l/o,0,1),{start:f,end:m}=t.getRange(),p=m-f;if(!Number.isFinite(p)||0===p)return void(u=s);const h=tn(f+d*p,0,100);n>1?t.zoomOut(h,n):n>0&&n<1&&t.zoomIn(h,1/n)}u=s}},v=e=>{!i||n||"touch"===e.pointerType&&(l.delete(e.pointerId),d())},y=e=>{!i||n||"touch"===e.pointerType&&(l.delete(e.pointerId),d())},x=()=>{if(!n&&i){if(i=!1,e.off("mousemove",m),e.off("mouseleave",p),e.canvas.removeEventListener("wheel",h),s){const t=e.canvas;t.style.touchAction=c,t.removeEventListener("pointerdown",g),t.removeEventListener("pointermove",b),t.removeEventListener("pointerup",v),t.removeEventListener("pointercancel",y)}l.clear(),d(),r=null,f()}};return{enable:()=>{if(!n&&!i&&(i=!0,e.on("mousemove",m),e.on("mouseleave",p),e.canvas.addEventListener("wheel",h,{passive:!1}),s)){const t=e.canvas;c=t.style.touchAction,t.style.touchAction="none",t.addEventListener("pointerdown",g,{passive:!1}),t.addEventListener("pointermove",b,{passive:!1}),t.addEventListener("pointerup",v),t.addEventListener("pointercancel",y)}},disable:x,dispose:()=>{n||(x(),n=!0)}}}(gt,jt),Jt.enable()):(null==Jt||Jt.dispose(),Jt=null)},dn=()=>{const e=R.series.length;he=new Array(e).fill(null),ge=new Array(e).fill(null),Le.clear();for(let t=0;t{const e=new Array(R.series.length);for(let t=0;tn.samplingThreshold?C(i,n.samplingThreshold):i;e[t]={...n,rawData:i,rawBounds:r,data:o};continue}const i=he[t]??n.rawData??n.data,r=ge[t]??n.rawBounds??void 0,o=N(i,n.sampling,n.samplingThreshold);e[t]={...n,rawData:i,rawBounds:r,data:o}}be=e};function pn(){const e=(null==jt?void 0:jt.getRange())??null,t=Mi(R,ge),n=Ni(t,e),i=.1*(n.max-n.min),r=n.min-i,o=n.max+i,a=2e5,s=Math.max(.001,Math.min(1,n.spanFraction)),l=new Array(be.length);for(let t=0;t=100){l[t]=i;continue}if("candlestick"===i.type){const e=G(he[t]??i.rawData??i.data,r,o),u=i.sampling,c=i.samplingThreshold,d=Number.isFinite(c)?Math.max(1,0|c):1,f=Math.min(a,Math.max(2,32*d)),m=ui(Math.round(d/s),2,f),p="ohlc"===u&&e.length>m?C(e,m):e;we[t]={data:p,cachedRange:{min:r,max:o},timestamp:Date.now()};const h=G(p,n.min,n.max);l[t]={...i,data:h};continue}const u=U(he[t]??i.rawData??i.data,r,o),c=i.sampling,d=i.samplingThreshold,f=Number.isFinite(d)?Math.max(1,0|d):1,m=Math.min(a,Math.max(2,32*f)),p=N(u,c,ui(Math.round(f/s),2,m));we[t]={data:p,cachedRange:{min:r,max:o},timestamp:Date.now()};const h=U(p,n.min,n.max);l[t]={...i,data:h}}ve=l,xe()}dn(),fn(),cn(),pn(),we=new Array(R.series.length).fill(null);const hn=function(e){const{device:t,targetFormat:n,pipelineCache:i,sampleCount:r}=e,o=[],a=[],c=[],d=[],f=[],m=[],p=function(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,c=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),d=Ge(e,64,{label:"barRenderer/vsUniforms"});ze(e,d,(()=>{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})());const f=e.createBindGroup({layout:c,entries:[{binding:0,resource:{buffer:d}}]}),m=Ue(e,{label:"barRenderer/pipeline",bindGroupLayouts:[c],vertex:{code:Pt,label:"bar.wgsl",buffers:[{arrayStride:32,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x4",offset:0},{shaderLocation:1,format:"float32x4",offset:16}]}]},fragment:{code:Pt,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:o}},a);let p=null,h=0,g=new ArrayBuffer(0),b=new Float32Array(g);const v=[],y=()=>{if(n)throw new Error("BarRenderer is disposed.")},x=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;in&&(n=i))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t){if(y(),0===t.length)return void(h=0);const a=(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?{plotWidthCss:r,plotHeightCss:o}:null})(o);if(!a)return void(h=0);const c=(e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:a,devicePixelRatio:s}=e;return{left:t*s/o*2-1,right:(o-n*s)/o*2-1,top:1-i*s/a*2,bottom:1-(a-r*s)/a*2}})(o),d=c.right-c.left,f=a.plotWidthCss>0?d/a.plotWidthCss:0,m=new Map,w=new Array(t.length);let M=0;for(let e=0;e{v.length=0;for(let t=0;te-t);let t=Number.POSITIVE_INFINITY;for(let e=1;e0&&n0?t:1})(t),N=(e=>{let t,n,i;for(let r=0;r{if(Number.isFinite(t)&&t>0){const n=e.scale(0),i=e.scale(0+t),r=Math.abs(i-n);if(Number.isFinite(r)&&r>0)return r}const r=Math.abs(n.right-n.left);return r>0?r/Math.max(1,Math.floor(i)):0})(i,F,c,A),P=Math.max(0,I*(1-S)),R=M+Math.max(0,M-1)*C,E=R>0?P/R:0;let B=0;const T=N.barWidth;if("number"==typeof T)B=Math.max(0,T)*f,B=Math.min(B,E);else if("string"==typeof T){const e=(e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null})(T);B=null==e?0:E*Rt(e)}B>0||(B=E);const D=B*C,U=M*B+Math.max(0,M-1)*D;let k=((e,t,n)=>{const i=t.invert(n.bottom),r=t.invert(n.top),o=Math.min(i,r),a=Math.max(i,r);return Number.isFinite(o)&&Number.isFinite(a)?o<=0&&0<=a?0:o>0?o:a<0?a:x(e):x(e)})(t,r,c),G=r.scale(k);if(!Number.isFinite(G)){const e=x(t);if(k=e,G=r.scale(e),Number.isFinite(G)||(k=0,G=r.scale(0)),!Number.isFinite(G))return void(h=0)}let z=0;for(let e=0;e{if(e<=b.length)return;const t=Math.max(8,Bt(e));g=new ArrayBuffer(4*t),b=new Float32Array(g)})(8*z);const V=b;let L=0;const W=new Map;for(let e=0;e0&&Number.isFinite(s)?Math.round((s-c.left)/I):Number.isFinite(F)&&F>0?Math.round(t/F):Math.round(1e6*t);let o,a,l=i.get(e);l||(l={posSum:k,negSum:k},i.set(e,l)),n>=0?(o=l.posSum,a=o+n,l.posSum=a):(o=l.negSum,a=o+n,l.negSum=a);const u=r.scale(o),d=r.scale(a);if(!Number.isFinite(u)||!Number.isFinite(d))continue;b=u,v=d-u}else{const e=r.scale(n);if(!Number.isFinite(e))continue;v=e-G}V[L+0]=g,V[L+1]=b,V[L+2]=B,V[L+3]=v,V[L+4]=a,V[L+5]=d,V[L+6]=f,V[L+7]=m,L+=8}}h=L/8;const O=Math.max(4,32*h);if(!p||p.size0&&e.queue.writeBuffer(p,0,g,0,32*h)},render:e=>{y(),p&&0!==h&&(e.setPipeline(m),e.setBindGroup(0,f),e.setVertexBuffer(0,p),e.draw(6,h))},dispose:()=>{if(!n){if(n=!0,p)try{p.destroy()}catch{}p=null,h=0;try{d.destroy()}catch{}}}}}(t,{targetFormat:n,pipelineCache:i,sampleCount:r});let h=null;return{ensureAreaRendererCount:function(e){for(;o.length>e;){const e=o.pop();null==e||e.dispose()}for(;o.lengthe;){const e=a.pop();null==e||e.dispose()}for(;a.lengthe;){const e=c.pop();null==e||e.dispose()}for(;c.lengthe;){const e=d.pop();null==e||e.dispose()}for(;d.lengthe;){const e=f.pop();null==e||e.dispose()}for(;f.lengthe;){const e=m.pop();null==e||e.dispose()}for(;m.length{if(P)throw new Error("RenderCoordinator is disposed.")},vn=()=>{if(W)try{L.cancel(W)}catch{}W=null,O=1,$=null,Z()},yn=(e,t)=>e.min===t.min&&e.max===t.max,wn=e=>{var t;gn();const n=(null==jt?void 0:jt.getRange())??null,i=(()=>{if($&&W){try{L.update(performance.now())}catch{}return((e,t,n)=>{const i=di(e.from.xBaseDomain,e.to.xBaseDomain,t),r=Ni(i,n),o=di(e.from.yBaseDomain,e.to.yBaseDomain,t),a=Q(e.from.series,e.to.series,t,null);return{xBaseDomain:i,xVisibleDomain:{min:r.min,max:r.max},yBaseDomain:o,series:a}})($,O,n)}const e=Mi(R,ge),t=Ni(e,n),i=Fi(R,ge,ye);return{xBaseDomain:e,xVisibleDomain:{min:t.min,max:t.max},yBaseDomain:i,series:ve}})();vn();const r=((e,t)=>{if(e.length!==t.length)return!0;for(let n=0;nCi(e))(R.animation);if(!f)return;$={from:{xBaseDomain:i.xBaseDomain,xVisibleDomain:i.xVisibleDomain,yBaseDomain:i.yBaseDomain,series:i.series},to:{xBaseDomain:s,xVisibleDomain:{min:l.min,max:l.max},yBaseDomain:u,series:c}},Z();const m=f.delayMs+f.durationMs;O=0;const p=L.animate(0,1,m,e=>{const t=li(e);if(!(m>0))return 1;const n=t*m;if(n<=f.delayMs)return 0;if(!(f.durationMs>0))return 1;const i=(n-f.delayMs)/f.durationMs;return f.easing(i)},e=>{P||W!==p||(O=li(e),O<1&&Nt())},()=>{P||W!==p||(O=1,$=null,W=null,Z())});W=p,Nt()};return{setOptions:wn,appendData:(e,t)=>{if(gn(),!Number.isFinite(e)||e<0||e>=R.series.length||!t)return;const n=R.series[e];if("pie"===n.type)return void(te.has(e)||(te.add(e),console.warn(`RenderCoordinator.appendData(${e}, ...): pie series are not supported by streaming append.`)));if(0===("candlestick"===n.type?t.length:s(t)))return;const i=Le.get(e);i?i.push(t):Le.set(e,[t]),Gt()},getInteractionX:()=>yt,setInteractionX:(e,t)=>{gn();const n=null!==e&&Number.isFinite(e)?e:null;vt={...vt,source:null===n?"mouse":"sync"},Ft(n,t),null===n&&!1===vt.hasPointer&&(st.setVisible(!1),lt.setVisible(!1),Ke()),Nt()},onInteractionXChange:e=>(gn(),xt.add(e),()=>{xt.delete(e)}),getZoomRange:()=>(null==jt?void 0:jt.getRange())??null,setZoomRange:(e,t)=>{gn(),jt&&jt.setRange(e,t)},onZoomRangeChange:e=>(gn(),an.add(e),()=>{an.delete(e)}),render:()=>{var t,n,i;if(gn(),!e.canvasContext||!e.canvas)return;(Le.size>0||ke)&&(St(),kt({requestRenderAfter:!1})),Ve&&(Ve=!1,function(){const e=(null==jt?void 0:jt.getRange())??null,t=Mi(R,ge),n=Ni(t,e);if(null==e||Number.isFinite(e.start)&&Number.isFinite(e.end)&&e.start<=0&&e.end>=100)return ve=be,void xe();const i=new Array(be.length);for(let e=0;e=r.cachedRange.min&&n.max<=r.cachedRange.max?"candlestick"===t.type?i[e]={...t,data:G(r.data,n.min,n.max)}:i[e]={...t,data:U(r.data,n.min,n.max)}:"candlestick"===t.type?i[e]={...t,data:G(t.data,n.min,n.max)}:i[e]={...t,data:U(t.data,n.min,n.max)}}ve=i,xe()}());const r=R.series.some(e=>"pie"!==e.type),o=ve;if("done"!==B){const e=(e=>Ci(e))(R.animation),t=(()=>{for(let e=0;e"number"==typeof(null==e?void 0:e.value)&&Number.isFinite(e.value)&&e.value>0))return!0;break;case"line":case"area":case"bar":case"scatter":if(s(t.data)>0)return!0;break;case"candlestick":if(t.data.length>0)return!0;break;default:Qn(t)}}return!1})();if("pending"===B&&e&&t){const t=e.delayMs+e.durationMs,n=n=>{const i=li(n);if(!(t>0))return 1;const r=i*t;if(r<=e.delayMs)return 0;if(!(e.durationMs>0))return 1;const o=(r-e.delayMs)/e.durationMs;return e.easing(o)};T=0,B="running",z=D.animate(0,1,t,n,e=>{P||"running"!==B||(T=li(e),T<1&&Nt())},()=>{P||(B="done",T=1,z=null)})}D.update(performance.now())}null!==$&&W&&L.update(performance.now());const u=ai(e,R);null==gt||gt.updateGridArea(u);const c=(null==jt?void 0:jt.getRange())??null,d=$?li(O):1,f=$?di($.from.xBaseDomain,$.to.xBaseDomain,d):Mi(R,ge),m=$?di($.from.yBaseDomain,$.to.yBaseDomain,d):Fi(R,ge,ye),h=Ni(f,c),g=(e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:a,devicePixelRatio:s}=e;return{left:t*s/o*2-1,right:(o-n*s)/o*2-1,top:1-i*s/a*2,bottom:1-(a-r*s)/a*2}})(u),b=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=ui(Math.floor(r),0,Math.max(0,t)),u=ui(Math.floor(a),0,Math.max(0,n)),c=ui(Math.ceil(o),0,Math.max(0,t)),d=ui(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(u),v=Mn().domain(h.min,h.max).range(g.left,g.right),y=Mn().domain(m.min,m.max).range(g.bottom,g.top),F=e.canvas,N=function(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}}(F),C=N.width,E=N.height,Z=C>0?fi(g.left,C):0,J=C>0?fi(g.right,C):0,K=E>0?mi(g.top,E):0,te=E>0?mi(g.bottom,E):0,fe=Math.max(0,J-Z),he=Math.max(0,te-K),Me=function(e){var t,n,i,r,o,a,s,l,u,c,d,f,m,p;const{annotations:h,xScale:g,yScale:b,plotBounds:v,canvasCssWidth:y,canvasCssHeight:x,theme:w,offsetX:M=0,offsetY:F=0}=e,{leftCss:N,topCss:C,widthCss:S,heightCss:A}=v,I=[],P=[],R=[],E=[],B=[];if(0===h.length||y<=0||x<=0||S<=0||A<=0)return{linesBelow:I,linesAbove:P,markersBelow:R,markersAbove:E,labels:B};for(let e=0;ev.leftCss+v.widthCss+j||Yv.topCss+v.heightCss+j)continue;const Z=_+((null==(f=null==O?void 0:O.offset)?void 0:f[0])??0),J=Y+((null==(m=null==O?void 0:O.offset)?void 0:m[1])??0),K=(null==O?void 0:O.text)??(null!=O&&O.template?Ie(O.template,$,O.decimals):O?(()=>{const e="lineX"===T.type?"x={x}":"lineY"===T.type?"y={y}":"point"===T.type?"({x}, {y})":"text"===T.type?T.text:"";return e.includes("{")?Ie(e,$,O.decimals):e})():"text"===T.type?T.text:""),Q="string"==typeof K?K.trim():"";if(0===Q.length)continue;const ee=Pe(null==O?void 0:O.anchor),te=(null==(p=T.style)?void 0:p.color)??w.textColor,ne=w.fontSize,ie=null==O?void 0:O.background,re=null!=(null==ie?void 0:ie.color)?Ae(ie.color,ie.opacity??1):void 0,oe=(()=>{const e=null==ie?void 0:ie.padding;return"number"==typeof e&&Number.isFinite(e)?[e,e,e,e]:Array.isArray(e)&&4===e.length&&e.every(e=>"number"==typeof e&&Number.isFinite(e))?[e[0],e[1],e[2],e[3]]:ie?[2,4,2,4]:void 0})(),ae="number"==typeof(null==ie?void 0:ie.borderRadius)&&Number.isFinite(ie.borderRadius)?ie.borderRadius:void 0,se={text:Q,x:M+Z,y:F+J,anchor:ee,color:te,fontSize:ne,...re?{background:{backgroundColor:re,...oe?{padding:oe}:{},...null!=ae?{borderRadius:ae}:{}}}:{}};B.push(se)}return{linesBelow:I,linesAbove:P,markersBelow:R,markersAbove:E,labels:B}}({annotations:r?R.annotations??[]:[],xScale:v,yScale:y,plotBounds:{leftCss:Z,rightCss:J,topCss:K,bottomCss:te,widthCss:fe,heightCss:he},canvasCssWidth:C,canvasCssHeight:E,theme:R.theme}),Fe=Me.linesBelow.length+Me.linesAbove.length>0?[...Me.linesBelow,...Me.linesAbove]:[],Be=Me.markersBelow.length+Me.markersAbove.length>0?[...Me.markersBelow,...Me.markersAbove]:[],Te=Me.linesBelow.length,De=Me.linesAbove.length,Ue=Me.markersBelow.length,Ge=Me.markersAbove.length,ze=function(e){return e?e.clientWidth:0}(e.canvas),We=Math.abs(h.max-h.min);let Oe=5,Xe=[];if("time"===R.xAxis.type){const e=(e=>{const{axisMin:t,axisMax:n,xScale:i,plotClipLeft:r,plotClipRight:o,canvasCssWidth:a,visibleRangeMs:s,measureCtx:l,measureCache:u,fontSize:c,fontFamily:d,tickFormatter:f}=e,m=Jn(t)??i.invert(r),p=Jn(n)??i.invert(o);if(!l||a<=0)return{tickCount:5,tickValues:wi(m,p,5)};l.font=`${c}px ${d}`,u&&u.size>2e3&&u.clear();const h=u?`${c}px ${d}@@`:null;for(let e=9;e>=1;e--){const t=wi(m,p,e);let n=Number.NEGATIVE_INFINITY,r=!0;for(let o=0;o{if(!h)return l.measureText(d).width;const e=h+d,t=u.get(e);if(null!=t)return t;const n=l.measureText(d).width;return u.set(e,n),n})(),p=i.scale(c),g=fi(p,a),b=1===e?"middle":0===o?"start":o===t.length-1?"end":"middle",v="start"===b?g+m:"end"===b?g:g+.5*m;if(("start"===b?g:"end"===b?g-m:g-.5*m){const i=e.canvas;if(!i)return null;const r=zt(i,t);return r?{xScale:Mn().domain(n.xDomain.min,n.xDomain.max).range(0,r.plotWidthCss),yScale:Mn().domain(n.yDomain.min,n.yDomain.max).range(r.plotHeightCss,0),plotWidthCss:r.plotWidthCss,plotHeightCss:r.plotHeightCss}:null})(u,{xDomain:{min:h.min,max:h.max},yDomain:m});Mt=$e;const Ze=$&&d<1?Q($.from.series,$.to.series,d,j):ve;if("mouse"===vt.source&&vt.hasPointer&&vt.isInGrid&&$e){const e=$e.xScale.invert(vt.gridX);Ft(Number.isFinite(e)?e:null,"mouse")}let Ke=vt;if("sync"===vt.source)if(null!==yt&&$e){const e=$e.xScale.scale(yt),t=.5*$e.plotHeightCss,n=Number.isFinite(e)&&Number.isFinite(t)&&e>=0&&e<=$e.plotWidthCss&&t>=0&&t<=$e.plotHeightCss;Ke={source:"sync",gridX:Number.isFinite(e)?e:0,gridY:Number.isFinite(t)?t:0,x:u.left+(Number.isFinite(e)?e:0),y:u.top+(Number.isFinite(t)?t:0),isInGrid:n,hasPointer:n}}else Ke={...vt,hasPointer:!1,isInGrid:!1};if(Ce({gridRenderer:rt,xAxisRenderer:ot,yAxisRenderer:at,crosshairRenderer:st,highlightRenderer:lt},{currentOptions:R,xScale:v,yScale:y,gridArea:u,xTickCount:Oe,hasCartesianSeries:r,effectivePointer:Ke,interactionScales:$e,seriesForRender:Ze,withAlpha:si}),Ke.hasPointer&&Ke.isInGrid&&!1!==(null==(t=R.tooltip)?void 0:t.show)){const t=e.canvas;if($e&&t&&Hn(t)){const e=null==(n=R.tooltip)?void 0:n.formatter,r=(null==(i=R.tooltip)?void 0:i.trigger)??"item",o=t.offsetLeft+Ke.x,a=t.offsetTop+Ke.y;if("sync"===Ke.source){const t=un(Ze,Ke.gridX,$e.xScale);if(0===t.length)Qe();else if("axis"===r){const n=t.map(e=>Vt(e.seriesIndex,e.dataIndex,e.point)),i=e?e(n):zn(n);!i||i===He&&o===qe&&a===je?i||Qe():(He=i,qe=o,je=a,Je(o,a,i))}else{const n=t[0],i=Vt(n.seriesIndex,n.dataIndex,n.point),r=e?e(i):Gn(i);!r||r===He&&o===qe&&a===je?r||Qe():(He=r,qe=o,je=a,Je(o,a,r))}}else if("axis"===r){const n=Wt(Ze,Ke.gridX,Ke.gridY,$e.plotWidthCss,$e.plotHeightCss);if(n){const t={seriesName:n.slice.name,seriesIndex:n.seriesIndex,dataIndex:n.dataIndex,value:[0,n.slice.value],color:n.slice.color},i=e?e([t]):Gn(t);!i||i===He&&o===qe&&a===je?i||Qe():(He=i,qe=o,je=a,Je(o,a,i))}else{const n=Ot(Ze,Ke.gridX,Ke.gridY,$e),i=un(Ze,Ke.gridX,$e.xScale);if(0===i.length)if(n){const i=[n.params],r=e?e(i):zn(i);if(r){const e=Si(n.match,$e.xScale,$e.yScale,u,t),i=(null==e?void 0:e.x)??o,s=(null==e?void 0:e.y)??a;(r!==He||i!==qe||s!==je)&&(He=r,qe=i,je=s,Je(i,s,r))}else Qe()}else Qe();else{const r=i.map(e=>Vt(e.seriesIndex,e.dataIndex,e.point));n&&r.push(n.params);const s=e?e(r):zn(r);if(s){let e=o,i=a;if(n){const r=Si(n.match,$e.xScale,$e.yScale,u,t);r&&(e=r.x,i=r.y)}(s!==He||e!==qe||i!==je)&&(He=s,qe=e,je=i,Je(e,i,s))}else Qe()}}}else{const n=Wt(Ze,Ke.gridX,Ke.gridY,$e.plotWidthCss,$e.plotHeightCss);if(n){const t={seriesName:n.slice.name,seriesIndex:n.seriesIndex,dataIndex:n.dataIndex,value:[0,n.slice.value],color:n.slice.color},i=e?e(t):Gn(t);!i||i===He&&o===qe&&a===je?i||Qe():(He=i,qe=o,je=a,Je(o,a,i))}else{const n=Ot(Ze,Ke.gridX,Ke.gridY,$e);if(n){const i=e?e(n.params):Gn(n.params);if(i){const e=Si(n.match,$e.xScale,$e.yScale,u,t),r=(null==e?void 0:e.x)??o,s=(null==e?void 0:e.y)??a;(i!==He||r!==qe||s!==je)&&(He=i,qe=r,je=s,Je(r,s,i,n.params))}else Qe();return}const i=Ne(Ze,Ke.gridX,Ke.gridY,$e.xScale,$e.yScale);if(i){const t=Vt(i.seriesIndex,i.dataIndex,i.point),n=e?e(t):Gn(t);!n||n===He&&o===qe&&a===je?n||Qe():(He=n,qe=o,je=a,Je(o,a,n))}else Qe()}}}else Qe()}else Qe();const et=$e??(F&&Hn(F)?zt(F,u):null),tt=et&&"number"==typeof et.plotWidthCss&&"number"==typeof et.plotHeightCss?.5*Math.min(et.plotWidthCss,et.plotHeightCss):0,nt=hn.getState(),dt=function(e,t){const{currentOptions:n,seriesForRender:i,xScale:r,yScale:o,gridArea:a,dataStore:u,appendedGpuThisFrame:c,gpuSeriesKindByIndex:d,zoomState:f,visibleXDomain:m,introPhase:h,introProgress01:g,withAlpha:b,maxRadiusCss:v}=t,y=n.yAxis.min??n.yAxis.min??0,x=[],w="running"===h?Re(g):1;for(let t=0;t{if("time"!==n.xAxis.type)return 0;const e=h.data,t=s(e);for(let n=0;n=100)&&"none"===h.sampling?d[t]="fullRawLine":d[t]="other",h.areaStyle){const n={type:"area",name:h.name,rawData:h.data,data:m,color:h.areaStyle.color,areaStyle:h.areaStyle,sampling:h.sampling,samplingThreshold:h.samplingThreshold,connectNulls:h.connectNulls};e.areaRenderers[t].prepare(n,n.data,r,o,y)}break}case"bar":x.push(h);break;case"scatter":if("density"===h.mode){const n=h.rawData??h.data,i=k(n,m.min,m.max);c.has(t)||u.setSeries(t,n);const s=u.getSeriesBuffer(t),l=u.getSeriesPointCount(t);e.scatterDensityRenderers[t].prepare(h,s,l,i.start,i.end,r,o,a,h.rawBounds),d[t]="other"}else{const n=w<1?{...h,color:b(h.color,w)}:h;e.scatterRenderers[t].prepare(n,h.data,r,o,a)}break;case"pie":if(w<1&&v>0){const n=ee(h.radius,v),i=Math.max(0,n.inner)*w,r=Math.max(i,n.outer)*w,o={...h,radius:[i,r]};e.pieRenderers[t].prepare(o,a);break}e.pieRenderers[t].prepare(h,a);break;case"candlestick":e.candlestickRenderers[t].prepare(h,h.data,r,o,a,n.theme.backgroundColor);break;default:throw new Error(`Unhandled series type: ${h.type}`)}}const M=i.map((e,t)=>({series:e,originalIndex:t})).filter(({series:e})=>!1!==e.visible),F=x.filter(e=>!1!==e.visible);return{visibleSeriesForRender:M,barSeriesConfigs:x,visibleBarSeriesConfigs:F}}(nt,{currentOptions:R,seriesForRender:Ze,xScale:v,yScale:y,gridArea:u,dataStore:it,appendedGpuThisFrame:Ye,gpuSeriesKindByIndex:_e,zoomState:jt,visibleXDomain:h,introPhase:B,introProgress01:T,withAlpha:si,maxRadiusCss:tt}),{visibleBarSeriesConfigs:ht}=dt,bt="running"===B?li(T):1,xt=bt<1?((e,t,n,i)=>{const r=li(i);if(r>=1)return e;const o=((e,t,n)=>{const i=t.invert(n.bottom),r=t.invert(n.top),o=Math.min(i,r),a=Math.max(i,r);return Number.isFinite(o)&&Number.isFinite(a)?o<=0&&0<=a?0:o>0?o:a<0?a:Ai(e):Ai(e)})(n,e,t),a=e.scale(o),s={domain:(t,n)=>(e.domain(t,n),s),range:(t,n)=>(e.range(t,n),s),scale(t){const n=e.scale(t);return Number.isFinite(n)&&Number.isFinite(a)?a+(n-a)*r:n},invert:t=>e.invert(t)};return s})(y,g,ht,bt):y;nt.barRenderer.prepare(ht,it,v,xt,u),r?(ut.prepare(u,Fe),ft.prepare(u,Fe),ct.prepare({canvasWidth:u.canvasWidth,canvasHeight:u.canvasHeight,devicePixelRatio:u.devicePixelRatio,instances:Be}),mt.prepare({canvasWidth:u.canvasWidth,canvasHeight:u.canvasHeight,devicePixelRatio:u.devicePixelRatio,instances:Be})):(ut.prepare(u,[]),ft.prepare(u,[]),ct.prepare({canvasWidth:u.canvasWidth,canvasHeight:u.canvasHeight,devicePixelRatio:u.devicePixelRatio,instances:[]}),mt.prepare({canvasWidth:u.canvasWidth,canvasHeight:u.canvasHeight,devicePixelRatio:u.devicePixelRatio,instances:[]})),pt.ensureTextures(u.canvasWidth,u.canvasHeight);const wt=pt.getState(),Ct=e.canvasContext.getCurrentTexture().createView(),At=a.createCommandEncoder({label:"renderCoordinator/commandEncoder"}),It=((e,t={r:0,g:0,b:0,a:1})=>{const n=_(e);if(!n)return t;const[i,r,o,a]=n;return{r:i,g:r,b:o,a}})(R.theme.backgroundColor,{r:0,g:0,b:0,a:1});!function(e,t,n){for(let i=0;i0&&s.h>0&&(c>0||d>0)&&(a.setScissorRect(s.x,s.y,s.w,s.h),c>0&&t.referenceLineRenderer.render(a,0,c),d>0&&t.annotationMarkerRenderer.render(a,0,d),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight));for(let t=0;t0&&s.h>0&&(a.setScissorRect(s.x,s.y,t,s.h),e.areaRenderers[i].render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight))}else a.setScissorRect(s.x,s.y,s.w,s.h),e.areaRenderers[i].render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight)}s.w>0&&s.h>0&&(a.setScissorRect(s.x,s.y,s.w,s.h),e.barRenderer.render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight));for(let t=0;t0&&s.h>0&&(a.setScissorRect(s.x,s.y,t,s.h),e.lineRenderers[i].render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight))}else a.setScissorRect(s.x,s.y,s.w,s.h),e.lineRenderers[i].render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight)}}(nt,{referenceLineRenderer:ut,annotationMarkerRenderer:ct},{hasCartesianSeries:r,gridArea:u,mainPass:Pt,plotScissor:b,introPhase:B,introProgress01:T,referenceLineBelowCount:Te,markerBelowCount:Ue},dt),Pt.end();const Rt=At.beginRenderPass({label:"renderCoordinator/annotationOverlayMsaaPass",colorAttachments:[{view:wt.overlayMsaaView,resolveTarget:Ct,clearValue:It,loadOp:"clear",storeOp:"discard"}]});Rt.setPipeline(wt.overlayBlitPipeline),Rt.setBindGroup(0,wt.overlayBlitBindGroup),Rt.draw(3),function(e,t){const{hasCartesianSeries:n,gridArea:i,overlayPass:r,plotScissor:o,referenceLineBelowCount:a,referenceLineAboveCount:s,markerBelowCount:l,markerAboveCount:u}=t;if(n&&o.w>0&&o.h>0&&(s>0||u>0)){const t=a,n=l;r.setScissorRect(o.x,o.y,o.w,o.h),s>0&&e.referenceLineRendererMsaa.render(r,t,s),u>0&&e.annotationMarkerRendererMsaa.render(r,n,u),r.setScissorRect(0,0,i.canvasWidth,i.canvasHeight)}}({referenceLineRendererMsaa:ft,annotationMarkerRendererMsaa:mt},{hasCartesianSeries:r,gridArea:u,overlayPass:Rt,plotScissor:b,referenceLineBelowCount:Te,referenceLineAboveCount:De,markerBelowCount:Ue,markerAboveCount:Ge}),Rt.end();const Et=At.beginRenderPass({label:"renderCoordinator/topOverlayPass",colorAttachments:[{view:Ct,loadOp:"load",storeOp:"store"}]});lt.render(Et),r&&(ot.render(Et),at.render(Et)),st.render(Et),Et.end(),a.queue.submit([At.finish()]),V=!0,function(e,t,n){var i,r,o;const{gpuContext:a,currentOptions:s,xScale:l,yScale:u,xTickValues:c,plotClipRect:d,visibleXRangeMs:f}=n;if(!s.series.some(e=>"pie"!==e.type)||!e||!t)return;const m=a.canvas;if(!m)return;const p=function(e){return e?e.clientWidth:0}(m),h=function(e){return e?e.clientHeight:0}(m);if(p<=0||h<=0)return;const g=m.offsetLeft||0,b=m.offsetTop||0,v=oe(d.left,p),y=oe(d.right,p),x=ae(d.top,h),w=ae(d.bottom,h);e.clear();const M=w+(s.xAxis.tickLength??6)+4+.5*s.theme.fontSize,F="time"===s.xAxis.type,N=(()=>{if(F)return null;const e=Y(s.xAxis.min)??l.invert(d.left),t=Y(s.xAxis.max)??l.invert(d.right),n=c.length;return ie(1===n?0:(t-e)/(n-1))})(),C=s.xAxis.tickFormatter;for(let t=0;t0){const t=(v+y)/2,n=(M+.5*s.theme.fontSize+((null==(r=s.dataZoom)?void 0:r.some(e=>"slider"===(null==e?void 0:e.type)))?h-32:h))/2;se(e.addLabel(D,g+t,b+n,{fontSize:T,color:s.theme.textColor,anchor:"middle"}),!0,s.theme)}const U=(null==(o=s.yAxis.name)?void 0:o.trim())??"";if(U.length>0){const t=(x+w)/2,n=R-(0===E.length?0:E.reduce((e,t)=>Math.max(e,t.getBoundingClientRect().width),0))-4-.5*T;se(e.addLabel(U,g+n,b+t,{fontSize:T,color:s.theme.textColor,anchor:"middle",rotation:-90}),!0,s.theme)}}(w,x,{gpuContext:e,currentOptions:R,xScale:v,yScale:y,xTickValues:Xe,plotClipRect:g,visibleXRangeMs:We}),function(e,t,n){var i,r,o;const{currentOptions:a,xScale:s,yScale:l,canvasCssWidthForAnnotations:u,canvasCssHeightForAnnotations:c,plotLeftCss:d,plotTopCss:f,plotWidthCss:m,plotHeightCss:p,canvas:h}=n;if(!a.series.some(e=>"pie"!==e.type)||!e||!t)return;if(!h||u<=0||c<=0||m<=0||p<=0)return void e.clear();const g=le(h)?h.offsetLeft:0,b=le(h)?h.offsetTop:0;e.clear();const v=a.annotations??[];if(0!==v.length)for(let t=0;td+m+M||xf+p+M)continue;const F=y+((null==(i=null==h?void 0:h.offset)?void 0:i[0])??0),N=x+((null==(r=null==h?void 0:h.offset)?void 0:r[1])??0),C=(null==h?void 0:h.text)??(null!=h&&h.template?me(h.template,w,h.decimals):h?(()=>{const e="lineX"===n.type?"x={x}":"lineY"===n.type?"y={y}":"point"===n.type?"({x}, {y})":"text"===n.type?n.text:"";return e.includes("{")?me(e,w,h.decimals):e})():"text"===n.type?n.text:""),S="string"==typeof C?C.trim():"";if(0===S.length)continue;const A=pe(null==h?void 0:h.anchor),I=(null==(o=n.style)?void 0:o.color)??a.theme.textColor,P=a.theme.fontSize,R=null==h?void 0:h.background,E=null!=(null==R?void 0:R.color)?de(R.color,R.opacity??1):void 0,B=(()=>{const e=null==R?void 0:R.padding;return"number"==typeof e&&Number.isFinite(e)?[e,e,e,e]:Array.isArray(e)&&4===e.length&&e.every(e=>"number"==typeof e&&Number.isFinite(e))?[e[0],e[1],e[2],e[3]]:R?[2,4,2,4]:void 0})(),T="number"==typeof(null==R?void 0:R.borderRadius)&&Number.isFinite(R.borderRadius)?R.borderRadius:void 0,D={x:g+F,y:b+N,...E?{background:{backgroundColor:E,...B?{padding:B}:{},...null!=T?{borderRadius:T}:{}}}:{}},U=e.addLabel(S,D.x,D.y,{fontSize:P,color:I,anchor:A});if(D.background){if(U.style.backgroundColor=D.background.backgroundColor,U.style.display="inline-block",U.style.boxSizing="border-box",D.background.padding){const[e,t,n,i]=D.background.padding;U.style.padding=`${e}px ${t}px ${n}px ${i}px`}null!=D.background.borderRadius&&(U.style.borderRadius=`${D.background.borderRadius}px`)}}}(M,x,{currentOptions:R,xScale:v,yScale:y,canvasCssWidthForAnnotations:C,canvasCssHeightForAnnotations:E,plotLeftCss:Z,plotTopCss:K,plotWidthCss:fe,plotHeightCss:he,canvas:F})},dispose:()=>{if(!P){P=!0;try{z&&D.cancel(z),D.cancelAll()}catch{}z=null,B="done",T=1;try{W&&L.cancel(W),L.cancelAll()}catch{}W=null,O=1,$=null,St(),At(),ke=!1,Le.clear(),null==Jt||Jt.dispose(),Jt=null,null==Kt||Kt(),Kt=null,jt=null,Qt=null,an.clear(),null==gt||gt.dispose(),st.dispose(),lt.dispose(),hn.dispose(),rt.dispose(),ot.dispose(),at.dispose(),ut.dispose(),ct.dispose(),ft.dispose(),mt.dispose(),pt.dispose(),it.dispose(),null==Xe||Xe.dispose(),Xe=null,null==F||F.dispose(),null==w||w.dispose(),null==M||M.dispose()}}}}const Pi=["#5470C6","#91CC75","#FAC858","#EE6666","#73C0DE","#3BA272","#FC8452","#9A60B4","#EA7CCC"],Ri="#22c55e",Ei="#ef4444",Bi="#22c55e",Ti="#ef4444",Di=1,Ui=5,ki=6,Gi={grid:{left:60,right:20,top:40,bottom:40},xAxis:{type:"value"},yAxis:{type:"value",autoBounds:"visible"},autoScroll:!1,theme:"dark",palette:Pi,series:[]},zi={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:["#00E5FF","#FF2D95","#B026FF","#00F5A0","#FFD300","#FF6B00","#4D5BFF","#FF3D3D"],fontFamily:'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',fontSize:12},Vi={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:["#1F77B4","#FF7F0E","#2CA02C","#D62728","#9467BD","#8C564B","#E377C2","#17BECF"],fontFamily:'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',fontSize:12};function Li(e){return"dark"===e?zi:Vi}const Wi=e=>{if(!Array.isArray(e))return;const t=[];for(const n of e){if(null===n||"object"!=typeof n||Array.isArray(n))continue;const e=n,i=e.type;if("inside"!==i&&"slider"!==i)continue;const r=e.xAxisIndex,o=e.start,a=e.end,s=e.minSpan,l=e.maxSpan,u="number"==typeof r&&Number.isFinite(r)?r:void 0,c="number"==typeof o&&Number.isFinite(o)?o:void 0,d="number"==typeof a&&Number.isFinite(a)?a:void 0,f="number"==typeof s&&Number.isFinite(s)?s:void 0,m="number"==typeof l&&Number.isFinite(l)?l:void 0;t.push({type:i,xAxisIndex:u,start:c,end:d,minSpan:f,maxSpan:m})}return t},Oi=e=>{if(!Array.isArray(e))return;const t=[],n=e=>"start"===e||"center"===e||"end"===e,i=e=>"circle"===e||"rect"===e||"triangle"===e,r=e=>{if("string"!=typeof e)return;const t=e.trim();return t.length>0?t:void 0},o=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0,a=e=>{const t=o(e);if(null!=t)return Math.min(1,Math.max(0,t))},s=e=>{if(!Array.isArray(e))return;const t=e.filter(e=>"number"==typeof e&&Number.isFinite(e)).map(e=>e);return 0!==t.length?(Object.freeze(t),t):void 0},l=e=>{if("number"==typeof e&&Number.isFinite(e))return e;if(!Array.isArray(e)||4!==e.length)return;const t=o(e[0]),n=o(e[1]),i=o(e[2]),r=o(e[3]);return null!=t&&null!=n&&null!=i&&null!=r?[t,n,i,r]:void 0};for(const u of e){if(null===u||"object"!=typeof u||Array.isArray(u))continue;const e=u,c=e.type;if("lineX"!==c&&"lineY"!==c&&"point"!==c&&"text"!==c)continue;const d=r(e.id),f=e.layer,m="belowSeries"===f||"aboveSeries"===f?f:void 0,p=e.style,h=p&&"object"==typeof p&&!Array.isArray(p)?(()=>{const e=p,t=r(e.color),n=o(e.lineWidth),i=s(e.lineDash),l=a(e.opacity),u={...t?{color:t}:{},...null!=n?{lineWidth:n}:{},...i?{lineDash:i}:{},...null!=l?{opacity:l}:{}};return Object.keys(u).length>0?u:void 0})():void 0,g=e.label,b=g&&"object"==typeof g&&!Array.isArray(g)?(()=>{const e=g,t=r(e.text),i=r(e.template),s=e.decimals,u="number"==typeof s&&Number.isFinite(s)&&s>=0?Math.min(20,Math.floor(s)):void 0,c=e.offset,d=Array.isArray(c)&&2===c.length&&"number"==typeof c[0]&&Number.isFinite(c[0])&&"number"==typeof c[1]&&Number.isFinite(c[1])?[c[0],c[1]]:void 0,f=e.anchor,m=n(f)?f:void 0,p=e.background,h=p&&"object"==typeof p&&!Array.isArray(p)?(()=>{const e=p,t=r(e.color),n=a(e.opacity),i=l(e.padding),s=o(e.borderRadius),u={...t?{color:t}:{},...null!=n?{opacity:n}:{},...null!=i?{padding:i}:{},...null!=s?{borderRadius:s}:{}};return Object.keys(u).length>0?u:void 0})():void 0,b={...t?{text:t}:{},...i?{template:i}:{},...null!=u?{decimals:u}:{},...d?{offset:d}:{},...m?{anchor:m}:{},...h?{background:h}:{}};return Object.keys(b).length>0?b:void 0})():void 0;if("lineX"===c){const n=o(e.x);if(null==n)continue;const i={type:"lineX",x:n,...d?{id:d}:{},...m?{layer:m}:{},...h?{style:h}:{},...b?{label:b}:{}};t.push(i);continue}if("lineY"===c){const n=o(e.y);if(null==n)continue;const i={type:"lineY",y:n,...d?{id:d}:{},...m?{layer:m}:{},...h?{style:h}:{},...b?{label:b}:{}};t.push(i);continue}if("point"===c){const n=o(e.x),l=o(e.y);if(null==n||null==l)continue;const u=e.marker,c=u&&"object"==typeof u&&!Array.isArray(u)?(()=>{const e=u,t=e.symbol,n=i(t)?t:void 0,l=o(e.size),c=e.style,d=c&&"object"==typeof c&&!Array.isArray(c)?(()=>{const e=c,t=r(e.color),n=a(e.opacity),i=o(e.lineWidth),l=s(e.lineDash),u={...t?{color:t}:{},...null!=n?{opacity:n}:{},...null!=i?{lineWidth:i}:{},...l?{lineDash:l}:{}};return Object.keys(u).length>0?u:void 0})():void 0,f={...n?{symbol:n}:{},...null!=l?{size:l}:{},...d?{style:d}:{}};return Object.keys(f).length>0?f:void 0})():void 0,f={type:"point",x:n,y:l,...c?{marker:c}:{},...d?{id:d}:{},...m?{layer:m}:{},...h?{style:h}:{},...b?{label:b}:{}};t.push(f);continue}{const n=e.position,i=r(e.text);if(!i||!n||"object"!=typeof n||Array.isArray(n))continue;const a=n,s=a.space;if("data"!==s&&"plot"!==s)continue;const l=o(a.x),u=o(a.y);if(null==l||null==u)continue;const c={type:"text",position:{space:s,x:l,y:u},text:i,...d?{id:d}:{},...m?{layer:m}:{},...h?{style:h}:{},...b?{label:b}:{}};t.push(c);continue}}return 0!==t.length?(Object.freeze(t),t):void 0},_i=e=>Array.isArray(e)?e.filter(e=>"string"==typeof e).map(e=>e.trim()).filter(e=>e.length>0):[],Yi=e=>{if("string"!=typeof e)return;const t=e.trim();return t.length>0?t:void 0},Xi=e=>{if("number"!=typeof e||!Number.isFinite(e))return;const t=Math.floor(e);return t>0?t:void 0},$i=e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"global"===t||"visible"===t?t:void 0};let Hi=!1;function qi(e={}){var t,n,i,r;const o=(e=>{const t=Li("dark");if("string"==typeof e)return Li("light"===e.trim().toLowerCase()?"light":"dark");if(null===e||"object"!=typeof e||Array.isArray(e))return t;const n=e,i=e=>{const t=n[e];if("string"!=typeof t)return;const i=t.trim();return i.length>0?i:void 0},r=n.fontSize,o="number"==typeof r&&Number.isFinite(r)?r:void 0,a=_i(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:a.length>0?a:Array.from(t.colorPalette),fontFamily:i("fontFamily")??t.fontFamily,fontSize:o??t.fontSize}})(e.theme),a=e.autoScroll,s="boolean"==typeof a?a:Gi.autoScroll,l=e.animation,u=("boolean"==typeof l||null!==l&&"object"==typeof l&&!Array.isArray(l)?l:void 0)??!0,c=_i(e.palette),d=c.length>0?{...o,colorPalette:c}:o,p=_i(d.colorPalette),h=p.length>0?p:_i(Gi.palette??Pi).length>0?_i(Gi.palette??Pi):Array.from(Pi),g=h.length>0?h:["#000000"],b={...d,colorPalette:g.slice()},v={left:(null==(t=e.grid)?void 0:t.left)??Gi.grid.left,right:(null==(n=e.grid)?void 0:n.right)??Gi.grid.right,top:(null==(i=e.grid)?void 0:i.top)??Gi.grid.top,bottom:(null==(r=e.grid)?void 0:r.bottom)??Gi.grid.bottom},y=((e,t)=>{const n=!1!==(null==e?void 0:e.show),i=Yi(null==e?void 0:e.color)??t.gridLineColor,r="number"==typeof(null==e?void 0:e.opacity)&&Number.isFinite(e.opacity)?Math.min(1,Math.max(0,e.opacity)):1,o=(e,t)=>{if(1===t)return e;const n=_(e);return n?`rgba(${Math.round(255*n[0])}, ${Math.round(255*n[1])}, ${Math.round(255*n[2])}, ${n[3]*t})`:e},a=o(i,r),s=(e,t)=>{if(!1===e)return{show:!1,count:0,color:a};if(!0===e||void 0===e)return{show:n,count:t,color:a};const i=!1!==e.show&&n,s="number"==typeof e.count&&Number.isFinite(e.count)&&e.count>=0?Math.floor(e.count):t,l=Yi(e.color);return{show:i,count:s,color:null!=l?o(l,r):a}};return{show:n,color:a,opacity:r,horizontal:s(null==e?void 0:e.horizontal,Ui),vertical:s(null==e?void 0:e.vertical,ki)}})(e.gridLines,b),x=e.xAxis?{...Gi.xAxis,...e.xAxis,type:e.xAxis.type??Gi.xAxis.type,autoBounds:$i(e.xAxis.autoBounds)??Gi.xAxis.autoBounds}:{...Gi.xAxis},w=e.yAxis?{...Gi.yAxis,...e.yAxis,type:e.yAxis.type??Gi.yAxis.type,autoBounds:$i(e.yAxis.autoBounds)??Gi.yAxis.autoBounds}:{...Gi.yAxis},M=(e.series??[]).map((e,t)=>{var n,i,r,o,a,s,l,u,c,d;const p=Yi(e.color),h=b.colorPalette[t%b.colorPalette.length],g=p??h,v=!1!==e.visible,y=(e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"none"===t||"lttb"===t||"average"===t||"max"===t||"min"===t||"ohlc"===t?t:void 0})(e.sampling)??"lttb",x=Xi(e.samplingThreshold)??5e3;switch(e.type){case"area":{const t=Yi(null==(n=e.areaStyle)?void 0:n.color)??p??h,r={opacity:(null==(i=e.areaStyle)?void 0:i.opacity)??.25,color:t},o=f(e.data)??void 0,a=m(e.data)?e.data:N(e.data,y,x);return{...e,visible:v,rawData:e.data,data:a,color:t,areaStyle:r,sampling:y,samplingThreshold:x,rawBounds:o,connectNulls:e.connectNulls??!1}}case"line":{const t=Yi(null==(r=e.lineStyle)?void 0:r.color)??p??h,n={width:(null==(o=e.lineStyle)?void 0:o.width)??2,opacity:(null==(a=e.lineStyle)?void 0:a.opacity)??1,color:t},{areaStyle:i,...s}=e,l=f(e.data)??void 0,u=m(e.data)?e.data:N(e.data,y,x);return{...s,visible:v,rawData:e.data,data:u,color:t,lineStyle:n,...e.areaStyle?{areaStyle:{opacity:e.areaStyle.opacity??.25,color:Yi(e.areaStyle.color)??t}}:{},sampling:y,samplingThreshold:x,rawBounds:l,connectNulls:e.connectNulls??!1}}case"bar":{const t=f(e.data)??void 0;return{...e,visible:v,rawData:e.data,data:N(e.data,y,x),color:g,sampling:y,samplingThreshold:x,rawBounds:t}}case"scatter":{const t=f(e.data)??void 0,n=(e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"points"===t||"density"===t?t:void 0})(e.mode)??"points",i=(e=>{if("number"!=typeof e||!Number.isFinite(e))return;const t=Math.floor(e);return t>0?Math.max(1,t):void 0})(e.binSize)??2,r=(e=>{if("string"==typeof e){const t=e.trim().toLowerCase();return"viridis"===t||"plasma"===t||"inferno"===t?t:void 0}if(!Array.isArray(e))return;if(e.length>0&&e.every(e=>"string"==typeof e&&e.length>0&&e===e.trim())){const t=e;return Object.isFrozen(t)||Object.freeze(t),t}const t=e.filter(e=>"string"==typeof e).map(e=>e.trim()).filter(e=>e.length>0);return 0!==t.length?(Object.freeze(t),t):void 0})(e.densityColormap)??"viridis",o=(e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"linear"===t||"sqrt"===t||"log"===t?t:void 0})(e.densityNormalization)??"log";return{...e,visible:v,rawData:e.data,data:N(e.data,y,x),color:g,mode:n,binSize:i,densityColormap:r,densityNormalization:o,sampling:y,samplingThreshold:x,rawBounds:t}}case"pie":{const{sampling:n,samplingThreshold:i,...r}=e;return{...r,visible:v,color:g,data:(e.data??[]).map((e,n)=>{const i=Yi(null==e?void 0:e.color),r=b.colorPalette[(t+n)%b.colorPalette.length],o=!1!==(null==e?void 0:e.visible);return{...e,color:i??r,visible:o}})}}case"candlestick":{Hi||(console.warn("ChartGPU: Candlestick series rendering is not yet implemented. Series will be skipped."),Hi=!0);const t=(e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"none"===t||"ohlc"===t?t:void 0})(e.sampling)??"ohlc",n=Xi(e.samplingThreshold)??5e3,i={upColor:Yi(null==(s=e.itemStyle)?void 0:s.upColor)??Ri,downColor:Yi(null==(l=e.itemStyle)?void 0:l.downColor)??Ei,upBorderColor:Yi(null==(u=e.itemStyle)?void 0:u.upBorderColor)??Bi,downBorderColor:Yi(null==(c=e.itemStyle)?void 0:c.downBorderColor)??Ti,borderWidth:"number"==typeof(null==(d=e.itemStyle)?void 0:d.borderWidth)&&Number.isFinite(e.itemStyle.borderWidth)?e.itemStyle.borderWidth:Di},r=(e=>{if(0===e.length)return;let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;if((e=>Array.isArray(e))(e[0])){const o=e;for(let e=0;en&&(n=s),cr&&(r=d)}}else{const o=e;for(let e=0;en&&(n=s),cr&&(r=d)}}return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)?(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r}):void 0})(e.data),o="ohlc"===t&&e.data.length>n?C(e.data,n):e.data;return{...e,visible:v,rawData:e.data,data:o,color:g,style:e.style??"classic",itemStyle:i,barWidth:e.barWidth??"80%",barMinWidth:e.barMinWidth??1,barMaxWidth:e.barMaxWidth??50,sampling:t,samplingThreshold:n,rawBounds:r}}default:return(e=>{throw new Error(`Unhandled series type: ${(null==e?void 0:e.type)??"unknown"}`)})(e)}});return{grid:v,gridLines:y,xAxis:x,yAxis:w,autoScroll:s,dataZoom:Wi(e.dataZoom),annotations:Oi(e.annotations),animation:u,theme:b,palette:b.colorPalette,series:M,legend:e.legend}}function ji(e={}){const t={...qi(e),tooltip:e.tooltip};return(e=>{var t;return(null==(t=e.dataZoom)?void 0:t.some(e=>"slider"===(null==e?void 0:e.type)))??!1})(e)?{...t,grid:{...t.grid,bottom:t.grid.bottom+40}}:t}const Zi=(e,t,n)=>Math.min(n,Math.max(t,e));function Ji(e,t,n){const i=null==n?void 0:n.height,r=null==n?void 0:n.marginTop,o=(null==n?void 0:n.zIndex)??4,a=(null==n?void 0:n.showPreview)??!1,s=document.createElement("div");s.style.display="block",s.style.width="100%",s.style.height=`${i}px`,s.style.marginTop=`${r}px`,s.style.boxSizing="border-box",s.style.position="relative",s.style.zIndex=`${o}`,s.style.userSelect="none",s.style.touchAction="none";const l=document.createElement("div");l.style.position="relative",l.style.height="100%",l.style.width="100%",l.style.boxSizing="border-box",l.style.borderRadius="8px",l.style.borderStyle="solid",l.style.borderWidth="1px",l.style.overflow="hidden",s.appendChild(l);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=a?"block":"none",l.appendChild(u);const c=document.createElement("div");c.style.position="absolute",c.style.top="0",c.style.bottom="0",c.style.left="0%",c.style.width="100%",c.style.boxSizing="border-box",c.style.cursor="grab",l.appendChild(c);const d=document.createElement("div");d.style.position="absolute",d.style.left="0",d.style.top="0",d.style.bottom="0",d.style.width="10px",d.style.cursor="ew-resize",c.appendChild(d);const f=document.createElement("div");f.style.position="absolute",f.style.right="0",f.style.top="0",f.style.bottom="0",f.style.width="10px",f.style.cursor="ew-resize",c.appendChild(f);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",c.appendChild(m),e.appendChild(s);let p=!1,h=null;const g=e=>{const t=(e=>{let{start:t,end:n}=e;if(t>n){const e=t;t=n,n=e}return{start:Zi(t,0,100),end:Zi(n,0,100)}})(e),n=Zi(t.end-t.start,0,100);c.style.left=`${t.start}%`,c.style.width=`${n}%`},b=(e,n)=>{if(p||0!==e.button)return;e.preventDefault(),null==h||h(),h=null;const i=e.clientX,r=t.getRange(),o=e.currentTarget instanceof Element?e.currentTarget:c;((e,t)=>{try{e.setPointerCapture(t)}catch{}})(o,e.pointerId),"pan-window"===n&&(c.style.cursor="grabbing",m.style.cursor="grabbing");const a=o=>{if(p||o.pointerId!==e.pointerId)return;o.preventDefault();const a=(e=>{const t=(()=>{const e=l.getBoundingClientRect().width;return Number.isFinite(e)&&e>0?e:null})();if(null===t)return null;const n=e/t*100;return Number.isFinite(n)?n:null})(o.clientX-i);if(null!==a)switch(n){case"left-handle":{const e=Math.min(r.end,r.start+a),n=t;return void(n.setRangeAnchored?n.setRangeAnchored(e,r.end,"end"):t.setRange(e,r.end))}case"right-handle":{const e=Math.max(r.start,r.end+a),n=t;return void(n.setRangeAnchored?n.setRangeAnchored(r.start,e,"start"):t.setRange(r.start,e))}case"pan-window":return void t.setRange(r.start+a,r.end+a)}};let s=!1;const u=()=>{s||(s=!0,window.removeEventListener("pointermove",a),window.removeEventListener("pointerup",d),window.removeEventListener("pointercancel",d),"pan-window"===n&&(c.style.cursor="grab",m.style.cursor="grab"),((e,t)=>{try{e.releasePointerCapture(t)}catch{}})(o,e.pointerId),h===u&&(h=null))},d=t=>{t.pointerId===e.pointerId&&u()};h=u,window.addEventListener("pointermove",a,{passive:!1}),window.addEventListener("pointerup",d,{passive:!0}),window.addEventListener("pointercancel",d,{passive:!0})},v=e=>b(e,"left-handle"),y=e=>b(e,"right-handle"),x=e=>b(e,"pan-window");d.addEventListener("pointerdown",v,{passive:!1}),f.addEventListener("pointerdown",y,{passive:!1}),m.addEventListener("pointerdown",x,{passive:!1});const w=t.onChange(e=>{p||g(e)});return g(t.getRange()),{update:e=>{if(p)return;l.style.background=e.backgroundColor,l.style.borderColor=e.axisLineColor,u.style.background=e.gridLineColor,c.style.background=e.gridLineColor,c.style.border=`1px solid ${e.axisTickColor}`,c.style.borderRadius="8px",c.style.boxSizing="border-box";const t=`1px solid ${e.axisLineColor}`;d.style.background=e.axisTickColor,d.style.borderRight=t,f.style.background=e.axisTickColor,f.style.borderLeft=t,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(!p){p=!0,null==h||h(),h=null;try{w()}catch{}d.removeEventListener("pointerdown",v),f.removeEventListener("pointerdown",y),m.removeEventListener("pointerdown",x),s.remove()}}}}let Ki=null;const Qi=120,er=e=>Array.isArray(e),tr=e=>(e=>Array.isArray(e))(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},nr=e=>{const t=s(e);if(0===t)return{x:[],y:[]};const n=new Array(t),i=new Array(t),r=[];let o=!1;for(let a=0;aer(e)?e[0]:e.timestamp,rr=e=>er(e)?e[2]:e.close,or=(e,t,n)=>Math.min(n,Math.max(t,e)),ar=(e,t)=>{let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(let a=0;ai&&(i=e.xMax),e.yMino&&(o=e.yMax);continue}}const u=s.rawBounds??null;if(u){const e=u;if(Number.isFinite(e.xMin)&&Number.isFinite(e.xMax)&&Number.isFinite(e.yMin)&&Number.isFinite(e.yMax)){e.xMini&&(i=e.xMax),e.yMino&&(o=e.yMax);continue}}if("candlestick"===s.type){const e=s.data;for(let t=0;ti&&(i=s),lo&&(o=u))}continue}const c=f(s.data);c&&(c.xMini&&(i=c.xMax),c.yMino&&(o=c.yMax))}return Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(o)?(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o}):{xMin:0,xMax:1,yMin:0,yMax:1}},sr=(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 e=n;n=i,i=e}return{min:n,max:i}},lr=(e,t)=>{if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"!=typeof e)return null;const n=e.trim();if(0===n.length)return null;if(n.endsWith("%")){const e=Number.parseFloat(n.slice(0,-1));return Number.isFinite(e)?e/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},ur=(e,t,n)=>{const i=(null==e?void 0:e[0])??"50%",r=(null==e?void 0:e[1])??"50%",o=lr(i,t),a=lr(r,n);return{x:Number.isFinite(o)?o:.5*t,y:Number.isFinite(a)?a:.5*n}},cr=(e,t)=>{if(null==e)return{inner:0,outer:.7*t};if((e=>Array.isArray(e))(e)){const n=lr(e[0],t),i=lr(e[1],t),r=Math.max(0,Number.isFinite(n)?n:0),o=Math.max(r,Number.isFinite(i)?i:.7*t);return{inner:r,outer:Math.min(t,o)}}const n=lr(e,t),i=Math.max(0,Number.isFinite(n)?n:.7*t);return{inner:0,outer:Math.min(t,i)}},dr={create:async function(e,t,n){var r;if(n){if(typeof navigator>"u"||!navigator.gpu)throw new Error("ChartGPU: Shared device mode requires WebGPU globals (navigator.gpu) to be available.")}else{const e=await async function(){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}`)):t=e instanceof Error?`Failed to request WebGPU adapter: ${e.message}`:`Failed to request WebGPU adapter: ${String(e)}`,{supported:!1,reason:t}}})(),Ki)}();if(!e.supported){const t=e.reason||"Unknown reason";throw new Error(`ChartGPU: WebGPU is not available.\nReason: ${t}\nBrowser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.\nResources:\n - MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API\n - Browser compatibility: https://caniuse.com/webgpu\n - WebGPU specification: https://www.w3.org/TR/webgpu/\n - Check your system: https://webgpureport.org/`)}}if(null!=n&&n.pipelineCache&&n.pipelineCache.device!==n.device)throw new Error("ChartGPU: pipelineCache.device must match the GPUDevice in the creation context. Create the pipeline cache with the same device: createPipelineCache(device).");const o=document.createElement("canvas");o.style.display="block",o.style.width="100%",o.style.height="100%",e.appendChild(o);const a=!!n;let d,m=!1,p=t.renderMode??"auto",h=!1,g=!1,b=null,v=null,y=null,x=null,w=null,M=!1,F=null,N=null,C=null,S=t,A=ji(S),I=new Array(A.series.length).fill(null).map(()=>({x:[],y:[]})),P=new Array(A.series.length).fill(null),R=null;const E=()=>{I=new Array(A.series.length).fill(null).map(()=>({x:[],y:[]})),P=new Array(A.series.length).fill(null),R=null;for(let e=0;eR||(R=A.series.map((e,t)=>{if("pie"===e.type)return e;if("candlestick"===e.type)return{...e,data:I[t]??e.data};const n=I[t];return{...e,data:n}}),R);E();let T=ar(A.series,P),D=null;const U={click:new Set,mouseover:new Set,mouseout:new Set,crosshairMove:new Set,zoomRangeChange:new Set,deviceLost:new Set,dataAppend:new Set};let k=!1,G=null,z=null,V=null;const L=new Set;let W=null,O=null,_=!0;const Y=new Float64Array(Qi);let X=0,$=0,H=0,q=0,j=0,Z=0;const J=performance.now();let K=0,Q=0;const ee=new Set,te=()=>U.mouseover.size>0||U.mouseout.size>0,ne=()=>U.click.size>0,ie=()=>{null!==W&&(cancelAnimationFrame(W),W=null)},re=e=>{if(m||g||h)return;h=!0;const t=performance.now();try{if(Y[X]=t,X=(X+1)%Qi,$0&&(t-K>25?(q++,j++,Z=t):j=0),K=t),ye(!1),!v||null==b||!b.device)return;if(_){_=!1;try{v.render()}catch{_=!0}}Q=performance.now()-t;const n=we();for(const e of ee)try{e(n)}catch(e){console.error("Error in performance update callback:",e)}}finally{h=!1}},oe=()=>{m||(_=!0,"external"!==p&&null===W&&(W=requestAnimationFrame(()=>{W=null,!m&&re(!0)})))},ae=()=>{if(x)try{x()}finally{x=null}},se=()=>{if(w)try{w()}finally{w=null}},le=()=>{null==N||N.dispose(),N=null},ue=()=>{le(),null==F||F.remove(),F=null},ce=(e,t)=>{const n=e.end-e.start;return Number.isFinite(n)&&0!==n?or((t-e.start)/n,0,1):.5},de=()=>({getRange:()=>(null==v?void 0:v.getZoomRange())??{start:0,end:100},setRange:(e,t)=>{null==v||v.setZoomRange(e,t)},zoomIn:(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||t<=1)return;const n=null==v?void 0:v.getZoomRange();if(!n)return;const i=or(e,0,100),r=ce(n,i),o=(n.end-n.start)/t,a=i-r*o;null==v||v.setZoomRange(a,a+o)},zoomOut:(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||t<=1)return;const n=null==v?void 0:v.getZoomRange();if(!n)return;const i=or(e,0,100),r=ce(n,i),o=(n.end-n.start)*t,a=i-r*o;null==v||v.setZoomRange(a,a+o)},pan:e=>{if(!Number.isFinite(e))return;const t=null==v?void 0:v.getZoomRange();t&&(null==v||v.setZoomRange(t.start+e,t.end+e))},onChange:e=>(null==v?void 0:v.onZoomRangeChange(e))??(()=>{})}),fe=()=>{if(!(e=>{var t;return(null==(t=e.dataZoom)?void 0:t.some(e=>"slider"===(null==e?void 0:e.type)))??!1})(S))return void ue();if(!v||!v.getZoomRange())return;const t=(()=>{if(F)return F;try{"static"===window.getComputedStyle(e).position&&(e.style.position="relative")}catch{}const t=document.createElement("div");return t.style.position="absolute",t.style.left="0",t.style.right="0",t.style.bottom="0",t.style.height="40px",t.style.paddingTop="8px",t.style.boxSizing="border-box",t.style.pointerEvents="auto",t.style.zIndex="5",e.appendChild(t),F=t,t})();N||(N=Ji(t,de(),{height:32,marginTop:0})),N.update(A.theme)},me=()=>{null==C||C.dispose(),C=null},pe=()=>{(e=>{var t;return(null==(t=e.dataZoom)?void 0:t.some(e=>"inside"===(null==e?void 0:e.type)))??!1})(S)?v&&v.getZoomRange()&&(C?C.update(A.theme):C=function(e,t,n){let i=!1;const r=typeof navigator<"u"&&navigator.maxTouchPoints>0,o=document.createElement("button");o.setAttribute("data-chartgpu-zoom-reset",""),o.setAttribute("aria-label","Reset zoom"),o.type="button",o.style.position="absolute",o.style.top="8px",o.style.right="8px",o.style.zIndex="10",o.style.width="32px",o.style.height="32px",o.style.border="none",o.style.borderRadius="6px",o.style.cursor="pointer",o.style.display="none",o.style.alignItems="center",o.style.justifyContent="center",o.style.fontSize="16px",o.style.lineHeight="1",o.style.padding="0",o.style.touchAction="manipulation",o.textContent="↺";const a=e=>{o.style.backgroundColor=e.backgroundColor,o.style.opacity="0.8",o.style.color=e.textColor};a(n);const s=()=>{if(!r)return void(o.style.display="none");const{start:e,end:n}=t.getRange();o.style.display=((e,t)=>e<=.01&&t>=99.99)(e,n)?"none":"flex"};s();const l=()=>{i||t.setRange(0,100)};o.addEventListener("click",l);const u=t.onChange(()=>{i||s()});return e.appendChild(o),{update(e){i||a(e)},dispose(){if(!i){i=!0,o.removeEventListener("click",l);try{u()}catch{}o.remove()}}}}(e,de(),A.theme)):me()},he={x:null,source:void 0},ge={start:0,end:100,source:void 0,sourceKind:void 0},be={seriesIndex:0,count:0,xExtent:{min:0,max:0}},ve=()=>{if(m||!b||!b.initialized)return;const e=(null==v?void 0:v.getZoomRange())??null;ae(),se(),le(),me(),null==v||v.dispose(),M=!1,d=void 0;const t={onRequestRender:oe,pipelineCache:null==n?void 0:n.pipelineCache};v=Ii(b,A,t),y=b.preferredFormat,ae(),!m&&v&&(x=v.onInteractionXChange((e,t)=>{he.x=e,he.source=t,Fe("crosshairMove",he)})),se(),!m&&v&&(w=v.onZoomRangeChange((e,t)=>{const n=M,i=d;M=!1,d=void 0;const r=void 0!==i?i:void 0,o=t??(n?"api":void 0);ge.start=e.start,ge.end=e.end,ge.source=r,ge.sourceKind=o,Fe("zoomRangeChange",ge)})),e&&v.setZoomRange(e.start,e.end),fe(),pe()},ye=e=>{var t;if(m)return;const n=o.getBoundingClientRect(),i=window.devicePixelRatio||1,r=(null==(t=null==b?void 0:b.device)?void 0:t.limits.maxTextureDimension2D)??8192,a=Math.min(r,Math.max(1,Math.round(n.width*i))),s=Math.min(r,Math.max(1,Math.round(n.height*i))),l=o.width!==a||o.height!==s;l&&(o.width=a,o.height=s);const u=null==b?void 0:b.device,c=null==b?void 0:b.canvasContext,d=null==b?void 0:b.preferredFormat;let f=!1;u&&c&&d&&(l||!O||O.width!==o.width||O.height!==o.height||O.format!==d)&&(c.configure({device:u,format:d,alphaMode:"opaque"}),O={width:o.width,height:o.height,format:d},f=!0,v&&y!==d&&ve()),e&&(l||f)&&oe()},xe=e=>{const t=o.getBoundingClientRect();if(!(t.width>0&&t.height>0))return{match:null,isInGrid:!1};const n=e.clientX-t.left,i=e.clientY-t.top,r=A.grid.left,a=A.grid.top,s=t.width-A.grid.left-A.grid.right,l=t.height-A.grid.top-A.grid.bottom;if(!(s>0&&l>0))return{match:null,isInGrid:!1};const u=n-r,c=i-a;if(!(u>=0&&u<=s&&c>=0&&c<=l))return{match:null,isInGrid:!1};const d=A.xAxis.min??T.xMin,f=A.xAxis.max??T.xMax,m=A.yAxis.min??T.yMin,p=A.yAxis.max??T.yMax,h=sr(d,f),g=(null==v?void 0:v.getZoomRange())??null,b=(()=>{if(!g)return h;const e=h.max-h.min;if(!Number.isFinite(e)||0===e)return h;const t=g.start,n=g.end,i=h.min+t/100*e,r=h.min+n/100*e;return sr(i,r)})(),y=sr(m,p);if(null===D||D.rectWidthCss!==t.width||D.rectHeightCss!==t.height||D.plotWidthCss!==s||D.plotHeightCss!==l||D.xDomainMin!==b.min||D.xDomainMax!==b.max||D.yDomainMin!==y.min||D.yDomainMax!==y.max){const e=Mn().domain(b.min,b.max).range(0,s),n=Mn().domain(y.min,y.max).range(l,0);D={rectWidthCss:t.width,rectHeightCss:t.height,plotWidthCss:s,plotHeightCss:l,xDomainMin:b.min,xDomainMax:b.max,yDomainMin:y.min,yDomainMax:y.max,xScale:e,yScale:n}}const x=D,w=(()=>{const e=.5*Math.min(s,l);if(!(e>0))return null;for(let t=A.series.length-1;t>=0;t--){const n=A.series[t];if("pie"!==n.type||!1===n.visible)continue;const i=n,r=ur(i.center,s,l),o=cr(i.radius,e),a=xn(u,c,{seriesIndex:t,series:i},r,o);if(!a)continue;const d=a.slice.value;return{kind:"pie",seriesIndex:a.seriesIndex,dataIndex:a.dataIndex,sliceValue:"number"==typeof d&&Number.isFinite(d)?d:0}}return null})();if(w)return{match:w,isInGrid:!0};for(let e=A.series.length-1;e>=0;e--){const t=A.series[e];if("candlestick"!==(null==t?void 0:t.type)||!1===t.visible)continue;const n=t,i=mn(n,n.data,x.xScale,s),r=bn([n],u,c,x.xScale,x.yScale,i);if(r)return{match:{kind:"candlestick",seriesIndex:e,dataIndex:r.dataIndex,point:r.point},isInGrid:!0}}const M=Ne(B(),u,c,x.xScale,x.yScale);return{match:M?{kind:"cartesian",match:M}:null,isInGrid:!0}},we=()=>{const e=(()=>{if($<2)return 0;const e=(X-$+Qi)%Qi;let t=0;for(let n=1;n<$;n++){const i=(e+n-1)%Qi;t+=Y[(e+n)%Qi]-Y[i]}const n=t/($-1);return n>0?1e3/n:0})(),t=(()=>{if($<2)return{min:0,max:0,avg:0,p50:0,p95:0,p99:0};const e=(X-$+Qi)%Qi,t=new Array($-1);let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=0;for(let o=1;o<$;o++){const a=(e+o-1)%Qi,s=Y[(e+o)%Qi]-Y[a];t[o-1]=s,si&&(i=s),r+=s}const o=r/t.length;t.sort((e,t)=>e-t);const a=Math.floor(.5*t.length),s=Math.floor(.95*t.length),l=Math.floor(.99*t.length);return{min:n,max:i,avg:o,p50:t[a],p95:t[s],p99:t[l]}})(),n={enabled:!1,cpuTime:Q,gpuTime:0},i="external"===p?{totalDrops:0,consecutiveDrops:0,lastDropTimestamp:0}:{totalDrops:q,consecutiveDrops:j,lastDropTimestamp:Z},r=performance.now()-J;return{fps:e,frameTimeStats:t,gpuTiming:n,memory:{used:0,peak:0,allocated:0},frameDrops:i,totalFrames:H,elapsedTime:r}},Me=(e,t)=>{if(!e)return{seriesIndex:null,dataIndex:null,value:null,seriesName:null,event:t};const n="cartesian"===e.kind?e.match.seriesIndex:e.seriesIndex,i="cartesian"===e.kind?e.match.dataIndex:e.dataIndex,r=A.series[n],o=(null==r?void 0:r.name)??null,a=o&&o.trim().length>0?o:null;if("pie"===e.kind)return{seriesIndex:n,dataIndex:i,value:[0,e.sliceValue],seriesName:a,event:t};if("candlestick"===e.kind)return{seriesIndex:n,dataIndex:i,value:[ir(e.point),rr(e.point)],seriesName:a,event:t};const{x:s,y:l}=tr(e.match.point);return{seriesIndex:n,dataIndex:i,value:[s,l],seriesName:a,event:t}},Fe=(e,t)=>{if(!m)for(const n of U[e])n(t)},Ce=(e,t)=>{const n=V;if(V=e,null===n&&null===e)return;if(null===n&&null!==e)return void Fe("mouseover",Me(e,t));if(null!==n&&null===e)return void Fe("mouseout",Me(n,t));if(null===n||null===e)return;const i="cartesian"===n.kind?n.match.seriesIndex:n.seriesIndex,r="cartesian"===n.kind?n.match.dataIndex:n.dataIndex,o="cartesian"===e.kind?e.match.seriesIndex:e.seriesIndex,a="cartesian"===e.kind?e.match.dataIndex:e.dataIndex;i===o&&r===a||(Fe("mouseout",Me(n,t)),Fe("mouseover",Me(e,t)))},Se=e=>{G&&e.isPrimary&&e.pointerId===G.pointerId&&(G=null)},Ae=e=>{if(m||!te())return;const{match:t,isInGrid:n}=xe(e);Ce(n?t:null,e)},Ie=e=>{m||!te()&&!G||(Se(e),Ce(null,e))},Pe=e=>{m||!te()&&!G||(Se(e),Ce(null,e))},Re=e=>{if(!m&&(te()||G||z===e.pointerId)){if(z===e.pointerId)return void(z=null);Se(e),Ce(null,e)}},Ee=e=>{if(!m&&ne()&&e.isPrimary&&("mouse"!==e.pointerType||0===e.button)){G={pointerId:e.pointerId,startClientX:e.clientX,startClientY:e.clientY,startTimeMs:e.timeStamp};try{o.setPointerCapture(e.pointerId)}catch{}}},Be=e=>{if(m||!ne()||!e.isPrimary||!G||e.pointerId!==G.pointerId)return;const t=e.timeStamp-G.startTimeMs,n=e.clientX-G.startClientX,i=e.clientY-G.startClientY,r=n*n+i*i;G=null;try{o.hasPointerCapture(e.pointerId)&&(z=e.pointerId,o.releasePointerCapture(e.pointerId))}catch{}if(!(t<=500&&r<=36))return;const{match:a}=xe(e);Fe("click",Me(a,e))};o.addEventListener("pointermove",Ae,{passive:!0}),o.addEventListener("pointerleave",Ie,{passive:!0}),o.addEventListener("pointercancel",Pe,{passive:!0}),o.addEventListener("lostpointercapture",Re,{passive:!0}),o.addEventListener("pointerdown",Ee,{passive:!0}),o.addEventListener("pointerup",Be,{passive:!0});const Te=()=>{if(!m){m=!0;try{ie(),ue(),me(),ae(),se(),null==v||v.dispose(),v=null,y=null,null==b||b.destroy()}finally{G=null,z=null,V=null,D=null,M=!1,d=void 0,o.removeEventListener("pointermove",Ae),o.removeEventListener("pointerleave",Ie),o.removeEventListener("pointercancel",Pe),o.removeEventListener("lostpointercapture",Re),o.removeEventListener("pointerdown",Ee),o.removeEventListener("pointerup",Be),U.click.clear(),U.mouseover.clear(),U.mouseout.clear(),U.crosshairMove.clear(),U.zoomRangeChange.clear(),U.deviceLost.clear(),U.dataAppend.clear(),k=!1,b=null,o.remove()}}},De={get options(){return S},get disposed(){return m},setOption(e){m||(S=e,A=ji(e),null==v||v.setOptions(A),E(),T=ar(A.series,P),D=null,fe(),pe(),oe())},appendData(e,t){if(m||!Number.isFinite(e)||e<0||e>=A.series.length)return;const n=A.series[e];if("pie"===n.type)return void(L.has(e)||(L.add(e),console.warn(`ChartGPU.appendData(${e}, ...): pie series are not supported by streaming append. Use setOption(...) to replace pie data.`)));let i=0;if("candlestick"===n.type){if(!Array.isArray(t))return;i=t.length}else i=s(t);if(0===i)return;null==v||v.appendData(e,t);let r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;if("candlestick"===n.type){const n=I[e],a=Array.isArray(n)?n:[],s=t;if(k)for(let e=0;eo&&(o=t))}a.push(...s),I[e]=a,P[e]=((e,t)=>{if(0===t.length)return e;let n=(null==e?void 0:e.xMin)??Number.POSITIVE_INFINITY,i=(null==e?void 0:e.xMax)??Number.NEGATIVE_INFINITY,r=(null==e?void 0:e.yMin)??Number.POSITIVE_INFINITY,o=(null==e?void 0:e.yMax)??Number.NEGATIVE_INFINITY;for(let e=0;ei&&(i=s),lo&&(o=u))}return Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(o)?(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o}):e})(P[e],s)}else{const n=I[e],a=t,d="object"==typeof a&&null!==a&&!Array.isArray(a)&&"x"in a&&"y"in a,m="object"==typeof a&&null!==a&&!Array.isArray(a)&&ArrayBuffer.isView(a);let p=!1;const h=new Array(i);if(d){const e=a;for(let t=0;to&&(o=i))}if(e.size){p=!0;for(let t=0;to&&(o=i))}}else for(let e=0;eo&&(o=t))}(n.size||p)&&(n.size||(n.size=new Array(n.x.length-i)),n.size.push(...h)),P[e]=((e,t)=>{const n=s(t);if(0===n)return e;let i=e;if(!i)return f(t);let r=i.xMin,o=i.xMax,a=i.yMin,c=i.yMax;const d="object"==typeof t&&null!==t&&!Array.isArray(t)&&"x"in t&&"y"in t,m="object"==typeof t&&null!==t&&!Array.isArray(t)&&ArrayBuffer.isView(t);if(d){const e=t;for(let t=0;to&&(o=n),ic&&(c=i))}}else if(m){const e=t;for(let t=0;to&&(o=n),ic&&(c=i))}}else for(let e=0;eo&&(o=n),ic&&(c=i))}return r===o&&(o=r+1),a===c&&(c=a+1),{xMin:r,xMax:o,yMin:a,yMax:c}})(P[e],a)}T=ar(A.series,P),R=null,D=null,oe(),k&&((!Number.isFinite(r)||!Number.isFinite(o))&&(r=0,o=0),be.seriesIndex=e,be.count=i,be.xExtent.min=r,be.xExtent.max=o,Fe("dataAppend",be))},renderFrame(){if(m||g)return!1;if("auto"===p)return console.warn('renderFrame() called in auto mode - this is a no-op. Set renderMode to "external" to use manual rendering.'),!1;if(h||!v||null==b||!b.device||!_)return!1;try{return re(!1),!0}catch{return!1}},needsRender:()=>!m&&_,getRenderMode:()=>p,setRenderMode(e){if(!m){if("auto"!==e&&"external"!==e)return void console.warn(`setRenderMode(): invalid mode '${String(e)}', ignoring.`);p!==e&&(K=0,q=0,j=0,Z=0,X=0,$=0,p=e,"external"===e?ie():_&&oe())}},resize:()=>ye(!0),dispose:Te,on(e,t){m||(U[e].add(t),"dataAppend"===e&&(k=!0))},off(e,t){U[e].delete(t),"dataAppend"===e&&(k=U.dataAppend.size>0)},getInteractionX:()=>m?null:(null==v?void 0:v.getInteractionX())??null,setInteractionX(e,t){m||null==v||v.setInteractionX(e,t)},setCrosshairX(e,t){m||null==v||v.setInteractionX(e,t)},onInteractionXChange:e=>m?()=>{}:(null==v?void 0:v.onInteractionXChange(e))??(()=>{}),getZoomRange:()=>m?null:(null==v?void 0:v.getZoomRange())??null,setZoomRange(e,t,n){if(m||!v)return;const i=v.getZoomRange();if(!i)return;M=!0,d=n,v.setZoomRange(e,t);const r=v.getZoomRange();(!r||r.start===i.start&&r.end===i.end)&&(M=!1,d=void 0)},getPerformanceMetrics:()=>m?null:we(),getPerformanceCapabilities:()=>m?null:{gpuTimingSupported:!1,highResTimerSupported:typeof performance<"u"&&"function"==typeof performance.now,performanceMetricsSupported:!0},onPerformanceUpdate:e=>m?()=>{}:(ee.add(e),()=>{ee.delete(e)}),hitTest(e){const t=o.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(m||!(t.width>0)||!(t.height>0))return{isInGrid:!1,canvasX:n,canvasY:i,gridX:0,gridY:0,match:null};const r=A.grid.left,a=A.grid.top,s=t.width-A.grid.left-A.grid.right,l=t.height-A.grid.top-A.grid.bottom,u=n-r,c=i-a;if(!(s>0&&l>0))return{isInGrid:!1,canvasX:n,canvasY:i,gridX:u,gridY:c,match:null};if(!(u>=0&&u<=s&&c>=0&&c<=l))return{isInGrid:!1,canvasX:n,canvasY:i,gridX:u,gridY:c,match:null};const d=A.xAxis.min??T.xMin,f=A.xAxis.max??T.xMax,p=A.yAxis.min??T.yMin,h=A.yAxis.max??T.yMax,g=sr(d,f),b=(null==v?void 0:v.getZoomRange())??null,y=(()=>{if(!b)return g;const e=g.max-g.min;if(!Number.isFinite(e)||0===e)return g;const t=b.start,n=b.end,i=g.min+t/100*e,r=g.min+n/100*e;return sr(i,r)})(),x=sr(p,h);if(null===D||D.rectWidthCss!==t.width||D.rectHeightCss!==t.height||D.plotWidthCss!==s||D.plotHeightCss!==l||D.xDomainMin!==y.min||D.xDomainMax!==y.max||D.yDomainMin!==x.min||D.yDomainMax!==x.max){const e=Mn().domain(y.min,y.max).range(0,s),n=Mn().domain(x.min,x.max).range(l,0);D={rectWidthCss:t.width,rectHeightCss:t.height,plotWidthCss:s,plotHeightCss:l,xDomainMin:y.min,xDomainMax:y.max,yDomainMin:x.min,yDomainMax:x.max,xScale:e,yScale:n}}const w=D,M=(()=>{const e=.5*Math.min(s,l);if(!(e>0))return null;for(let t=A.series.length-1;t>=0;t--){const n=A.series[t];if("pie"!==n.type||!1===n.visible)continue;const i=n,r=ur(i.center,s,l),o=cr(i.radius,e),a=xn(u,c,{seriesIndex:t,series:i},r,o);if(!a)continue;const d=a.slice.value;return{kind:"pie",seriesIndex:a.seriesIndex,dataIndex:a.dataIndex,sliceValue:"number"==typeof d&&Number.isFinite(d)?d:0}}return null})();if(M)return{isInGrid:!0,canvasX:n,canvasY:i,gridX:u,gridY:c,match:{kind:"pie",seriesIndex:M.seriesIndex,dataIndex:M.dataIndex,value:[0,M.sliceValue]}};for(let e=A.series.length-1;e>=0;e--){const t=A.series[e];if("candlestick"!==(null==t?void 0:t.type)||!1===t.visible)continue;const r=t,o=mn(r,r.data,w.xScale,s),a=bn([r],u,c,w.xScale,w.yScale,o);if(!a)continue;const l=ir(a.point),d=rr(a.point);return{isInGrid:!0,canvasX:n,canvasY:i,gridX:u,gridY:c,match:{kind:"candlestick",seriesIndex:e,dataIndex:a.dataIndex,value:[l,d]}}}const F=Ne(B(),u,c,w.xScale,w.yScale);if(F){const{x:e,y:t}=tr(F.point);return{isInGrid:!0,canvasX:n,canvasY:i,gridX:u,gridY:c,match:{kind:"cartesian",seriesIndex:F.seriesIndex,dataIndex:F.dataIndex,value:[e,t]}}}return{isInGrid:!0,canvasX:n,canvasY:i,gridX:u,gridY:c,match:null}}};try{ye(!1);try{const e=n?{device:n.device,adapter:n.adapter}:void 0;b=await i.create(o,e)}catch(e){const t=e instanceof Error?e.message:String(e);throw new Error(`ChartGPU: WebGPU is not available.\nReason: ${t}\nBrowser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.\nResources:\n - MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API\n - Browser compatibility: https://caniuse.com/webgpu\n - WebGPU specification: https://www.w3.org/TR/webgpu/\n - Check your system: https://webgpureport.org/`)}return null==(r=b.device)||r.lost.then(e=>{g=!0,!m&&("destroyed"!==e.reason&&console.warn("WebGPU device lost:",e),a&&"destroyed"!==e.reason&&Fe("deviceLost",{reason:e.reason,message:e.message}),Te())}),ye(!1),ve(),fe(),pe(),"auto"===p&&oe(),De}catch(e){throw De.dispose(),e}}};HTMLWidgets.widget({name:"chartgpu",type:"output",factory:function(e,t,n){let i=null;return{renderValue:function(t){var n=t.options;const r=document.getElementById(e.id);console.log(i),null===i?i=dr.create(r,n):i.then(function(e){e.setOption(n)})},resize:function(e,t){}}}})})(); \ No newline at end of file +(()=>{"use strict";HTMLWidgets;const e=Symbol("GPUContext.ownsDevice"),t=t=>t[e]??!0;function n(e){if(!e.canvas)throw new Error("GPUContext: Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.canvasContext)throw new Error("GPUContext: not initialized. Call initializeGPUContext() first.");return e.canvasContext.getCurrentTexture()}class i{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=function(t,n){const i=(null==n?void 0:n.devicePixelRatio)??(typeof window<"u"?window.devicePixelRatio:1),r=Number.isFinite(i)&&i>0?i:1,o=(null==n?void 0:n.alphaMode)??"opaque",a=(null==n?void 0:n.powerPreference)??"high-performance",s=!(null==n||!n.device||null==n||!n.adapter),l=!s;return{adapter:s?n.adapter:null,device:s?n.device:null,initialized:!1,canvas:t||null,canvasContext:null,preferredFormat:null,devicePixelRatio:r,alphaMode:o,powerPreference:a,[e]:l}}(t,n)}async initialize(){this._state=await async function(n){var i,r,o;if(n.initialized)throw new Error("GPUContext: already initialized. Call destroyGPUContext() before reinitializing.");const a=Number.isFinite(n.devicePixelRatio)&&n.devicePixelRatio>0?n.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 s=null,l=null,u=t(n);try{if(n.adapter&&n.device){if(l=n.adapter,s=n.device,u=!1,"function"!=typeof(null==(i=navigator.gpu)?void 0:i.getPreferredCanvasFormat))throw new Error("GPUContext: Shared device requires navigator.gpu.getPreferredCanvasFormat() for canvas format selection, but it is not available in this environment. Use a browser with full WebGPU support.");const e=navigator.gpu.getPreferredCanvasFormat();if("bgra8unorm"!==e&&"rgba8unorm"!==e)throw new Error(`GPUContext: Shared device preferred canvas format is not supported by ChartGPU. Received navigator.gpu.getPreferredCanvasFormat()="${e}". Supported formats: "bgra8unorm", "rgba8unorm".`);const t=s.limits.maxBufferSize;if(t<33554432)throw new Error(`GPUContext: Injected device.limits.maxBufferSize is insufficient. Required >= 33554432 bytes, actual=${t} bytes.`);const r=s.limits.maxStorageBufferBindingSize;if(r<33554432)throw new Error(`GPUContext: Injected device.limits.maxStorageBufferBindingSize is insufficient. Required >= 33554432 bytes, actual=${r} bytes.`)}else{const e=await navigator.gpu.requestAdapter({powerPreference:n.powerPreference});if(!e)throw new Error("GPUContext: Failed to request WebGPU adapter. No compatible adapter found. This may occur if no GPU is available or WebGPU is disabled.");const t=await e.requestDevice();if(!t)throw new Error("GPUContext: Failed to request WebGPU device from adapter.");l=e,s=t,u=!0,s.addEventListener("uncapturederror",e=>{console.error("WebGPU uncaptured error:",e.error)})}let t=null,c=null;if(n.canvas){const e=n.canvas.getContext("webgpu");if(!e){if(u&&s)try{s.destroy()}catch(e){console.warn("Error destroying device during canvas setup failure:",e)}throw new Error("GPUContext: Failed to get WebGPU context from canvas.")}const{width:i,height:l}=function(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}}(n.canvas),d=a,f=Math.floor(i*d),m=Math.floor(l*d),p=s.limits.maxTextureDimension2D;if(!u&&(f>p||m>p)){const e=Math.max(f,m);throw new Error(`GPUContext: Injected device.limits.maxTextureDimension2D is insufficient. Required >= ${e} (for ${f}x${m} at devicePixelRatio=${d}), actual=${p}.`)}const h=Math.max(1,Math.min(f,p)),g=Math.max(1,Math.min(m,p));n.canvas.width=h,n.canvas.height=g,c=(null==(o=(r=navigator.gpu).getPreferredCanvasFormat)?void 0:o.call(r))||"bgra8unorm",e.configure({device:s,format:c,alphaMode:n.alphaMode}),t=e}return{adapter:l,device:s,initialized:!0,canvas:n.canvas,canvasContext:t,preferredFormat:c,devicePixelRatio:a,alphaMode:n.alphaMode,powerPreference:n.powerPreference,[e]:u}}catch(e){if(u&&s)try{s.destroy()}catch(e){console.warn("Error destroying device during initialization failure:",e)}throw e instanceof Error?e:new Error(`Failed to initialize GPUContext: ${String(e)}`)}}(this._state)}static async create(e,t){const n=new i(e,t);return await n.initialize(),n}getCanvasTexture(){return n(this._state)}clearScreen(e,t,i,r){!function(e,t,i,r,o){if(t<0||t>1||i<0||i>1||r<0||r>1||o<0||o>1)throw new Error("GPUContext: Color components must be in the range [0.0, 1.0]");if(!e.canvas)throw new Error("GPUContext: Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.device||!e.canvasContext)throw new Error("GPUContext: not initialized. Call initializeGPUContext() first.");const a=n(e),s=e.device.createCommandEncoder();s.beginRenderPass({colorAttachments:[{view:a.createView(),clearValue:{r:t,g:i,b:r,a:o},loadOp:"clear",storeOp:"store"}]}).end(),e.device.queue.submit([s.finish()])}(this._state,e,t,i,r)}destroy(){this._state=function(n){if(n.canvasContext)try{n.canvasContext.unconfigure()}catch(e){console.warn("Error unconfiguring GPU canvas context:",e)}if(!1!==t(n)&&n.device)try{n.device.destroy()}catch(e){console.warn("Error destroying GPU device:",e)}return{adapter:null,device:null,initialized:!1,canvas:n.canvas,canvasContext:null,preferredFormat:null,devicePixelRatio:n.devicePixelRatio,alphaMode:n.alphaMode,powerPreference:n.powerPreference,[e]:!1}}(this._state)}}function r(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"x"in e&&"y"in e&&"object"==typeof e.x&&"object"==typeof e.y&&"length"in e.x&&"length"in e.y}function o(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function a(e){return Array.isArray(e)}function s(e){if(r(e))return Math.min(e.x.length,e.y.length);if(o(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 l(e,t){if(r(e))return e.x[t];if(o(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return e[2*t]}const n=e[t];return null==n||"object"!=typeof n?NaN:a(n)?n[0]:n.x}function u(e,t){if(r(e))return e.y[t];if(o(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");return e[2*t+1]}const n=e[t];return null==n||"object"!=typeof n?NaN:a(n)?n[1]:n.y}function c(e,t){var n;if(r(e))return null==(n=e.size)?void 0:n[t];if(o(e))return;const i=e[t];return null!=i&&"object"==typeof i?a(i)?i[2]:i.size:void 0}function d(e,t,n,i,l,u){const c=s(n)-i,d=Math.min(l,c);if(d<=0)return;const f=t+2*d;if(f>e.length)throw new Error(`packXYInto: output buffer too small (need ${f} floats, have ${e.length})`);if(r(n))for(let r=0;rn&&(n=r),sa&&(a=s))}}else if(o(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData. Use typed arrays (Float32Array, Float64Array, etc.).");const r=e,o=Math.floor(r.length/2);for(let e=0;en&&(n=o),sa&&(a=s))}}else{const r=e.length;for(let o=0;on&&(n=r),sa&&(a=s))}}return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(a)?(t===n&&(n=t+1),i===a&&(a=i+1),{xMin:t,xMax:n,yMin:i,yMax:a}):null}function m(e){return!!Array.isArray(e)&&e.includes(null)}function p(e){if(Array.isArray(e))return e.filter(e=>{if(null==e||"object"!=typeof e)return!1;const t=a(e)?e[0]:e.x,n=a(e)?e[1]:e.y;return Number.isFinite(t)&&Number.isFinite(n)});const t=s(e),n=[];for(let i=0;i>>0;for(let e=0;e>>0;return n>>>0}function v(e){return b(2166136261,new Uint32Array(e.buffer,e.byteOffset,e.byteLength/4))}function y(e){return Array.isArray(e)}function x(e,t){const n=Math.floor(t);if(e instanceof Float32Array){const t=e.length>>>1;if(n<=0||0===t)return new Float32Array(0);if(t<=n)return e;const i=function(e,t){const n=e.length>>>1,i=n-1;if(t<=0||0===n)return new Int32Array(0);if(1===t)return new Int32Array([0]);if(2===t)return n>=2?new Int32Array([0,i]):new Int32Array([0]);if(n<=t){const e=new Int32Array(n);for(let t=0;t=c&&(t=Math.min(t,i-1),c=Math.min(t+1,i));const d=Math.floor(o*(n+1))+1,f=Math.min(Math.floor(o*(n+2))+1,i);let m=l,p=u;if(d0&&(m=t/i,p=n/i)}const h=e[2*a+0],g=e[2*a+1];let b=-1,v=t;for(let n=t;nb&&(b=r,v=n)}r[s++]=v,a=v}return r}(e,n),r=new Float32Array(2*i.length);for(let t=0;t=2?new Int32Array([0,i]):new Int32Array([0]);if(n<=t){const e=new Int32Array(n);for(let t=0;t=l&&(t=Math.min(t,i-1),l=Math.min(t+1,i));const d=Math.floor(o*(n+1))+1,f=Math.min(Math.floor(o*(n+2))+1,i);let m=u,p=c;if(d0&&(m=t/i,p=n/i)}const h=e[a],g=y(h)?h[0]:h.x,b=y(h)?h[1]:h.y;let v=-1,x=t;for(let n=t;nv&&(v=o,x=n)}r[s++]=x,a=x}return r}(e,n),o=new Array(r.length);for(let t=0;t=2){const t=l(e,0),n=u(e,0),r=c(e,0),o=l(e,i-1),a=u(e,i-1),s=c(e,i-1);return[void 0!==r?[t,n,r]:[t,n],void 0!==s?[o,a,s]:[o,a]]}{const t=l(e,0),n=u(e,0),i=c(e,0);return void 0!==i?[[t,n,i]]:[[t,n]]}}const o=i-1,a=new Array(r);{const t=l(e,0),n=u(e,0),i=c(e,0);a[0]=void 0!==i?[t,n,i]:[t,n];const s=l(e,o),d=u(e,o),f=c(e,o);a[r-1]=void 0!==f?[s,d,f]:[s,d]}const d=(i-2)/(r-2);for(let t=0;t=r&&(i=Math.min(i,o-1),r=Math.min(i+1,o));let s=null;if("average"===n){let t=0,n=0,o=0,a=0,d=0;for(let s=i;s0){const e=t/a,i=n/a;s=d>0?[e,i,o/d]:[e,i]}}else{let t="max"===n?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,o=i;for(let a=i;at&&(t=i,o=a):i0)||r<=i)return e;switch(t){case"lttb":return e instanceof Float32Array?x(e,i):function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&ArrayBuffer.isView(e)}(e)||function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"x"in e&&"y"in e&&"object"==typeof e.x&&"object"==typeof e.y&&"length"in e.x&&"length"in e.y}(e)?x(M(e),i):x(e.filter(e=>null!==e),i);case"average":return F(e,i,"average");case"max":return F(e,i,"max");case"min":return F(e,i,"min");default:return e}}function C(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],2===n)return r;const o=function(e){return Array.isArray(e)}(e[0]),a=(i-2)/(n-2);if(o){const t=e;for(let e=0;e=o&&(n=Math.min(n,i-2),o=Math.min(n+1,i-1));const s=t[n],l=t[o-1],u=s[0],c=s[1],d=l[2];let f=-1/0,m=1/0;for(let e=n;ef&&(f=r),i=o&&(n=Math.min(n,i-2),o=Math.min(n+1,i-1));const s=t[n],l=t[o-1],u=s.timestamp,c=s.open,d=l.close;let f=-1/0,m=1/0;for(let e=n;ef&&(f=i),r>>1;l(e,r)>>1;l(e,r)<=t?n=r+1:i=r}return n}function T(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"x"in e&&"y"in e&&"object"==typeof e.x&&"object"==typeof e.y&&"length"in e.x&&"length"in e.y}function D(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&ArrayBuffer.isView(e)}function U(e,t,n){const i=s(e);if(0===i||!Number.isFinite(t)||!Number.isFinite(n))return e;if(R(e)){const r=E(e,t),o=B(e,n);return r<=0&&o>=i?e:function(e,t,n){const i=s(e),r=Math.max(0,Math.min(t,i)),o=Math.max(r,Math.min(n,i));if(0===r&&o===i)return e;if(o<=r){if(T(e))return{x:[],y:[],...e.size?{size:[]}:{}};if(D(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData");return new(0,e.constructor)(0)}return[]}if(T(e)){const t={x: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),y: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)};if(e.size){const n=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);t.size=n}return t}if(D(e)){if(e instanceof DataView)throw new Error("DataView is not supported for InterleavedXYData");return e.subarray(2*r,2*o)}return e.slice(r,o)}(e,r,o)}const r=[];for(let o=0;o=t&&i<=n){const t=u(e,o);r.push([i,t])}}return r}function k(e,t,n){const i=s(e);if(0===i)return{start:0,end:0};if(!Number.isFinite(t)||!Number.isFinite(n))return{start:0,end:i};if(!R(e))return{start:0,end:i};const r=E(e,t),o=B(e,n),a=S(r,0,i),l=S(o,0,i);return l<=a?{start:a,end:a}:{start:a,end:l}}function G(e,t,n){const i=e.length;if(0===i||!Number.isFinite(t)||!Number.isFinite(n))return e;const r=function(e){const t=P.get(e);if(void 0!==t)return t;let n=Number.NEGATIVE_INFINITY;for(let t=0;t0&&A(e[0]);if(r){const r=o?function(e,t){let n=0,i=e.length;for(;n>>1;e[r][0]>>1;e[r].timestamp>>1;e[r][0]<=t?n=r+1:i=r}return n}(e,n):function(e,t){let n=0,i=e.length;for(;n>>1;e[r].timestamp<=t?n=r+1:i=r}return n}(e,n);return r<=0&&a>=i?e:a<=r?[]:e.slice(r,a)}const a=[];for(let r=0;r=t&&o<=n&&a.push(i)}return a}const z=e=>Math.min(1,Math.max(0,e)),V=e=>Math.min(255,Math.max(0,e)),L=e=>{const t=Number.parseInt(e,16);return Number.isFinite(t)?t:0},W=e=>{const t=Number.parseInt(e,16);return Number.isFinite(t)?t:0},O=e=>{const t=e.trim();if(0===t.length)return null;if(t.endsWith("%")){const e=Number.parseFloat(t.slice(0,-1));return Number.isFinite(e)?V(e/100*255):null}const n=Number.parseFloat(t);return Number.isFinite(n)?V(n):null},_=e=>{if("string"!=typeof e)return null;const t=e.trim();if(0===t.length)return null;const n=(e=>{const t=e.trim();if(!t.startsWith("#"))return null;const n=t.slice(1);return 3===n.length?[17*L(n[0])/255,17*L(n[1])/255,17*L(n[2])/255,1]:4===n.length?[17*L(n[0])/255,17*L(n[1])/255,17*L(n[2])/255,17*L(n[3])/255]:6===n.length?[W(n.slice(0,2))/255,W(n.slice(2,4))/255,W(n.slice(4,6))/255,1]:8===n.length?[W(n.slice(0,2))/255,W(n.slice(2,4))/255,W(n.slice(4,6))/255,W(n.slice(6,8))/255]:null})(t);return n||((e=>{const t=e.trim(),n=/^(rgba?|RGBA?)\(\s*([^\)]*)\s*\)$/.exec(t);if(!n)return null;const i=n[1].toLowerCase(),r=n[2].split(",").map(e=>e.trim());if("rgb"===i){if(3!==r.length)return null;const e=O(r[0]),t=O(r[1]),n=O(r[2]);return null==e||null==t||null==n?null:[e/255,t/255,n/255,1]}if("rgba"===i){if(4!==r.length)return null;const e=O(r[0]),t=O(r[1]),n=O(r[2]),i=(e=>{const t=e.trim();if(0===t.length)return null;if(t.endsWith("%")){const e=Number.parseFloat(t.slice(0,-1));return Number.isFinite(e)?z(e/100):null}const n=Number.parseFloat(t);return Number.isFinite(n)?z(n):null})(r[3]);return null==e||null==t||null==n||null==i?null:[e/255,t/255,n/255,i]}return null})(t)||null)},Y=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0,X=e=>{throw new Error(`RenderCoordinator: unreachable value: ${String(e)}`)},$=e=>Math.min(1,Math.max(0,e)),H=(e,t)=>(e+1)/2*t,q=(e,t)=>(1-e)/2*t,j=864e5,Z=30*j,J=365*j,K=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Q=(e,t)=>{if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"!=typeof e)return null;const n=e.trim();if(0===n.length)return null;if(n.endsWith("%")){const e=Number.parseFloat(n.slice(0,-1));return Number.isFinite(e)?e/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},ee=(e,t)=>{if(null==e)return{inner:0,outer:.7*t};if((e=>Array.isArray(e))(e)){const n=Q(e[0],t),i=Q(e[1],t),r=Math.max(0,Number.isFinite(n)?n:0),o=Math.max(r,Number.isFinite(i)?i:.7*t);return{inner:r,outer:Math.min(t,o)}}const n=Q(e,t),i=Math.max(0,Number.isFinite(n)?n:.7*t);return{inner:0,outer:Math.min(t,i)}},te=e=>String(Math.trunc(e)).padStart(2,"0"),ne=(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(),a=n.getHours(),s=n.getMinutes();return t{if("name"===i)return t.name??"";const r=t[i];return null==r?"":function(e,t){if(!Number.isFinite(e))return"";if(null==t)return String(e);const n=Math.min(20,Math.max(0,Math.floor(t)));return e.toFixed(n)}(r,n)})}function pe(e){switch(e){case"center":return"middle";case"end":return"end";default:return"start"}}function he(e,t){let n=0,i=s(e);for(;n>>1;l(e,r)=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom}const be=e=>Math.min(1,Math.max(0,e)),ve=e=>{if("string"!=typeof e)return"";const t=e.trim();return t.length>0?t:""},ye=e=>Array.isArray(e),xe=(e,t)=>{const n=(e=>{if(ye(e)){const t=e[2];return"number"==typeof t&&Number.isFinite(t)?t:null}const t=e.size;return"number"==typeof t&&Number.isFinite(t)?t:null})(t);if(null!=n)return Math.max(0,n);const i=e.symbolSize;if("number"==typeof i)return Number.isFinite(i)?Math.max(0,i):4;if("function"==typeof i){const e=((e,t)=>{try{const n=e(t);return"number"==typeof n&&Number.isFinite(n)?n:null}catch{return null}})(i,(e=>ye(e)?e:[e.x,e.y,e.size])(t));return null==e?4:Math.max(0,e)}return 4};function we(e,t){const n=function(e){const t=new Map,n=new Array(e.length),i=new Array(e.length);let r=0;for(let o=0;oe-t);let n=Number.POSITIVE_INFINITY;for(let e=1;e0&&i0?n:1}(e),o=function(e,t,n){if(Number.isFinite(n)&&n>0){const e=t.scale(0),i=t.scale(0+n),r=Math.abs(i-e);if(Number.isFinite(r)&&r>0)return r}const i=[];for(let n=0;ne-t);let r=Number.POSITIVE_INFINITY;for(let e=1;e0&&t0?r:0}(e,t,r),a=(e=>{let t,n,i;for(let r=0;r0?d/f:0;let p=0;const h=a.barWidth;if("number"==typeof h)p=Math.max(0,h),p=Math.min(p,m);else if("string"==typeof h){const e=(e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null})(h);p=null==e?0:m*be(e)}p>0||(p=m);const g=p*u;return{categoryStep:r,categoryWidthPx:o,barWidthPx:p,gapPx:g,clusterWidthPx:i*p+Math.max(0,i-1)*g,clusterSlots:n}}const Me=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;in&&(n=i))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t)0&&Number.isFinite(e)?Math.round(e/t):Number.isFinite(i)&&i>0&&Number.isFinite(n)?Math.round(n/i):Math.round(1e6*n)}function Ne(e,t,n,i,r,o=20){var a;if(!Number.isFinite(t)||!Number.isFinite(n))return null;const d=Number.isFinite(o)?Math.max(0,o):20,f=d*d,m=i.invert(t);if(!Number.isFinite(m))return null;let p=-1,h=-1,g=null,b=Number.POSITIVE_INFINITY;const v=[],y=[];for(let t=0;t0){const o=we(v,i);if(o.barWidthPx>0&&o.clusterWidthPx>=0){const d=function(e,t){let n=0;for(let i=0;in&&(n=o)}}return Math.max(0,n)}(v,r),{baselineDomain:f,baselinePx:m}=function(e,t,n){const i=t.invert(n),r=t.invert(0),o=Math.min(i,r),a=Math.max(i,r);let s;s=Number.isFinite(o)&&Number.isFinite(a)?o<=0&&0<=a?0:o>0?o:a<0?a:Me(e):Me(e);let l=t.scale(s);return Number.isFinite(l)||(s=Me(e),l=t.scale(s)),Number.isFinite(l)||(s=0,l=t.scale(0)),{baselineDomain:s,baselinePx:l}}(v,r,d),{clusterSlots:p,barWidthPx:h,gapPx:g,clusterWidthPx:b,categoryWidthPx:x,categoryStep:w}=o,M=new Map;let F=null;for(let e=0;e=0?(y=n.posSum,S=y+s,n.posSum=S):(y=n.negSum,S=y+s,n.negSum=S)}else y=f,S=s;const A=""!==C?r.scale(y):m,I=r.scale(S);if(!Number.isFinite(A)||!Number.isFinite(I))continue;const P={left:p,right:v,top:Math.min(A,I),bottom:Math.max(A,I)};ge(t,n,P)&&(null===F||P.topF.seriesIndex)&&(F={seriesIndex:a,dataIndex:e,top:P.top})}}if(F){const t=null==(a=e[F.seriesIndex])?void 0:a.data;if(t){const e=l(t,F.dataIndex),n=u(t,F.dataIndex),i=c(t,F.dataIndex),r=void 0!==i?[e,n,i]:[e,n];return{seriesIndex:F.seriesIndex,dataIndex:F.dataIndex,point:r,distance:0}}}}}const x=[],w=[];for(let t=0;tb)break;let N=f;if(M){const t=c(v,o),n=d+xe(M,void 0!==t?[e,s,t]:[e,s]);N=n*n}if(!(F>N)&&(F=0;o--){const e=l(v,o),s=u(v,o);if(!Number.isFinite(e)||!Number.isFinite(s))continue;const m=i.scale(e),y=r.scale(s);if(!Number.isFinite(m)||!Number.isFinite(y))continue;const x=m-t,w=y-n,F=x*x+w*w;if(x*x>b)break;let N=f;if(M){const t=c(v,o),n=d+xe(M,void 0!==t?[e,s,t]:[e,s]);N=n*n}if(!(F>N)&&(FN)&&(F0&&h>0&&m.horizontal.color!==m.vertical.color)e.gridRenderer.prepare(a,{lineCount:{horizontal:p,vertical:0},color:m.horizontal.color}),e.gridRenderer.prepare(a,{lineCount:{horizontal:0,vertical:h},color:m.vertical.color,append:!0});else{const t=p>0?m.horizontal.color:m.vertical.color;e.gridRenderer.prepare(a,{lineCount:{horizontal:p,vertical:h},color:t})}if(l&&(e.xAxisRenderer.prepare(i.xAxis,r,"x",a,i.theme.axisLineColor,i.theme.axisTickColor,s),e.yAxisRenderer.prepare(i.yAxis,o,"y",a,i.theme.axisLineColor,i.theme.axisTickColor,5)),u.hasPointer&&u.isInGrid){const t={showX:!0,showY:"sync"!==u.source,color:f(i.theme.axisLineColor,.6),lineWidth:1};e.crosshairRenderer.prepare(u.x,u.y,a,t),e.crosshairRenderer.setVisible(!0)}else e.crosshairRenderer.setVisible(!1);if("mouse"===u.source&&u.hasPointer&&u.isInGrid)if(c){const t=Ne(d,u.gridX,u.gridY,c.xScale,c.yScale);if(t){const{x:r,y:o}=(e=>(e=>Array.isArray(e))(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y})(t.point),s=c.xScale.scale(r),l=c.yScale.scale(o);if(Number.isFinite(s)&&Number.isFinite(l)){const r=a.left+s,o=a.top+l,u=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=S(Math.floor(r),0,Math.max(0,t)),u=S(Math.floor(a),0,Math.max(0,n)),c=S(Math.ceil(o),0,Math.max(0,t)),d=S(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(a),c={centerDeviceX:r*a.devicePixelRatio,centerDeviceY:o*a.devicePixelRatio,devicePixelRatio:a.devicePixelRatio,canvasWidth:a.canvasWidth,canvasHeight:a.canvasHeight,scissor:u},d=(null==(n=i.series[t.seriesIndex])?void 0:n.color)??"#888";e.highlightRenderer.prepare(c,d,4),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 Se(e,t,n){const i=_(e??n)??_(n)??[1,1,1,1],r=null==t?1:$(t);return[$(i[0]),$(i[1]),$(i[2]),$(i[3]*r)]}function Ae(e,t){const n=_(e)??[0,0,0,1],i=$(n[3]*$(t));return`rgba(${Math.round(255*$(n[0]))}, ${Math.round(255*$(n[1]))}, ${Math.round(255*$(n[2]))}, ${i})`}function Ie(e,t,n){return e.replace(/\{(x|y|value|name)\}/g,(e,i)=>{if("name"===i)return t.name??"";const r=t[i];return null==r?"":function(e,t){if(!Number.isFinite(e))return"";if(null==t)return String(e);const n=Math.min(20,Math.max(0,Math.floor(t)));return e.toFixed(n)}(r,n)})}function Pe(e){switch(e){case"center":return"middle";case"end":return"end";default:return"start"}}function Re(e){return Math.max(0,Math.min(1,e))}function Ee(e){return"area"===e.type||"line"===e.type&&!!e.areaStyle}const Be="// grid.wgsl\n// Minimal grid line shader:\n// - Vertex input: vec2 position in clip-space coordinates\n// - Uniforms: identity transform + solid RGBA color\n\nstruct VSUniforms {\n transform: mat4x4,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct FSUniforms {\n color: vec4,\n};\n\n@group(0) @binding(1) var fsUniforms: FSUniforms;\n\nstruct VSIn {\n @location(0) position: vec2,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn) -> VSOut {\n var out: VSOut;\n out.clipPosition = vsUniforms.transform * vec4(in.position, 0.0, 1.0);\n return out;\n}\n\n@fragment\nfn fsMain() -> @location(0) vec4 {\n return fsUniforms.color;\n}\n",Te=(e,t,n)=>{if(n&&n.device!==e)throw new Error("getStageModule(pipelineCache): cache.device must match the provided GPUDevice.");return"module"in t?{module:t.module,entryPoint:t.entryPoint||"",constants:t.constants}:{module:De(e,t.code,t.label,n),entryPoint:t.entryPoint||"",constants:t.constants}};function De(e,t,n,i){if("string"!=typeof t||0===t.length)throw new Error("createShaderModule(code): WGSL code must be a non-empty string.");if(i){if(i.device!==e)throw new Error("createShaderModule(pipelineCache): cache.device must match the provided GPUDevice.");return i.getOrCreateShaderModule(t,n)}return e.createShaderModule({code:t,label:n})}function Ue(e,t,n){if(n&&n.device!==e)throw new Error("createRenderPipeline(pipelineCache): cache.device must match the provided GPUDevice.");const i=Te(e,t.vertex,n),r=i.entryPoint||"vsMain";let o;if(t.fragment){const i=Te(e,t.fragment,n),r=i.entryPoint||"fsMain";let a;if(t.fragment.targets)a=[...t.fragment.targets];else{const e=t.fragment.formats;if(!e)throw new Error("createRenderPipeline(fragment): provide either `fragment.targets` or `fragment.formats` when a fragment stage is present.");if("string"==typeof e)a=[{format:e,blend:t.fragment.blend,writeMask:t.fragment.writeMask}];else{a=new Array(e.length);for(let n=0;n{if(!Number.isFinite(e)||e<0)throw new Error(`alignTo(value): value must be a finite non-negative number. Received: ${String(e)}`);if(!(e=>Number.isInteger(e)&&e>0&&!(e&e-1))(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)})(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:null==n?void 0:n.label,size:r,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST})}function ze(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(0!==i.size){if(3&i.offset||3&i.size)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 Ve=[1,1,1,.8],Le=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0;function We(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=(null==t?void 0:t.sampleCount)??1,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),l=Ge(e,64,{label:"axisRenderer/vsUniforms"}),u=Ge(e,16,{label:"axisRenderer/fsUniformsLine"}),c=Ge(e,16,{label:"axisRenderer/fsUniformsTick"}),d=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}},{binding:1,resource:{buffer:u}}]}),f=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}},{binding:1,resource:{buffer:c}}]}),m=Ue(e,{label:"axisRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:Be,label:"grid.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:Be,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:o}},a);let p=null,h=0;const g=()=>{if(n)throw new Error("AxisRenderer is disposed.")};return{prepare:(t,n,i,r,o,a,s)=>{if(g(),"x"!==i&&"y"!==i)throw new Error("AxisRenderer.prepare: orientation must be 'x' or 'y'.");const d=((e,t,n,i,r)=>{const{left:o,right:a,top:s,bottom:l,canvasWidth:u,canvasHeight:c}=i,d=Number.isFinite(i.devicePixelRatio)&&i.devicePixelRatio>0?i.devicePixelRatio:1;if(!(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))(i))throw new Error("AxisRenderer.prepare: gridArea dimensions must be finite numbers.");if(u<=0||c<=0)throw new Error("AxisRenderer.prepare: canvas dimensions must be positive.");if(o<0||a<0||s<0||l<0)throw new Error("AxisRenderer.prepare: gridArea margins must be non-negative.");const f=o*d/u*2-1,m=(u-a*d)/u*2-1,p=1-s*d/c*2,h=1-(c-l*d)/c*2,g=e.tickLength??6;if(!Number.isFinite(g)||g<0)throw new Error("AxisRenderer.prepare: tickLength must be a finite non-negative number.");const b=r??5,v=Math.max(1,Math.floor(b));if(!Number.isFinite(b)||v<1)throw new Error("AxisRenderer.prepare: tickCount must be a finite number >= 1.");const y=g*d,x=y/u*2,w=y/c*2,M=((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 e=n;n=i,i=e}return{min:n,max:i}})(Le(e.min)??("x"===n?t.invert(f):t.invert(h)),Le(e.max)??("x"===n?t.invert(m):t.invert(p))),F=M.min,N=M.max,C=new Float32Array(2*(1+v)*2);let S=0;if("x"===n){C[S++]=f,C[S++]=h,C[S++]=m,C[S++]=h;const e=h,n=e-w;for(let i=0;i{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})());const b=o??"rgba(255,255,255,0.8)",v=a??b,y=_(b)??Ve,x=_(v)??y,w=new ArrayBuffer(16);new Float32Array(w).set([y[0],y[1],y[2],y[3]]),ze(e,u,w);const M=new ArrayBuffer(16);new Float32Array(M).set([x[0],x[1],x[2],x[3]]),ze(e,c,M)},render:e=>{g(),0!==h&&p&&(e.setPipeline(m),e.setVertexBuffer(0,p),e.setBindGroup(0,d),e.draw(Math.min(2,h)),h>2&&(e.setBindGroup(0,f),e.draw(h-2,1,2,0)))},dispose:()=>{if(!n){n=!0;try{l.destroy()}catch{}try{u.destroy()}catch{}try{c.destroy()}catch{}if(p)try{p.destroy()}catch{}p=null,h=0}}}}const Oe=[1,1,1,.15];const _e='// area.wgsl\n// Minimal area-fill shader (triangle-strip):\n// - Vertex input: vec2 position in data coords\n// - Uniforms: clip-space transform + baseline value + solid RGBA color\n// - Topology: triangle-strip\n// - CPU duplicates vertices as p0,p0,p1,p1,... and we use vertex_index parity:\n// even index -> "top" vertex (original y)\n// odd index -> "baseline" vertex (uniform baseline)\n\nstruct VSUniforms {\n transform: mat4x4,\n baseline: f32,\n // Pad to 16-byte multiple (uniform buffer layout requirements).\n _pad0: vec3,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct FSUniforms {\n color: vec4,\n};\n\n@group(0) @binding(1) var fsUniforms: FSUniforms;\n\nstruct VSIn {\n @location(0) position: vec2,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n var out: VSOut;\n let useBaseline = (vertexIndex & 1u) == 1u;\n let y = select(in.position.y, vsUniforms.baseline, useBaseline);\n let pos = vec2(in.position.x, y);\n out.clipPosition = vsUniforms.transform * vec4(pos, 0.0, 1.0);\n return out;\n}\n\n@fragment\nfn fsMain() -> @location(0) vec4 {\n return fsUniforms.color;\n}\n\n',Ye=e=>Math.min(1,Math.max(0,e)),Xe=(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),a=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(a)?a:0}};function $e(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,c=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),d=Ge(e,96,{label:"areaRenderer/vsUniforms"}),m=Ge(e,16,{label:"areaRenderer/fsUniforms"}),p=new ArrayBuffer(96),h=new Float32Array(p),g=new Float32Array(4),b=e.createBindGroup({layout:c,entries:[{binding:0,resource:{buffer:d}},{binding:1,resource:{buffer:m}}]}),v=Ue(e,{label:"areaRenderer/pipeline",bindGroupLayouts:[c],vertex:{code:_e,label:"area.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:_e,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:o}},a);let y=null,x=0;const w=()=>{if(n)throw new Error("AreaRenderer is disposed.")};return{prepare:(t,n,i,r,o)=>{w();const a=(e=>{const t=s(e),n=new Float32Array(2*t*2);let i=0;for(let r=0;r0&&e.queue.writeBuffer(y,0,a.buffer,0,a.byteLength),x=a.length/2;const v=f(n),{xMin:M,xMax:F,yMin:N,yMax:C}=v??{xMin:0,xMax:1,yMin:0,yMax:1},{a:S,b:A}=Xe(i,M,F),{a:I,b:P}=Xe(r,N,C);((t,n,i,r,o)=>{((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})(h,t,n,i,r),h[16]=o,h[17]=0,h[18]=0,h[19]=0,h[20]=0,h[21]=0,h[22]=0,h[23]=0,ze(e,d,p)})(S,A,I,P,Number.isFinite(o??Number.NaN)?o:Number.isFinite(N)?N:0);const[R,E,B,T]=(e=>_(e)??[0,0,0,1])(t.areaStyle.color),D=Ye(t.areaStyle.opacity);g[0]=R,g[1]=E,g[2]=B,g[3]=Ye(T*D),ze(e,m,g)},render:e=>{w(),y&&!(x<4)&&(e.setPipeline(v),e.setBindGroup(0,b),e.setVertexBuffer(0,y),e.draw(x))},dispose:()=>{if(!n){if(n=!0,y)try{y.destroy()}catch{}y=null,x=0;try{d.destroy()}catch{}try{m.destroy()}catch{}}}}}const He='// line.wgsl — Screen-space quad expansion with SDF-based anti-aliasing.\n//\n// Each "instance" draws one line segment (point[i] → point[i+1]).\n// 6 vertices per instance (2 triangles = 1 quad per segment).\n//\n// The vertex shader:\n// 1. Reads endpoints from a storage buffer.\n// 2. Transforms both to clip space using the mat4x4 transform.\n// 3. Converts clip→screen (NDC * canvasSize * 0.5).\n// 4. Computes the perpendicular direction in screen space.\n// 5. Offsets vertices by ±(halfWidth + AA_PADDING) along the perpendicular.\n// 6. Converts back to clip space.\n// 7. Outputs `acrossDevice` varying for SDF-based AA.\n//\n// The fragment shader applies smoothstep AA on the distance-from-edge.\n\nconst AA_PADDING: f32 = 1.5;\n\nstruct VSUniforms {\n transform : mat4x4, // 64 bytes: data-coord → clip-space\n canvasSize : vec2, // 8 bytes: device pixels (width, height)\n devicePixelRatio: f32, // 4 bytes\n lineWidthCssPx : f32, // 4 bytes: line width in CSS pixels\n};\n// Total: 80 bytes (aligned to 16).\n\n@group(0) @binding(0) var vsUniforms : VSUniforms;\n\nstruct FSUniforms {\n color : vec4,\n};\n\n@group(0) @binding(1) var fsUniforms : FSUniforms;\n\n@group(0) @binding(2) var points : array>;\n\nstruct VSOut {\n @builtin(position) clipPosition : vec4,\n @location(0) acrossDevice : f32,\n @location(1) @interpolate(flat) widthDevice : f32,\n};\n\n// Returns UV for the 6 vertices of a quad (2 triangles):\n// uv.x: 0 → endpoint A, 1 → endpoint B\n// uv.y: 0 → +side, 1 → −side\nfn quadUv(vid : u32) -> vec2 {\n switch (vid) {\n case 0u: { return vec2(0.0, 0.0); }\n case 1u: { return vec2(1.0, 0.0); }\n case 2u: { return vec2(0.0, 1.0); }\n case 3u: { return vec2(0.0, 1.0); }\n case 4u: { return vec2(1.0, 0.0); }\n default: { return vec2(1.0, 1.0); }\n }\n}\n\n@vertex\nfn vsMain(\n @builtin(vertex_index) vid : u32,\n @builtin(instance_index) iid : u32,\n) -> VSOut {\n let uv = quadUv(vid);\n\n // Read segment endpoints in data coordinates.\n let pA_data = points[iid];\n let pB_data = points[iid + 1u];\n\n // ── Gap detection ──────────────────────────────────────────────\n // Null entries in the data array are packed as NaN by the CPU.\n // Collapse the quad to a degenerate point so the rasterizer discards it.\n // WGSL has no isnan(); use the IEEE 754 property that NaN != NaN.\n if (pA_data.x != pA_data.x || pA_data.y != pA_data.y ||\n pB_data.x != pB_data.x || pB_data.y != pB_data.y) {\n var out: VSOut;\n out.clipPosition = vec4(0.0, 0.0, 0.0, 0.0);\n out.acrossDevice = 0.0;\n out.widthDevice = 0.0;\n return out;\n }\n\n // Transform to clip space.\n let clipA = vsUniforms.transform * vec4(pA_data, 0.0, 1.0);\n let clipB = vsUniforms.transform * vec4(pB_data, 0.0, 1.0);\n\n // Convert clip → screen (device pixels). \n // screen = (ndc * 0.5 + 0.5) * canvasSize, but Y is flipped.\n let ndcA = clipA.xy / clipA.w;\n let ndcB = clipB.xy / clipB.w;\n let screenA = vec2(\n (ndcA.x * 0.5 + 0.5) * vsUniforms.canvasSize.x,\n (1.0 - (ndcA.y * 0.5 + 0.5)) * vsUniforms.canvasSize.y,\n );\n let screenB = vec2(\n (ndcB.x * 0.5 + 0.5) * vsUniforms.canvasSize.x,\n (1.0 - (ndcB.y * 0.5 + 0.5)) * vsUniforms.canvasSize.y,\n );\n\n // Segment direction and perpendicular in screen space.\n let delta = screenB - screenA;\n let segLen = length(delta);\n\n // Degenerate segment: collapse quad to a degenerate triangle.\n if (segLen < 1e-6) {\n var out : VSOut;\n out.clipPosition = clipA;\n out.acrossDevice = 0.0;\n out.widthDevice = 0.0;\n return out;\n }\n\n let dir = delta / segLen;\n // Perpendicular: rotate 90° CW → (dy, -dx).\n let perp = vec2(dir.y, -dir.x);\n\n // Compute line width in device pixels + AA padding.\n let dpr = max(vsUniforms.devicePixelRatio, 1e-6);\n let widthDevice = max(1.0, vsUniforms.lineWidthCssPx * dpr);\n let halfExtent = widthDevice * 0.5 + AA_PADDING;\n\n // Select endpoint: uv.x=0 → A, uv.x=1 → B.\n let baseScreen = mix(screenA, screenB, uv.x);\n\n // Offset perpendicular: uv.y selects +side (0) vs −side (1).\n let side = mix(1.0, -1.0, uv.y);\n let screenPos = baseScreen + perp * halfExtent * side;\n\n // acrossDevice: 0 at −side edge, widthDevice at +side edge.\n // Map from [−halfExtent, +halfExtent] to [0, widthDevice + 2*AA_PADDING].\n let totalExtent = 2.0 * halfExtent;\n let acrossDevice = (side * halfExtent + halfExtent) / totalExtent * totalExtent;\n // Simplified: acrossDevice = halfExtent * (1 + side) = halfExtent + halfExtent * side\n // But for the fragment shader we want [0, totalExtent]:\n // Let\'s define it properly:\n // At side=+1: screenPos is at +halfExtent from center → acrossDevice = totalExtent\n // At side=-1: screenPos is at -halfExtent from center → acrossDevice = 0\n let acrossDeviceVal = halfExtent * (1.0 + side);\n\n // Convert screen → clip.\n let clipX = (screenPos.x / vsUniforms.canvasSize.x) * 2.0 - 1.0;\n let clipY = 1.0 - (screenPos.y / vsUniforms.canvasSize.y) * 2.0;\n\n var out : VSOut;\n out.clipPosition = vec4(clipX, clipY, 0.0, 1.0);\n out.acrossDevice = acrossDeviceVal;\n out.widthDevice = widthDevice;\n return out;\n}\n\n@fragment\nfn fsMain(in : VSOut) -> @location(0) vec4 {\n let totalExtent = in.widthDevice + 2.0 * AA_PADDING;\n let edgeDist = min(in.acrossDevice, totalExtent - in.acrossDevice);\n\n // Smooth step from 0 to AA zone for anti-aliased edges.\n let aa = max(fwidth(in.acrossDevice), 1e-3) * 1.25;\n let edgeCoverage = smoothstep(0.0, aa, edgeDist);\n\n // Also fade out in the AA_PADDING region (beyond the nominal half-width).\n // The padding zone is [0, AA_PADDING] at each edge.\n // Distance from the nominal edge = edgeDist - AA_PADDING (negative means inside).\n // Actually, remap: the nominal line occupies [AA_PADDING, AA_PADDING + widthDevice].\n let nominalDist = min(in.acrossDevice - AA_PADDING, (AA_PADDING + in.widthDevice) - in.acrossDevice);\n let paddingCoverage = smoothstep(0.0, aa, nominalDist);\n\n // Combine: paddingCoverage handles the SDF fade, edgeCoverage handles the outer trim.\n // For thin lines (< 1 device px), paddingCoverage alone provides the desired fade.\n let coverage = min(edgeCoverage, paddingCoverage);\n\n var color = fsUniforms.color;\n color = vec4(color.rgb, color.a * coverage);\n return color;\n}\n',qe=e=>Math.min(1,Math.max(0,e)),je=(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),a=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(a)?a:0}};function Ze(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,l=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),u=Ge(e,80,{label:"lineRenderer/vsUniforms"}),c=Ge(e,16,{label:"lineRenderer/fsUniforms"}),d=new ArrayBuffer(80),m=new Float32Array(d),p=new Float32Array(4);let h=null;const g=Ue(e,{label:"lineRenderer/pipeline",bindGroupLayouts:[l],vertex:{code:He,label:"line.wgsl",buffers:[]},fragment:{code:He,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:"triangle-list",cullMode:"none"},multisample:{count:o}},a);let b=0;const v=()=>{if(n)throw new Error("LineRenderer is disposed.")};return{prepare:(t,n,i,r,o=0,a=1,g=1,y=1)=>{v(),b=s(t.data);const x=f(t.data),{xMin:w,xMax:M,yMin:F,yMax:N}=x??{xMin:0,xMax:1,yMin:0,yMax:1},{a:C,b:S}=je(i,w,M),{a:A,b:I}=je(r,F,N);((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})(m,C,S+C*o,A,I);const P=Number.isFinite(a)&&a>0?a:1,R=Number.isFinite(g)&&g>0?g:1,E=Number.isFinite(y)&&y>0?y:1,B=Number.isFinite(t.lineStyle.width)&&t.lineStyle.width>0?t.lineStyle.width:2;m[16]=R,m[17]=E,m[18]=P,m[19]=B,ze(e,u,d);const[T,D,U,k]=(e=>_(e)??[0,0,0,1])(t.color),G=qe(t.lineStyle.opacity);p[0]=T,p[1]=D,p[2]=U,p[3]=qe(k*G),ze(e,c,p),h=e.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:u}},{binding:1,resource:{buffer:c}},{binding:2,resource:{buffer:n}}]})},render:e=>{v(),h&&!(b<2)&&(e.setPipeline(g),e.setBindGroup(0,h),e.draw(6,b-1))},dispose:()=>{if(!n){n=!0,h=null,b=0;try{u.destroy()}catch{}try{c.destroy()}catch{}}}}}const Je="// scatter.wgsl\n// Instanced anti-aliased circle shader (SDF):\n// - Per-instance vertex input:\n// - center = vec2 point center (transformed by VSUniforms.transform)\n// - radiusPx = f32 circle radius in pixels\n// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS\n// - Uniforms:\n// - @group(0) @binding(0): VSUniforms { transform, viewportPx }\n// - @group(0) @binding(1): FSUniforms { color }\n//\n// Notes:\n// - `viewportPx` is the current render target size in pixels (width, height).\n// - The quad is expanded in clip space using `radiusPx` and `viewportPx`.\n\nstruct VSUniforms {\n transform: mat4x4,\n viewportPx: vec2,\n // Pad to 16-byte alignment (mat4x4 is 64B; vec2 adds 8B; pad to 80B).\n _pad0: vec2,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct FSUniforms {\n color: vec4,\n};\n\n@group(0) @binding(1) var fsUniforms: FSUniforms;\n\nstruct VSIn {\n @location(0) center: vec2,\n @location(1) radiusPx: f32,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n @location(0) localPx: vec2,\n @location(1) radiusPx: f32,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fixed local corners for 2 triangles (triangle-list).\n // `localNdc` is a quad in [-1, 1]^2; we convert it to pixel offsets via radiusPx.\n let localNdc = array, 6>(\n vec2(-1.0, -1.0),\n vec2( 1.0, -1.0),\n vec2(-1.0, 1.0),\n vec2(-1.0, 1.0),\n vec2( 1.0, -1.0),\n vec2( 1.0, 1.0)\n );\n\n let corner = localNdc[vertexIndex];\n let localPx = corner * in.radiusPx;\n\n // Convert pixel offset to clip-space offset.\n // Clip space spans [-1, 1] across the viewport, so px -> clip is (2 / viewportPx).\n let localClip = localPx * (2.0 / vsUniforms.viewportPx);\n\n let centerClip = (vsUniforms.transform * vec4(in.center, 0.0, 1.0)).xy;\n\n var out: VSOut;\n out.clipPosition = vec4(centerClip + localClip, 0.0, 1.0);\n out.localPx = localPx;\n out.radiusPx = in.radiusPx;\n return out;\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n // Signed distance to the circle boundary (negative inside).\n let dist = length(in.localPx) - in.radiusPx;\n\n // Analytic-ish AA: smooth edge based on derivative of dist in screen space.\n let w = fwidth(dist);\n let a = 1.0 - smoothstep(0.0, w, dist);\n\n // Discard fully outside to avoid unnecessary blending work.\n if (a <= 0.0) {\n discard;\n }\n\n return vec4(fsUniforms.color.rgb, fsUniforms.color.a * a);\n}\n\n",Ke=(e,t,n)=>Math.min(n,Math.max(t,0|e)),Qe=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},et=(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),a=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(a)?a:0}};function tt(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,d=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),m=Ge(e,80,{label:"scatterRenderer/vsUniforms"}),p=Ge(e,16,{label:"scatterRenderer/fsUniforms"}),h=new ArrayBuffer(80),g=new Float32Array(h),b=new Float32Array(4),v=e.createBindGroup({layout:d,entries:[{binding:0,resource:{buffer:m}},{binding:1,resource:{buffer:p}}]}),y=Ue(e,{label:"scatterRenderer/pipeline",bindGroupLayouts:[d],vertex:{code:Je,label:"scatter.wgsl",buffers:[{arrayStride:16,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x2",offset:0},{shaderLocation:1,format:"float32",offset:8}]}]},fragment:{code:Je,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:o}},a);let x=null,w=0,M=new ArrayBuffer(0),F=new Float32Array(M),N=0,C=0,S=[1,1],A=null;const I=()=>{if(n)throw new Error("ScatterRenderer is disposed.")},P=(t,n,i,r,o,a)=>{const s=Number.isFinite(o)&&o>0?o:1,l=Number.isFinite(a)&&a>0?a:1;((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})(g,t,n,i,r),g[16]=s,g[17]=l,g[18]=0,g[19]=0,ze(e,m,h),S=[s,l]};return{prepare:(t,n,i,r,o)=>{I();const a=f(n),{xMin:d,xMax:m,yMin:h,yMax:g}=a??{xMin:0,xMax:1,yMin:0,yMax:1},{a:v,b:y}=et(i,d,m),{a:R,b:E}=et(r,h,g);o?(N=o.canvasWidth,C=o.canvasHeight,P(v,y,R,E,o.canvasWidth,o.canvasHeight),A=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=Ke(Math.floor(r),0,Math.max(0,t)),u=Ke(Math.floor(a),0,Math.max(0,n)),c=Ke(Math.ceil(o),0,Math.max(0,t)),d=Ke(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(o)):(P(v,y,R,E,S[0],S[1]),A=null);const[B,T,D,U]=(e=>_(e)??[0,0,0,1])(t.color);b[0]=B,b[1]=T,b[2]=D,b[3]=(e=>Math.min(1,Math.max(0,e)))(U),ze(e,p,b);const k=(null==o?void 0:o.devicePixelRatio)??1,G=k>0&&Number.isFinite(k),z=t.symbolSize,V=[0,0,void 0],L="function"==typeof z?(e,t,n)=>{V[0]=e,V[1]=t,V[2]=n;const i=z(V);return"number"==typeof i&&Number.isFinite(i)?i:4}:"number"==typeof z&&Number.isFinite(z)?(e,t,n)=>z:(e,t,n)=>4,W=s(n);(e=>{if(e<=F.length)return;const t=Math.max(8,Qe(e));M=new ArrayBuffer(4*t),F=new Float32Array(M)})(4*W);const O=F;let Y=0;for(let e=0;e0&&(O[Y+0]=t,O[Y+1]=i,O[Y+2]=s,O[Y+3]=0,Y+=4)}w=Y/4;const X=Math.max(4,16*w);if(!x||x.size0&&e.queue.writeBuffer(x,0,M,0,16*w)},render:e=>{I(),x&&0!==w&&(A&&N>0&&C>0&&e.setScissorRect(A.x,A.y,A.w,A.h),e.setPipeline(y),e.setBindGroup(0,v),e.setVertexBuffer(0,x),e.draw(6,w),A&&N>0&&C>0&&e.setScissorRect(0,0,N,C))},dispose:()=>{if(!n){if(n=!0,x)try{x.destroy()}catch{}x=null,w=0;try{m.destroy()}catch{}try{p.destroy()}catch{}N=0,C=0,S=[1,1],A=null}}}}const nt="struct RenderUniforms {\n plotOriginPx: vec2,\n plotSizePx: vec2,\n binSizePx: u32,\n binCountX: u32,\n binCountY: u32,\n normalization: u32,\n _pad: vec2,\n};\n\n@group(0) @binding(0) var u: RenderUniforms;\n@group(0) @binding(1) var bins: array;\n@group(0) @binding(2) var maxBuf: array;\n@group(0) @binding(3) var lutTex: texture_2d;\n\nstruct VsOut {\n @builtin(position) position: vec4f,\n};\n\n@vertex\nfn vsMain(@builtin(vertex_index) vid: u32) -> VsOut {\n // Fullscreen triangle (covers clip space).\n // (0,0)->(-1,-1), (2,0)->(3,-1), (0,2)->(-1,3)\n var pos = array(\n vec2f(-1.0, -1.0),\n vec2f(3.0, -1.0),\n vec2f(-1.0, 3.0)\n );\n var out: VsOut;\n out.position = vec4f(pos[vid], 0.0, 1.0);\n return out;\n}\n\nfn applyNormalization(count: f32, maxCount: f32, mode: u32) -> f32 {\n if (maxCount <= 0.0) {\n return 0.0;\n }\n let t = clamp(count / maxCount, 0.0, 1.0);\n if (mode == 1u) { // sqrt\n return sqrt(t);\n }\n if (mode == 2u) { // log\n // log1p(count) / log1p(max)\n return clamp(log(1.0 + count) / max(1e-9, log(1.0 + maxCount)), 0.0, 1.0);\n }\n return t; // linear\n}\n\n@fragment\nfn fsMain(@builtin(position) pos: vec4f) -> @location(0) vec4f {\n // pos.xy is framebuffer pixel coords (device px) with origin top-left.\n let x = pos.x;\n let y = pos.y;\n\n let left = f32(u.plotOriginPx.x);\n let top = f32(u.plotOriginPx.y);\n // plot scissor also applied on CPU; keep a guard anyway.\n if (x < left || y < top) {\n return vec4f(0.0);\n }\n\n let localX = u32((x - left) / f32(u.binSizePx));\n let localY = u32((y - top) / f32(u.binSizePx));\n if (localX >= u.binCountX || localY >= u.binCountY) {\n return vec4f(0.0);\n }\n\n let idx = localY * u.binCountX + localX;\n let c = f32(bins[idx]);\n let maxC = f32(maxBuf[0]);\n\n let t = applyNormalization(c, maxC, u.normalization);\n let lutX = i32(round(t * 255.0));\n let lut = textureLoad(lutTex, vec2(lutX, 0), 0);\n return vec4f(lut.rgb, 1.0);\n}\n\n",it=e=>Math.min(1,Math.max(0,e)),rt=(e,t,n)=>Math.min(n,Math.max(t,0|e)),ot=(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),a=i-o*t;return{a:Number.isFinite(o)?o:0,b:Number.isFinite(a)?a:0}},at=(e,t,n)=>e+(t-e)*n,st=(e,t,n)=>[at(e[0],t[0],n),at(e[1],t[1],n),at(e[2],t[2],n),at(e[3],t[3],n)],lt=e=>_(e)??[0,0,0,1],ut=e=>"plasma"===e?["#0d0887","#6a00a8","#b12a90","#e16462","#fca636","#f0f921"]:"inferno"===e?["#000004","#420a68","#932667","#dd513a","#fca50a","#fcffa4"]:["#440154","#3b528b","#21918c","#5ec962","#fde725"],ct=new Uint32Array([0]).buffer;function dt(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=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"}}]}),l=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"}}]}),u=Ge(e,128,{label:"scatterDensity/computeUniforms"}),c=new ArrayBuffer(128),d=new Float32Array(c,0,20),f=new Uint32Array(c),m=Ge(e,48,{label:"scatterDensity/renderUniforms"}),p=new ArrayBuffer(48),h=new Uint32Array(p),g=De(e,"struct ComputeUniforms {\n transform: mat4x4,\n viewportPx: vec2f,\n _pad0: vec2f,\n plotOriginPx: vec2,\n plotSizePx: vec2,\n binSizePx: u32,\n binCountX: u32,\n binCountY: u32,\n visibleStart: u32,\n visibleEnd: u32,\n normalization: u32,\n _pad1: vec2,\n};\n\n@group(0) @binding(0) var u: ComputeUniforms;\n@group(0) @binding(1) var points: array;\n@group(0) @binding(2) var bins: array>;\n\nstruct MaxBuffer {\n value: atomic,\n};\n@group(0) @binding(3) var maxBuf: MaxBuffer;\n\nfn clipToDevicePx(clip: vec2f) -> vec2f {\n // clip in [-1,1] -> device pixel in [0, viewport]\n return vec2f(\n (clip.x * 0.5 + 0.5) * u.viewportPx.x,\n (-clip.y * 0.5 + 0.5) * u.viewportPx.y\n );\n}\n\n@compute @workgroup_size(256)\nfn binPoints(@builtin(global_invocation_id) gid: vec3) {\n let idx = u.visibleStart + gid.x;\n if (idx >= u.visibleEnd) {\n return;\n }\n\n let p = points[idx];\n let clip4 = u.transform * vec4f(p.x, p.y, 0.0, 1.0);\n let clip = clip4.xy / max(1e-9, clip4.w);\n let px = clipToDevicePx(clip);\n\n // Scissor bounds in device px\n let left = f32(u.plotOriginPx.x);\n let top = f32(u.plotOriginPx.y);\n let right = left + f32(u.plotSizePx.x);\n let bottom = top + f32(u.plotSizePx.y);\n\n if (px.x < left || px.x >= right || px.y < top || px.y >= bottom) {\n return;\n }\n\n let localX = u32((px.x - left) / f32(u.binSizePx));\n let localY = u32((px.y - top) / f32(u.binSizePx));\n if (localX >= u.binCountX || localY >= u.binCountY) {\n return;\n }\n\n let binIndex = localY * u.binCountX + localX;\n atomicAdd(&bins[binIndex], 1u);\n}\n\n@compute @workgroup_size(256)\nfn reduceMax(@builtin(global_invocation_id) gid: vec3) {\n let binTotal = u.binCountX * u.binCountY;\n let i = gid.x;\n if (i >= binTotal) {\n return;\n }\n\n let v = atomicLoad(&bins[i]);\n atomicMax(&maxBuf.value, v);\n}\n\n","scatterDensityBinning.wgsl",a),b=e.createPipelineLayout({bindGroupLayouts:[s]}),v=ke(e,{label:"scatterDensity/binPointsPipeline",layout:b,compute:{module:g,entryPoint:"binPoints"}},a),y=ke(e,{label:"scatterDensity/reduceMaxPipeline",layout:b,compute:{module:g,entryPoint:"reduceMax"}},a),x=Ue(e,{label:"scatterDensity/renderPipeline",bindGroupLayouts:[l],vertex:{code:nt,label:"scatterDensityColormap.wgsl"},fragment:{code:nt,label:"scatterDensityColormap.wgsl",formats:i,blend:void 0},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:o}},a);let w=null,M=null,F=0,N=null,C=null,S="",A=null,I=null,P=null,R=-1,E=0,B=0,T=0,D=0,U=0,k=null,G=0,z=0,V=2,L=!0,W=!1,O=new Uint32Array(0);const _=()=>{if(n)throw new Error("ScatterDensityRenderer is disposed.")};return{prepare:(t,n,i,r,o,a,g,b,v)=>{_(),W=!0;const y=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=rt(Math.floor(r),0,Math.max(0,t)),u=rt(Math.floor(a),0,Math.max(0,n)),c=rt(Math.ceil(o),0,Math.max(0,t)),d=rt(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(b),x=b.devicePixelRatio,Y=Number.isFinite(t.binSize)?Math.max(1e-6,t.binSize):2,X=Math.max(1,Math.round(Y*(Number.isFinite(x)&&x>0?x:1))),$=Math.max(1,Math.ceil(y.w/X)),H=Math.max(1,Math.ceil(y.h/X));((t,n)=>{const i=Math.max(1,0|t)*Math.max(1,0|n);if(w&&M&&i<=F)return;const r=Math.max(1,i);if(F=Math.max(256,(e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))})(r)),w){try{w.destroy()}catch{}w=null}if(M){try{M.destroy()}catch{}M=null}w=e.createBuffer({label:"scatterDensity/binsBuffer",size:4*F,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),M=e.createBuffer({label:"scatterDensity/maxBuffer",size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),O=new Uint32Array(F),A=null,I=null,L=!0})($,H),(t=>{const n=(e=>{if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return"custom"}})(t.densityColormap);if(N||(N=e.createTexture({label:"scatterDensity/lutTexture",size:{width:256,height:1,depthOrArrayLayers:1},format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),C=N.createView(),S=""),n===S)return;const i=(e=>{const t=("string"==typeof e?ut(e):Array.isArray(e)&&e.length>0?e:ut("viridis")).map(lt),n=Math.max(2,t.length),i=new Uint8Array(new ArrayBuffer(1024));for(let e=0;e<256;e++){const r=e/255*(n-1),o=Math.min(n-2,Math.max(0,Math.floor(r))),a=r-o,s=st(t[o],t[o+1],a);i[4*e+0]=rt(Math.round(255*it(s[0])),0,255),i[4*e+1]=rt(Math.round(255*it(s[1])),0,255),i[4*e+2]=rt(Math.round(255*it(s[2])),0,255),i[4*e+3]=rt(Math.round(255*it(s[3])),0,255)}return i})(t.densityColormap);e.queue.writeTexture({texture:N},i,{bytesPerRow:1024,rowsPerImage:1},{width:256,height:1,depthOrArrayLayers:1}),S=n})(t);const q=(e=>"sqrt"===e?1:"log"===e?2:0)(t.densityNormalization);P!==n&&(P=n,A=null,I=null,L=!0),R!==i&&(R=i,L=!0),(E!==r||B!==o)&&(E=r,B=o,L=!0),(T!==X||D!==$||U!==H)&&(T=X,D=$,U=H,L=!0),(!k||k.x!==y.x||k.y!==y.y||k.w!==y.w||k.h!==y.h)&&(k=y,L=!0),(G!==b.canvasWidth||z!==b.canvasHeight)&&(G=b.canvasWidth,z=b.canvasHeight,L=!0),V!==q&&(V=q,L=!0);const j=v,Z=(null==j?void 0:j.xMin)??0,J=(null==j?void 0:j.xMax)??1,K=(null==j?void 0:j.yMin)??0,Q=(null==j?void 0:j.yMax)??1,{a:ee,b:te}=ot(a,Z,J),{a:ne,b:ie}=ot(g,K,Q);((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})(d,ee,te,ne,ie),d[16]=b.canvasWidth>0?b.canvasWidth:1,d[17]=b.canvasHeight>0?b.canvasHeight:1,d[18]=0,d[19]=0,f[20]=y.x>>>0,f[21]=y.y>>>0,f[22]=y.w>>>0,f[23]=y.h>>>0,f[24]=X>>>0,f[25]=$>>>0,f[26]=H>>>0,f[27]=(0|Math.max(0,r))>>>0,f[28]=(0|Math.max(0,o))>>>0,f[29]=q>>>0,ze(e,u,c),h[0]=y.x>>>0,h[1]=y.y>>>0,h[2]=y.w>>>0,h[3]=y.h>>>0,h[4]=X>>>0,h[5]=$>>>0,h[6]=H>>>0,h[7]=q>>>0,ze(e,m,p),!w||!M||!C||!P||(A||(A=e.createBindGroup({label:"scatterDensity/computeBindGroup",layout:s,entries:[{binding:0,resource:{buffer:u}},{binding:1,resource:{buffer:P}},{binding:2,resource:{buffer:w}},{binding:3,resource:{buffer:M}}]})),I||(I=e.createBindGroup({label:"scatterDensity/renderBindGroup",layout:l,entries:[{binding:0,resource:{buffer:m}},{binding:1,resource:{buffer:w}},{binding:2,resource:{buffer:M}},{binding:3,resource:C}]})))},encodeCompute:t=>{if(_(),!W||!L)return;if(!w||!M||!A||R<=0)return void(L=!1);if(!k||k.w<=0||k.h<=0)return void(L=!1);e.queue.writeBuffer(w,0,O.buffer,0,4*F),e.queue.writeBuffer(M,0,ct);const n=D*U|0,i=Math.max(0,B-E|0),r=t.beginComputePass({label:"scatterDensity/computePass"});r.setBindGroup(0,A),r.setPipeline(v);const o=Math.ceil(i/256);o>0&&r.dispatchWorkgroups(o),r.setPipeline(y);const a=Math.ceil(n/256);a>0&&r.dispatchWorkgroups(a),r.end(),L=!1},render:e=>{_(),W&&(!I||!k||!C||k.w<=0||k.h<=0||(e.setScissorRect(k.x,k.y,k.w,k.h),e.setPipeline(x),e.setBindGroup(0,I),e.draw(3),G>0&&z>0&&e.setScissorRect(0,0,G,z)))},dispose:()=>{if(!n){n=!0;try{u.destroy()}catch{}try{m.destroy()}catch{}if(w)try{w.destroy()}catch{}if(M)try{M.destroy()}catch{}if(w=null,M=null,F=0,N)try{N.destroy()}catch{}N=null,C=null,A=null,I=null,P=null}}}}const ft="// pie.wgsl\n// Instanced anti-aliased pie-slice shader (instanced quad + SDF mask).\n//\n// - Per-instance vertex input:\n// - center = vec2 slice center (transformed by VSUniforms.transform)\n// - startAngleRad = f32 start angle in radians\n// - endAngleRad = f32 end angle in radians\n// - radiiPx = vec2(innerRadiusPx, outerRadiusPx) in *device pixels*\n// - color = vec4 RGBA color in [0..1]\n//\n// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS\n//\n// - Uniforms:\n// - @group(0) @binding(0): VSUniforms { transform, viewportPx }\n//\n// Notes:\n// - The quad is expanded in clip space using `radiusPx` and `viewportPx`.\n// - Fragment uses an SDF mask for the circle boundary + an angular wedge mask.\n// - Fully outside fragments are discarded to avoid unnecessary blending work.\n//\n// Conventions: matches other shaders in this repo (vsMain/fsMain, group 0 bindings,\n// and explicit uniform padding/alignment where needed).\n\nconst PI: f32 = 3.141592653589793;\nconst TAU: f32 = 6.283185307179586; // 2*pi\n\nstruct VSUniforms {\n transform: mat4x4,\n viewportPx: vec2,\n // Pad to 16-byte alignment (mat4x4 is 64B; vec2 adds 8B; pad to 80B).\n _pad0: vec2,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct VSIn {\n @location(0) center: vec2,\n @location(1) startAngleRad: f32,\n @location(2) endAngleRad: f32,\n @location(3) radiiPx: vec2, // (innerPx, outerPx)\n @location(4) color: vec4,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n @location(0) localPx: vec2,\n @location(1) startAngleRad: f32,\n @location(2) endAngleRad: f32,\n @location(3) radiiPx: vec2,\n @location(4) color: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fixed local corners for 2 triangles (triangle-list).\n // `localNdc` is a quad in [-1, 1]^2; we convert it to pixel offsets via radiusPx.\n let localNdc = array, 6>(\n vec2(-1.0, -1.0),\n vec2( 1.0, -1.0),\n vec2(-1.0, 1.0),\n vec2(-1.0, 1.0),\n vec2( 1.0, -1.0),\n vec2( 1.0, 1.0)\n );\n\n let corner = localNdc[vertexIndex];\n let outerPx = in.radiiPx.y;\n let localPx = corner * outerPx;\n\n // Convert pixel offset to clip-space offset.\n // Clip space spans [-1, 1] across the viewport, so px -> clip is (2 / viewportPx).\n let localClip = localPx * (2.0 / vsUniforms.viewportPx);\n\n let centerClip = (vsUniforms.transform * vec4(in.center, 0.0, 1.0)).xy;\n\n var out: VSOut;\n out.clipPosition = vec4(centerClip + localClip, 0.0, 1.0);\n out.localPx = localPx;\n out.startAngleRad = in.startAngleRad;\n out.endAngleRad = in.endAngleRad;\n out.radiiPx = in.radiiPx;\n out.color = in.color;\n return out;\n}\n\nfn wrapToTau(theta: f32) -> f32 {\n // Maps theta to [0, TAU). (Input often comes from atan2 in [-PI, PI].)\n return select(theta, theta + TAU, theta < 0.0);\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n let p = in.localPx;\n let r = length(p);\n\n let innerPx = in.radiiPx.x;\n let outerPx = in.radiiPx.y;\n\n // --- Radial mask: ring between inner and outer radii (inner==0 => pie) ---\n // Positive inside the ring, negative outside.\n let radialDist = min(r - innerPx, outerPx - r);\n let radialW = fwidth(radialDist);\n let radialA = smoothstep(-radialW, radialW, radialDist);\n\n if (radialA <= 0.0) {\n discard;\n }\n\n // Compute fragment angle in [0, TAU).\n let angle = wrapToTau(atan2(p.y, p.x));\n\n // --- Angular mask: wedge between start/end angles with wrap ---\n let start = in.startAngleRad;\n let end = in.endAngleRad;\n\n // Compute span in [0, 2π) with wrap.\n var span = end - start;\n span = span + select(0.0, TAU, span < 0.0);\n\n // Compute rel in [0, 2π) with wrap.\n var rel = angle - start;\n rel = rel + select(0.0, TAU, rel < 0.0);\n\n let inside = rel <= span;\n\n // Signed angular distance (in radians) to nearest boundary.\n // - Inside: +min(rel, span-rel)\n // - Outside: -min(rel-span, 2π-rel)\n let dIn = min(rel, max(span - rel, 0.0));\n let dOutA = max(rel - span, 0.0);\n let dOutB = max(TAU - rel, 0.0);\n let dOut = min(dOutA, dOutB);\n\n let signedAngleDist = select(-dOut, dIn, inside);\n\n // Convert to approximate pixel distance to the boundary ray.\n // (For small angles, perpendicular distance to a ray ≈ r * angle.)\n let angleDistPx = signedAngleDist * max(r, 1.0);\n\n let angW = fwidth(angleDistPx);\n let angularA = smoothstep(-angW, angW, angleDistPx);\n\n let aOut = radialA * angularA;\n if (aOut <= 0.0) {\n discard;\n }\n\n return vec4(in.color.rgb, in.color.a * aOut);\n}\n\n",mt=2*Math.PI,pt=e=>Math.min(1,Math.max(0,e)),ht=(e,t,n)=>Math.min(n,Math.max(t,0|e)),gt=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},bt=e=>{if(!Number.isFinite(e))return 0;const t=e%mt;return t<0?t+mt:t},vt=(e,t)=>{const n=_(e);if(n)return[n[0],n[1],n[2],pt(n[3])];const i=_(t);return i?[i[0],i[1],i[2],pt(i[3])]:[0,0,0,1]},yt=(e,t)=>{if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"!=typeof e)return null;const n=e.trim();if(0===n.length)return null;if(n.endsWith("%")){const e=Number.parseFloat(n.slice(0,-1));return Number.isFinite(e)?e/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},xt=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);function wt(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),l=Ge(e,80,{label:"pieRenderer/vsUniforms"}),u=new ArrayBuffer(80),c=new Float32Array(u),d=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}}]}),f=Ue(e,{label:"pieRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:ft,label:"pie.wgsl",buffers:[{arrayStride:40,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:ft,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:o}},a);let m=null,p=0,h=new ArrayBuffer(0),g=new Float32Array(h),b=0,v=0,y=null;const x=()=>{if(n)throw new Error("PieRenderer is disposed.")};return{prepare:(t,n)=>{x();const i=n.devicePixelRatio,r=i>0&&Number.isFinite(i)?i:1;b=n.canvasWidth,v=n.canvasHeight,((t,n)=>{const i=Number.isFinite(t)&&t>0?t:1,r=Number.isFinite(n)&&n>0?n:1;c.set(xt,0),c[16]=i,c[17]=r,c[18]=0,c[19]=0,ze(e,l,u)})(n.canvasWidth,n.canvasHeight),y=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=ht(Math.floor(r),0,Math.max(0,t)),u=ht(Math.floor(a),0,Math.max(0,n)),c=ht(Math.ceil(o),0,Math.max(0,t)),d=ht(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(n);const o=n.canvasWidth/r,a=n.canvasHeight/r;if(!(o>0&&a>0))return void(p=0);const s=o-n.left-n.right,d=a-n.top-n.bottom;if(!(s>0&&d>0))return void(p=0);const f=.5*Math.min(s,d);if(!(f>0))return void(p=0);const w=((e,t,n)=>{const i=(null==e?void 0:e[0])??"50%",r=(null==e?void 0:e[1])??"50%",o=yt(i,t),a=yt(r,n);return{x:Number.isFinite(o)?o:.5*t,y:Number.isFinite(a)?a:.5*n}})(t.center,s,d),M=(n.left+w.x)/o*2-1,F=1-(n.top+w.y)/a*2;if(!Number.isFinite(M)||!Number.isFinite(F))return void(p=0);const N=((e,t)=>{if(null==e)return{inner:0,outer:.7*t};if((e=>Array.isArray(e))(e)){const n=yt(e[0],t),i=yt(e[1],t),r=Math.max(0,Number.isFinite(n)?n:0),o=Math.max(r,Number.isFinite(i)?i:.7*t);return{inner:r,outer:Math.min(t,o)}}const n=yt(e,t),i=Math.max(0,Number.isFinite(n)?n:.7*t);return{inner:0,outer:Math.min(t,i)}})(t.radius,f),C=Math.max(0,Math.min(N.inner,N.outer)),S=C*r,A=Math.max(C,N.outer)*r;if(!(A>0))return void(p=0);let I=0,P=0;for(let e=0;e0&&!1!==n.visible&&(I+=i,P++)}if(!(I>0)||0===P)return void(p=0);(e=>{if(e<=g.length)return;const t=Math.max(8,gt(e));h=new ArrayBuffer(4*t),g=new Float32Array(h)})(10*P);const R=g,E="number"==typeof t.startAngle&&Number.isFinite(t.startAngle)?t.startAngle:90;let B=bt(E*Math.PI/180),T=0,D=0,U=0;for(let e=0;e0))continue;const o=B,a=1===P?B+mt:bt(B+r);B=bt(B+r);const[s,l,u,c]=vt(n.color,t.color);R[D+0]=M,R[D+1]=F,R[D+2]=o,R[D+3]=a,R[D+4]=S,R[D+5]=A,R[D+6]=s,R[D+7]=l,R[D+8]=u,R[D+9]=c,D+=10}p=D/10;const k=Math.max(4,40*p);if(!m||m.size0&&e.queue.writeBuffer(m,0,h,0,40*p)},render:e=>{x(),m&&0!==p&&(y&&b>0&&v>0&&e.setScissorRect(y.x,y.y,y.w,y.h),e.setPipeline(f),e.setBindGroup(0,d),e.setVertexBuffer(0,m),e.draw(6,p),y&&b>0&&v>0&&e.setScissorRect(0,0,b,v))},dispose:()=>{if(!n){if(n=!0,m)try{m.destroy()}catch{}m=null,p=0;try{l.destroy()}catch{}b=0,v=0,y=null}}}}const Mt="// candlestick.wgsl\n// Instanced candlestick shader (bodies + wicks):\n// - Per-instance vertex input:\n// - xClip, openClip, closeClip, lowClip, highClip, bodyWidthClip (6 floats)\n// - bodyColor rgba (4 floats)\n// - Draw call: draw(18, instanceCount) using triangle-list expansion in VS\n// - vertices 0-5: body quad (2 triangles)\n// - vertices 6-11: upper wick (2 triangles)\n// - vertices 12-17: lower wick (2 triangles)\n// - Uniforms:\n// - @group(0) @binding(0): VSUniforms { transform, wickWidthClip }\n\nstruct VSUniforms {\n transform: mat4x4,\n wickWidthClip: f32,\n _pad0: f32,\n _pad1: f32,\n _pad2: f32,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct VSIn {\n @location(0) xClip: f32,\n @location(1) openClip: f32,\n @location(2) closeClip: f32,\n @location(3) lowClip: f32,\n @location(4) highClip: f32,\n @location(5) bodyWidthClip: f32,\n @location(6) bodyColor: vec4,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n @location(0) color: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Compute body bounds\n let bodyTop = max(in.openClip, in.closeClip);\n let bodyBottom = min(in.openClip, in.closeClip);\n let bodyLeft = in.xClip - in.bodyWidthClip * 0.5;\n let bodyRight = in.xClip + in.bodyWidthClip * 0.5;\n\n // Wick bounds\n let wickLeft = in.xClip - vsUniforms.wickWidthClip * 0.5;\n let wickRight = in.xClip + vsUniforms.wickWidthClip * 0.5;\n\n var pos: vec2;\n\n if (vertexIndex < 6u) {\n // Body quad (vertices 0-5)\n let corners = array, 6>(\n vec2(0.0, 0.0),\n vec2(1.0, 0.0),\n vec2(0.0, 1.0),\n vec2(0.0, 1.0),\n vec2(1.0, 0.0),\n vec2(1.0, 1.0)\n );\n let corner = corners[vertexIndex];\n let bodyMin = vec2(bodyLeft, bodyBottom);\n let bodyMax = vec2(bodyRight, bodyTop);\n pos = bodyMin + corner * (bodyMax - bodyMin);\n } else if (vertexIndex < 12u) {\n // Upper wick (vertices 6-11): from bodyTop to highClip\n let idx = vertexIndex - 6u;\n let corners = array, 6>(\n vec2(0.0, 0.0),\n vec2(1.0, 0.0),\n vec2(0.0, 1.0),\n vec2(0.0, 1.0),\n vec2(1.0, 0.0),\n vec2(1.0, 1.0)\n );\n let corner = corners[idx];\n let wickMin = vec2(wickLeft, bodyTop);\n let wickMax = vec2(wickRight, in.highClip);\n pos = wickMin + corner * (wickMax - wickMin);\n } else {\n // Lower wick (vertices 12-17): from lowClip to bodyBottom\n let idx = vertexIndex - 12u;\n let corners = array, 6>(\n vec2(0.0, 0.0),\n vec2(1.0, 0.0),\n vec2(0.0, 1.0),\n vec2(0.0, 1.0),\n vec2(1.0, 0.0),\n vec2(1.0, 1.0)\n );\n let corner = corners[idx];\n let wickMin = vec2(wickLeft, in.lowClip);\n let wickMax = vec2(wickRight, bodyBottom);\n pos = wickMin + corner * (wickMax - wickMin);\n }\n\n var out: VSOut;\n out.clipPosition = vsUniforms.transform * vec4(pos, 0.0, 1.0);\n out.color = in.bodyColor;\n return out;\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n return in.color;\n}\n",Ft=10,Nt=(e,t,n)=>Math.min(n,Math.max(t,0|e)),Ct=e=>_(e)??[0,0,0,1],St=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},At=e=>(e=>Array.isArray(e))(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};function It(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),l=Ge(e,80,{label:"candlestickRenderer/vsUniforms"});ze(e,l,(()=>{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})());const u=new ArrayBuffer(80),c=new Float32Array(u),d=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}}]}),f=Ue(e,{label:"candlestickRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:Mt,label:"candlestick.wgsl",buffers:[{arrayStride:40,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:Mt,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:o}},a);let m=null,p=0,h=new ArrayBuffer(0),g=new Float32Array(h),b=0,v=0,y=null,x=!1,w=null,M=0,F=new ArrayBuffer(0),N=new Float32Array(F);const C=()=>{if(n)throw new Error("CandlestickRenderer is disposed.")};return{prepare:(t,n,i,r,o,a)=>{if(C(),0===n.length)return p=0,void(M=0);const s=(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?{plotWidthCss:r,plotHeightCss:o}:null})(o);if(!s)return p=0,void(M=0);const d=(e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:a,devicePixelRatio:s}=e,l=t*s/o*2-1,u=(o-n*s)/o*2-1,c=1-i*s/a*2,d=1-(a-r*s)/a*2;return{left:l,right:u,top:c,bottom:d,width:u-l,height:c-d}})(o),f=s.plotWidthCss>0?d.width/s.plotWidthCss:0;b=o.canvasWidth,v=o.canvasHeight,y=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=Nt(Math.floor(r),0,Math.max(0,t)),u=Nt(Math.floor(a),0,Math.max(0,n)),c=Nt(Math.ceil(o),0,Math.max(0,t)),d=Nt(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(o);const S=(e=>{const t=[];for(let n=0;ne-t);let n=Number.POSITIVE_INFINITY;for(let e=1;e0&&i0?n:1})(n),A=((e,t,n,i)=>{if(Number.isFinite(t)&&t>0){const n=e.scale(0),i=e.scale(0+t),r=Math.abs(i-n);if(Number.isFinite(r)&&r>0)return r}const r=Math.abs(n.width);return r>0?r/Math.max(1,Math.floor(i)):0})(i,S,d,n.length);let I=0;const P=t.barWidth;if("number"==typeof P)I=Math.max(0,P)*f;else if("string"==typeof P){const e=(e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null})(P);I=null==e?0:A*(e=>Math.min(1,Math.max(0,e)))(e)}const R=t.barMinWidth*f,E=t.barMaxWidth*f;I=Math.min(Math.max(I,R),E);const B=t.itemStyle.borderWidth??1,T=Math.max(0,B)*f;c.set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,T,0,0,0]),ze(e,l,u);const D=Ct(t.itemStyle.upColor),U=Ct(t.itemStyle.downColor),k=Ct(t.itemStyle.upBorderColor),G=Ct(t.itemStyle.downBorderColor),z=a?Ct(a):[0,0,0,1];x="hollow"===t.style,(e=>{if(e<=g.length)return;const t=Math.max(8,St(e));h=new ArrayBuffer(4*t),g=new Float32Array(h)})(n.length*Ft);const V=g;let L=0;x&&(e=>{if(e<=N.length)return;const t=Math.max(8,St(e));F=new ArrayBuffer(4*t),N=new Float32Array(F)})(n.length*Ft);const W=N;let O=0;for(let e=0;ea;if(x){const e=g?k:G;if(V[L+0]=c,V[L+1]=d,V[L+2]=m,V[L+3]=p,V[L+4]=h,V[L+5]=I,V[L+6]=e[0],V[L+7]=e[1],V[L+8]=e[2],V[L+9]=e[3],L+=Ft,g){const e=t.itemStyle.borderWidth*f,n=Math.max(0,I-2*e);W[O+0]=c,W[O+1]=d,W[O+2]=m,W[O+3]=p,W[O+4]=h,W[O+5]=n,W[O+6]=z[0],W[O+7]=z[1],W[O+8]=z[2],W[O+9]=z[3],O+=Ft}}else{const e=g?D:U;V[L+0]=c,V[L+1]=d,V[L+2]=m,V[L+3]=p,V[L+4]=h,V[L+5]=I,V[L+6]=e[0],V[L+7]=e[1],V[L+8]=e[2],V[L+9]=e[3],L+=Ft}}p=L/Ft,M=O/Ft;const _=Math.max(4,40*p);if(!m||m.size<_){const t=Math.max(Math.max(4,St(_)),m?m.size:0);if(m)try{m.destroy()}catch{}m=e.createBuffer({label:"candlestickRenderer/instanceBuffer",size:t,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST})}if(p>0&&e.queue.writeBuffer(m,0,h,0,40*p),x&&M>0){const t=Math.max(4,40*M);if(!w||w.size{C(),m&&0!==p&&(y&&b>0&&v>0&&e.setScissorRect(y.x,y.y,y.w,y.h),e.setPipeline(f),e.setBindGroup(0,d),e.setVertexBuffer(0,m),e.draw(18,p),x&&w&&M>0&&(e.setVertexBuffer(0,w),e.draw(6,M)),y&&b>0&&v>0&&e.setScissorRect(0,0,b,v))},dispose:()=>{if(!n){if(n=!0,m)try{m.destroy()}catch{}if(m=null,p=0,w)try{w.destroy()}catch{}w=null,M=0;try{l.destroy()}catch{}b=0,v=0,y=null}}}}const Pt="// bar.wgsl\n// Instanced bar/rect shader:\n// - Per-instance vertex input:\n// - rect = vec4(x, y, width, height) in CLIP space\n// - color = vec4(r, g, b, a) in [0..1]\n// - Draw call: draw(6, instanceCount) using triangle-list expansion in VS\n// - Uniforms:\n// - @group(0) @binding(0): VSUniforms { transform }\n\nstruct VSUniforms {\n transform: mat4x4,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct VSIn {\n // rect.xy = origin, rect.zw = size (width, height)\n @location(0) rect: vec4,\n @location(1) color: vec4,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n @location(0) color: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fixed local corners for 2 triangles (triangle-list).\n let corners = array, 6>(\n vec2(0.0, 0.0),\n vec2(1.0, 0.0),\n vec2(0.0, 1.0),\n vec2(0.0, 1.0),\n vec2(1.0, 0.0),\n vec2(1.0, 1.0)\n );\n\n // Normalize negative width/height by computing min/max extents.\n let p0 = in.rect.xy;\n let p1 = in.rect.xy + in.rect.zw;\n let rectMin = min(p0, p1);\n let rectMax = max(p0, p1);\n let rectSize = rectMax - rectMin;\n\n let corner = corners[vertexIndex];\n let pos = rectMin + corner * rectSize;\n\n var out: VSOut;\n out.clipPosition = vsUniforms.transform * vec4(pos, 0.0, 1.0);\n out.color = in.color;\n return out;\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n return in.color;\n}\n\n",Rt=e=>Math.min(1,Math.max(0,e)),Et=e=>_(e)??[0,0,0,1],Bt=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))},Tt=e=>{if("string"!=typeof e)return"";const t=e.trim();return t.length>0?t:""};const Dt="\nstruct VSOut { @builtin(position) pos: vec4f };\n\n@vertex\nfn vsMain(@builtin(vertex_index) i: u32) -> VSOut {\n var positions = array(\n vec2f(-1.0, -1.0),\n vec2f( 3.0, -1.0),\n vec2f(-1.0, 3.0)\n );\n var o: VSOut;\n o.pos = vec4f(positions[i], 0.0, 1.0);\n return o;\n}\n\n// Using textureLoad (no filtering) for pixel-exact blit into the MSAA overlay pass.\n@group(0) @binding(0) var srcTex: texture_2d;\n\n@fragment\nfn fsMain(@builtin(position) pos: vec4f) -> @location(0) vec4f {\n let xy = vec2(pos.xy);\n return textureLoad(srcTex, xy, 0);\n}\n";function Ut(e){if(e)try{e.destroy()}catch{}}const kt="// crosshair.wgsl\n// Minimal crosshair line shader:\n// - Vertex input: vec2 position in clip-space coordinates\n// - VS uniform: transform mat4 (identity)\n// - FS uniform: solid RGBA color\n\nstruct VSUniforms {\n transform: mat4x4,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct FSUniforms {\n color: vec4,\n};\n\n@group(0) @binding(1) var fsUniforms: FSUniforms;\n\nstruct VSIn {\n @location(0) position: vec2,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn) -> VSOut {\n var out: VSOut;\n out.clipPosition = vsUniforms.transform * vec4(in.position, 0.0, 1.0);\n return out;\n}\n\n@fragment\nfn fsMain() -> @location(0) vec4 {\n return fsUniforms.color;\n}\n\n";const Gt=[1,1,1,.8],zt=(e,t,n)=>Math.min(n,Math.max(t,0|e)),Vt=(e,t)=>e/t*2-1,Lt=(e,t)=>1-e/t*2,Wt=(e,t)=>{e.push(t[0],t[1],t[2],t[3])},Ot=(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[];if(!Number.isFinite(10))return[];const r=Math.ceil((i-n)/10);if(!Number.isFinite(r)||r<=0)return[];const o=[];let a=n;for(;ae&&o.push([e,t]),a+=10}return o};function _t(e,t){let n=!1,i=!0;const r=(null==t?void 0:t.targetFormat)??"bgra8unorm",o=(null==t?void 0:t.sampleCount)??1,a=Number.isFinite(o)?Math.max(1,Math.floor(o)):1,s=null==t?void 0:t.pipelineCache,l=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),u=Ge(e,64,{label:"crosshairRenderer/vsUniforms"}),c=Ge(e,16,{label:"crosshairRenderer/fsUniforms"}),d=e.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:u}},{binding:1,resource:{buffer:c}}]}),f=Ue(e,{label:"crosshairRenderer/pipeline",bindGroupLayouts:[l],vertex:{code:kt,label:"crosshair.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:kt,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:a}},s),m=function(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=(e=>e+3&-4)(Math.max(4,Math.floor(t))),i=e.limits.maxBufferSize;if(n>i)throw new Error(`createStreamBuffer(maxSize): requested size ${n} bytes exceeds device.limits.maxBufferSize (${i}).`);const r=n>>>2,o=t=>({buffer:e.createBuffer({label:t,size:n,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),mirror:new Uint32Array(r)}),a=[o("streamBuffer/a"),o("streamBuffer/b")];let s=!1,l=0,u=0;const c=()=>{if(s)throw new Error("createStreamBuffer: StreamBuffer is disposed.")},d=(t,n,i)=>{const r=a[t],o=r.mirror;if(i<0||i>n.length)throw new Error("createStreamBuffer.write: internal error (invalid usedWords).");if(0===i)return;const s=i<<2;e.queue.writeBuffer(r.buffer,0,n.buffer,n.byteOffset,s),o.set(n.subarray(0,i),0)};return{write:t=>{if(c(),1&t.length)throw new Error("createStreamBuffer.write: data length must be even (vec2 vertices).");const i=t.byteLength;if(i>n)throw new Error(`createStreamBuffer.write: data.byteLength (${i}) exceeds capacity (${n}). Increase maxSize.`);const r=t.length>>>1;if(0===i)return void(u=r);const o=(e=>{if(3&e.byteOffset)throw new Error("createStreamBuffer.write: data.byteOffset must be 4-byte aligned.");return new Uint32Array(e.buffer,e.byteOffset,e.byteLength>>>2)})(t),s=1-l;((t,n,i)=>{const r=a[t],o=r.mirror;if(i<0||i>n.length)throw new Error("createStreamBuffer.write: internal error (invalid usedWords).");const s=i<<2;if(s>0&&s<=1024)return void d(t,n,i);const l=[];let u=0,c=0,f=0;for(;f=i)break;const e=f;for(f++;f128||c>16384)return void d(t,n,i)}for(let t=0;t(c(),a[l].buffer),getVertexCount:()=>(c(),u),dispose:()=>{if(!s){s=!0,u=0;for(const e of a)try{e.buffer.destroy()}catch{}}}}}(e,65536);let p=0,h=0,g=0,b={x:0,y:0,w:0,h:0};const v=()=>{if(n)throw new Error("CrosshairRenderer is disposed.")};return{prepare:(t,n,i,r)=>{if(v(),"boolean"!=typeof r.showX||"boolean"!=typeof r.showY)throw new Error("CrosshairRenderer.prepare: showX/showY must be boolean.");if("string"!=typeof r.color)throw new Error("CrosshairRenderer.prepare: color must be a string.");if(!Number.isFinite(r.lineWidth)||r.lineWidth<0)throw new Error("CrosshairRenderer.prepare: lineWidth must be a finite non-negative number.");const{vertices:o,scissor:a}=((e,t,n,i)=>{if(!Number.isFinite(e)||!Number.isFinite(t))throw new Error("CrosshairRenderer.prepare: x and y must be finite numbers.");if(!(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))(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,a=Number.isFinite(n.devicePixelRatio)&&n.devicePixelRatio>0?n.devicePixelRatio:1,s=n.left*a,l=r-n.right*a,u=n.top*a,c=o-n.bottom*a,d=zt(Math.floor(s),0,Math.max(0,r)),f=zt(Math.floor(u),0,Math.max(0,o)),m=zt(Math.ceil(l),0,Math.max(0,r)),p=zt(Math.ceil(c),0,Math.max(0,o)),h=Math.max(0,m-d),g=Math.max(0,p-f),b=e*a,v=t*a,y=((e,t)=>{if(!Number.isFinite(e)||e<0)throw new Error("CrosshairRenderer.prepare: lineWidth must be a finite non-negative number.");if(0===e)return[];const n=e*t,i=Math.max(1,Math.min(8,Math.round(n))),r=(i-1)/2,o=[];for(let e=0;e0&&F<=8192,C=e=>{const t=Vt(e,r),n=Lt(u,o),i=Lt(c,o);Wt(x,[t,n,t,i])},S=e=>{const t=Lt(e,o),n=Vt(s,r),i=Vt(l,r);Wt(x,[n,t,i,t])};if(i.showX)for(let e=0;e{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})());const s=_(r.color)??Gt,l=new ArrayBuffer(16);new Float32Array(l).set([s[0],s[1],s[2],s[3]]),ze(e,c,l),h=i.canvasWidth,g=i.canvasHeight,b=a},render:e=>{v(),i&&0!==p&&(h<=0||g<=0||(e.setScissorRect(b.x,b.y,b.w,b.h),e.setPipeline(f),e.setBindGroup(0,d),e.setVertexBuffer(0,m.getBuffer()),e.draw(p),e.setScissorRect(0,0,h,g)))},setVisible:e=>{v(),i=!!e},dispose:()=>{if(!n){n=!0;try{u.destroy()}catch{}try{c.destroy()}catch{}m.dispose(),p=0,h=0,g=0,b={x:0,y:0,w:0,h:0}}}}}const Yt="// highlight.wgsl\n// Draws an anti-aliased ring highlight around a point.\n//\n// Contract:\n// - `@builtin(position)` in the fragment stage is framebuffer-space pixels.\n// - The renderer supplies `center` and ring sizes in *device pixels*.\n\nstruct Uniforms {\n center: vec2,\n radius: f32,\n thickness: f32,\n color: vec4,\n outlineColor: vec4,\n};\n\n@group(0) @binding(0) var u: Uniforms;\n\nstruct VSOut {\n @builtin(position) position: vec4,\n};\n\n@vertex\nfn vsMain(@builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fullscreen triangle.\n // Covers clip-space [-1,1] with 3 verts: (-1,-1), (3,-1), (-1,3)\n let positions = array, 3>(\n vec2(-1.0, -1.0),\n vec2(3.0, -1.0),\n vec2(-1.0, 3.0)\n );\n\n var out: VSOut;\n out.position = vec4(positions[vertexIndex], 0.0, 1.0);\n return out;\n}\n\nfn ringCoverage(distancePx: f32, radiusPx: f32, thicknessPx: f32) -> f32 {\n let aa = 1.0; // ~1px antialias band (device pixels)\n let halfT = max(0.5, thicknessPx * 0.5);\n let a0 = smoothstep(radiusPx - halfT - aa, radiusPx - halfT + aa, distancePx);\n let a1 = smoothstep(radiusPx + halfT - aa, radiusPx + halfT + aa, distancePx);\n return clamp(a0 - a1, 0.0, 1.0);\n}\n\n@fragment\nfn fsMain(@builtin(position) fragPos: vec4) -> @location(0) vec4 {\n let d = distance(fragPos.xy, u.center);\n\n let ring = ringCoverage(d, u.radius, u.thickness);\n let outline = ringCoverage(d, u.radius, u.thickness + 2.0);\n\n let cover = max(ring, outline);\n if (cover <= 0.0) {\n discard;\n }\n\n // Blend between outline and ring color based on relative coverage,\n // then apply total coverage as alpha.\n let t = clamp(select(0.0, ring / cover, cover > 0.0), 0.0, 1.0);\n let rgb = mix(u.outlineColor.rgb, u.color.rgb, t);\n let a = mix(u.outlineColor.a, u.color.a, t) * cover;\n return vec4(rgb, a);\n}\n\n",Xt=[1,1,1,1],$t=e=>Math.min(1,Math.max(0,e)),Ht=(e,t,n)=>Math.min(n,Math.max(t,0|e));const qt='// Reference line renderer (axis-aligned, instanced quads).\n//\n// Coordinate conventions:\n// - Instance position is provided in CANVAS-LOCAL CSS pixels (same coordinate space as pointer events).\n// - Plot rect is provided in DEVICE pixels (computed from grid margins + DPR).\n// - Line width and dash lengths are provided in CSS pixels and converted in-shader using DPR.\n//\n// Scissoring/clipping:\n// - The render coordinator is expected to set a scissor rect for the plot area before drawing.\n// - This shader simply draws full-height/full-width quads; clipping is handled by scissor.\n//\n// Dash semantics:\n// - lineDash is a repeating on/off sequence in CSS pixels, starting with "on" at t=0.\n// - Up to 8 dash entries are supported per line (truncated on CPU).\n//\n// Performance:\n// - Vertex stage expands each instance into a quad (2 triangles, 6 vertices).\n// - We intentionally avoid snapping to integer device pixels to prevent visible stepping/jiggle\n// while zooming; edge AA is handled in the fragment stage.\n\nstruct VSUniforms {\n canvasSize : vec2, // device pixels (canvas.width, canvas.height)\n plotOrigin : vec2, // device pixels (plotLeft, plotTop)\n plotSize : vec2, // device pixels (plotWidth, plotHeight)\n devicePixelRatio : f32,\n _pad0 : f32,\n};\n\n@group(0) @binding(0) var u : VSUniforms;\n\nstruct VSIn {\n // axisPos.x = axis (0 = vertical, 1 = horizontal)\n // axisPos.y = position in CANVAS-LOCAL CSS pixels (x for vertical, y for horizontal)\n @location(0) axisPos : vec2,\n\n // widthDashCount.x = lineWidth in CSS px\n // widthDashCount.y = dashCount (float, cast to u32)\n @location(1) widthDashCount : vec2,\n\n // dashMeta.x = dashTotal (CSS px)\n // dashMeta.y = reserved (unused)\n @location(2) dashMeta : vec2,\n\n @location(3) dash0_3 : vec4,\n @location(4) dash4_7 : vec4,\n\n // Premultiplied or straight alpha is fine; blending is handled by pipeline state.\n @location(5) color : vec4,\n};\n\nstruct VSOut {\n @builtin(position) position : vec4,\n\n // Distance along the line in CSS pixels (0..plotLengthCss).\n @location(0) alongCss : f32,\n\n // Packed dash metadata to avoid extra varyings.\n // dashInfo.x = dashCount (float, cast to u32)\n // dashInfo.y = dashTotal (CSS px)\n @location(1) @interpolate(flat) dashInfo : vec2,\n\n @location(2) @interpolate(flat) dash0_3 : vec4,\n @location(3) @interpolate(flat) dash4_7 : vec4,\n @location(4) @interpolate(flat) color : vec4,\n\n // Axis-aligned quad anti-aliasing (device pixels).\n // acrossDevice ranges [0..widthDevice] across the stroke thickness.\n @location(5) acrossDevice : f32,\n @location(6) @interpolate(flat) widthDevice : f32,\n};\n\nfn quadUv(vid : u32) -> vec2 {\n // Two triangles covering [0,1]x[0,1].\n // 0: (0,0) 1:(1,0) 2:(0,1) 3:(0,1) 4:(1,0) 5:(1,1)\n switch (vid) {\n case 0u: { return vec2(0.0, 0.0); }\n case 1u: { return vec2(1.0, 0.0); }\n case 2u: { return vec2(0.0, 1.0); }\n case 3u: { return vec2(0.0, 1.0); }\n case 4u: { return vec2(1.0, 0.0); }\n default: { return vec2(1.0, 1.0); }\n }\n}\n\n@vertex\nfn vsMain(in : VSIn, @builtin(vertex_index) vid : u32) -> VSOut {\n let uv = quadUv(vid);\n let dpr = max(1e-6, u.devicePixelRatio);\n // IMPORTANT: Do NOT snap reference lines to integer device pixels.\n // Snapping looks crisp at rest but causes visible "jiggle" / stepping while zooming because\n // the line position is continuously changing (data-space → screen-space), and rounding\n // quantizes that motion to adjacent pixels. We rely on analytic AA in the fragment stage\n // to keep strokes stable and reasonably crisp across DPRs.\n\n let axis = in.axisPos.x;\n let posCss = in.axisPos.y;\n let widthCss = max(0.0, in.widthDashCount.x);\n let widthDevice = max(1.0, widthCss * dpr);\n\n var xDevice : f32;\n var yDevice : f32;\n var alongCss : f32;\n var acrossDevice : f32;\n\n if (axis < 0.5) {\n // Vertical line at x = posCss (canvas-local CSS px), spanning plot height.\n let centerX = posCss * dpr;\n let startX = centerX - 0.5 * widthDevice;\n xDevice = startX + uv.x * widthDevice;\n yDevice = u.plotOrigin.y + uv.y * u.plotSize.y;\n alongCss = (uv.y * u.plotSize.y) / dpr;\n acrossDevice = uv.x * widthDevice;\n } else {\n // Horizontal line at y = posCss (canvas-local CSS px), spanning plot width.\n let centerY = posCss * dpr;\n let startY = centerY - 0.5 * widthDevice;\n xDevice = u.plotOrigin.x + uv.x * u.plotSize.x;\n yDevice = startY + uv.y * widthDevice;\n alongCss = (uv.x * u.plotSize.x) / dpr;\n acrossDevice = uv.y * widthDevice;\n }\n\n let clipX = (xDevice / u.canvasSize.x) * 2.0 - 1.0;\n let clipY = 1.0 - (yDevice / u.canvasSize.y) * 2.0;\n\n var out : VSOut;\n out.position = vec4(clipX, clipY, 0.0, 1.0);\n out.alongCss = alongCss;\n out.dashInfo = vec2(in.widthDashCount.y, in.dashMeta.x);\n out.dash0_3 = in.dash0_3;\n out.dash4_7 = in.dash4_7;\n out.color = in.color;\n out.acrossDevice = acrossDevice;\n out.widthDevice = widthDevice;\n return out;\n}\n\nfn dashValue(i : u32, d0 : vec4, d1 : vec4) -> f32 {\n switch (i) {\n case 0u: { return d0.x; }\n case 1u: { return d0.y; }\n case 2u: { return d0.z; }\n case 3u: { return d0.w; }\n case 4u: { return d1.x; }\n case 5u: { return d1.y; }\n case 6u: { return d1.z; }\n default: { return d1.w; }\n }\n}\n\n@fragment\nfn fsMain(in : VSOut) -> @location(0) vec4 {\n // Analytic edge anti-aliasing for axis-aligned quads (reduces shimmering during zoom).\n // This is a lightweight alternative to full MSAA for thin strokes.\n let edgeDist = min(in.acrossDevice, in.widthDevice - in.acrossDevice);\n // Slightly widen AA to reduce temporal shimmer on moving 1-2px strokes.\n // Keep conservative so lines remain reasonably crisp.\n let aa = max(fwidth(in.acrossDevice), 1e-3) * 1.25;\n let edgeCoverage = smoothstep(0.0, aa, edgeDist);\n var color = in.color;\n color.a = color.a * edgeCoverage;\n\n let dashCount = u32(round(in.dashInfo.x));\n let dashTotal = in.dashInfo.y;\n\n // IMPORTANT: derivative ops (fwidth) must execute in uniform control flow.\n // So compute the dash parameterization unconditionally (using a safe total) BEFORE any early-return.\n let dashTotalSafe = max(dashTotal, 1.0);\n let t = in.alongCss - floor(in.alongCss / dashTotalSafe) * dashTotalSafe;\n // Anti-alias dash edges along the line axis (CSS pixels).\n // This reduces shimmer during zoom for dashed reference lines without requiring MSAA.\n let dashAa = max(fwidth(t), 1e-3);\n\n // Solid line (no dash pattern).\n if (dashCount == 0u || dashTotal <= 0.0) {\n return color;\n }\n\n var acc = 0.0;\n var on = true;\n\n for (var i : u32 = 0u; i < 8u; i = i + 1u) {\n if (i >= dashCount) { break; }\n let seg = dashValue(i, in.dash0_3, in.dash4_7);\n if (seg <= 0.0) { continue; }\n\n if (t < acc + seg) {\n // IMPORTANT: Avoid `discard` for off segments.\n // Discard can cause temporal popping on moving dashed edges; prefer a smooth alpha mask.\n //\n // Fade in/out near dash boundaries for smooth edges. This produces coverage in [0..1]\n // within the current segment, going to 0 at segment boundaries.\n let inFromStart = smoothstep(0.0, dashAa, t - acc);\n let inFromEnd = smoothstep(0.0, dashAa, (acc + seg) - t);\n let segCoverage = min(inFromStart, inFromEnd);\n\n // On segments contribute alpha; off segments contribute 0 alpha (no discard).\n let dashMask = select(0.0, segCoverage, on);\n color.a = color.a * dashMask;\n return color;\n }\n\n acc = acc + seg;\n on = !on;\n }\n\n // Defensive fallback if the dash list is degenerate.\n // If we didn\'t find a segment (shouldn\'t happen), default to transparent (safer than solid).\n color.a = 0.0;\n return color;\n}\n',jt=e=>{if(!e||0===e.length)return{dashCount:0,dashTotal:0,values:new Array(8).fill(0)};const t=[];for(let n=0;n0&&t.push(i)}if(0===t.length)return{dashCount:0,dashTotal:0,values:new Array(8).fill(0)};const n=t.length%2==1?t.concat(t):t,i=Math.min(8,n.length),r=new Array(8).fill(0);let o=0;for(let e=0;e{if(n)throw new Error("ReferenceLineRenderer is disposed.")};return{prepare:(t,n)=>{if(p(),!Array.isArray(n))throw new Error("ReferenceLineRenderer.prepare: lines must be an array.");if(!(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))(t))throw new Error("ReferenceLineRenderer.prepare: gridArea dimensions must be finite numbers.");if(t.canvasWidth<=0||t.canvasHeight<=0)throw new Error("ReferenceLineRenderer.prepare: canvas dimensions must be positive.");if(t.left<0||t.right<0||t.top<0||t.bottom<0)throw new Error("ReferenceLineRenderer.prepare: gridArea margins must be non-negative.");const i=Number.isFinite(t.devicePixelRatio)&&t.devicePixelRatio>0?t.devicePixelRatio:1,r=t.left*i,o=t.top*i,a=t.canvasWidth-t.right*i-r,s=t.canvasHeight-t.bottom*i-o;if(!(a>0&&s>0))return void(m=0);const u=new Float32Array(8);if(u[0]=t.canvasWidth,u[1]=t.canvasHeight,u[2]=r,u[3]=o,u[4]=a,u[5]=s,u[6]=i,u[7]=0,ze(e,l,u),0===n.length)return void(m=0);if(!d||f{if(p(),0===m||!d)return;const i=Number.isFinite(t)?Math.max(0,Math.floor(t)):0,r=Math.max(0,m-i),o=null==n?r:Number.isFinite(n)?Math.max(0,Math.min(r,Math.floor(n))):r;0!==o&&(e.setPipeline(c),e.setBindGroup(0,u),e.setVertexBuffer(0,d),e.draw(6,o,0,i))},dispose:()=>{if(!n){n=!0;try{l.destroy()}catch{}if(d)try{d.destroy()}catch{}d=null,f=0,m=0}}}}const Jt="// annotationMarker.wgsl\n// Instanced annotation marker shader (circle SDF with optional stroke).\n//\n// Coordinate contract:\n// - Instance center is CANVAS-LOCAL CSS pixels (xCssPx, yCssPx)\n// - Instance size is diameter in CSS pixels (sizeCssPx)\n// - Uniform provides render target size in *device* pixels and DPR for CSS→device conversion.\n//\n// Draw call: draw(6, instanceCount) using triangle-list quad expansion in VS.\n\nstruct VSUniforms {\n viewportPx: vec2, // render target size in device pixels (width, height)\n dpr: f32, // device pixel ratio (CSS px -> device px)\n _pad0: f32,\n};\n\n@group(0) @binding(0) var vsUniforms: VSUniforms;\n\nstruct VSIn {\n // Center in CANVAS-LOCAL CSS pixels.\n @location(0) centerCssPx: vec2,\n // Marker diameter in CSS pixels.\n @location(1) sizeCssPx: f32,\n // Stroke width in CSS pixels (0 disables stroke).\n @location(2) strokeWidthCssPx: f32,\n // Colors are straight-alpha RGBA in 0..1.\n @location(3) fillRgba: vec4,\n @location(4) strokeRgba: vec4,\n};\n\nstruct VSOut {\n @builtin(position) clipPosition: vec4,\n // Local quad coordinates in [-1, 1]^2 (used for circle SDF).\n @location(0) local: vec2,\n // Half-size in device pixels (radius in screen space).\n @location(1) halfSizePx: f32,\n @location(2) strokeWidthPx: f32,\n @location(3) fillRgba: vec4,\n @location(4) strokeRgba: vec4,\n};\n\n@vertex\nfn vsMain(in: VSIn, @builtin(vertex_index) vertexIndex: u32) -> VSOut {\n // Fixed local corners for 2 triangles (triangle-list).\n let localCorners = array, 6>(\n vec2(-1.0, -1.0),\n vec2( 1.0, -1.0),\n vec2(-1.0, 1.0),\n vec2(-1.0, 1.0),\n vec2( 1.0, -1.0),\n vec2( 1.0, 1.0)\n );\n\n let corner = localCorners[vertexIndex];\n\n let dpr = select(1.0, vsUniforms.dpr, vsUniforms.dpr > 0.0);\n let centerPx = in.centerCssPx * dpr;\n let halfSizePx = 0.5 * max(0.0, in.sizeCssPx) * dpr;\n let strokeWidthPx = max(0.0, in.strokeWidthCssPx) * dpr;\n\n let posPx = centerPx + corner * halfSizePx;\n\n // Convert device pixels to clip-space with origin at top-left:\n // x: [0..w] -> [-1..1], y: [0..h] -> [1..-1]\n let clipX = (posPx.x / vsUniforms.viewportPx.x) * 2.0 - 1.0;\n let clipY = 1.0 - (posPx.y / vsUniforms.viewportPx.y) * 2.0;\n\n var out: VSOut;\n out.clipPosition = vec4(clipX, clipY, 0.0, 1.0);\n out.local = corner;\n out.halfSizePx = halfSizePx;\n out.strokeWidthPx = strokeWidthPx;\n out.fillRgba = in.fillRgba;\n out.strokeRgba = in.strokeRgba;\n return out;\n}\n\n@fragment\nfn fsMain(in: VSOut) -> @location(0) vec4 {\n if (in.halfSizePx <= 0.0) {\n discard;\n }\n\n // Circle SDF in normalized space: dist == 1 at the circle boundary.\n let dist = length(in.local);\n let aa = max(1e-6, fwidth(dist));\n\n // Coverage inside the circle.\n let outerCoverage = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, dist);\n if (outerCoverage <= 0.0) {\n discard;\n }\n\n // Optional stroke: compute inner radius in normalized units.\n let strokeNorm = clamp(in.strokeWidthPx / max(1e-6, in.halfSizePx), 0.0, 1.0);\n let inner = max(0.0, 1.0 - strokeNorm);\n let innerCoverage = 1.0 - smoothstep(inner - aa, inner + aa, dist);\n\n let fillCoverage = clamp(innerCoverage, 0.0, 1.0);\n let strokeCoverage = clamp(outerCoverage - innerCoverage, 0.0, 1.0);\n\n let fillA = clamp(in.fillRgba.a, 0.0, 1.0) * fillCoverage;\n let strokeA = clamp(in.strokeRgba.a, 0.0, 1.0) * strokeCoverage;\n let outA = fillA + strokeA;\n if (outA <= 0.0) {\n discard;\n }\n\n // Straight-alpha output: compute a weighted average RGB for correct blending.\n let rgb = (in.fillRgba.rgb * fillA + in.strokeRgba.rgb * strokeA) / outA;\n return vec4(rgb, outA);\n}\n\n",Kt=e=>Math.min(1,Math.max(0,e)),Qt=e=>{if(!Number.isFinite(e)||e<=0)return 1;const t=Math.ceil(e);return 2**Math.ceil(Math.log2(t))};function en(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=(null==t?void 0:t.sampleCount)??1,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),l=Ge(e,16,{label:"annotationMarkerRenderer/vsUniforms"}),u=new Float32Array(4),c=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}}]}),d=Ue(e,{label:"annotationMarkerRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:Jt,label:"annotationMarker.wgsl",buffers:[{arrayStride:48,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:Jt,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}},a);let f=null,m=0,p=new ArrayBuffer(0),h=new Float32Array(p);const g=()=>{if(n)throw new Error("AnnotationMarkerRenderer is disposed.")};return{prepare:({canvasWidth:t,canvasHeight:n,devicePixelRatio:i,instances:r})=>{if(g(),!Number.isFinite(t)||!Number.isFinite(n)||t<=0||n<=0)throw new Error("AnnotationMarkerRenderer.prepare: canvasWidth/canvasHeight must be positive finite numbers.");if(!Array.isArray(r))throw new Error("AnnotationMarkerRenderer.prepare: instances must be an array.");((t,n,i)=>{const r=Number.isFinite(t)&&t>0?t:1,o=Number.isFinite(n)&&n>0?n:1,a=Number.isFinite(i)&&i>0?i:1;u[0]=r,u[1]=o,u[2]=a,u[3]=0,ze(e,l,u)})(t,n,i),(e=>{if(e<=h.length)return;const t=Math.max(32,Qt(e));p=new ArrayBuffer(4*t),h=new Float32Array(p)})(12*r.length);const o=h;let a=0;for(let e=0;e{if(g(),!f||0===m)return;const i=Number.isFinite(t)?Math.max(0,Math.floor(t)):0,r=Math.max(0,m-i),o=null==n?r:Number.isFinite(n)?Math.max(0,Math.min(r,Math.floor(n))):r;0!==o&&(e.setPipeline(d),e.setBindGroup(0,c),e.setVertexBuffer(0,f),e.draw(6,o,0,i))},dispose:()=>{if(!n){if(n=!0,f)try{f.destroy()}catch{}f=null,m=0;try{l.destroy()}catch{}}}}}const tn=(e,t,n)=>Math.min(n,Math.max(t,e));const nn=(e,t,n)=>Math.min(n,Math.max(t,e)),rn=e=>nn(e,0,1),on=e=>Object.is(e,-0)?0:e;const an=new WeakMap,sn=e=>{const t="object"==typeof e&&null!==e?e:null;if(t&&an.has(t))return an.get(t);let n=!1;const i=s(e);for(let t=0;t{let n=0,i=s(e);for(;n>>1;l(e,r){const n=[];for(let t=0;te.s),t),r=i.barWidthPx,o=i.gapPx,a=i.clusterWidthPx;if(!(Number.isFinite(r)&&r>0))return null;const s=new Map;for(let e=0;e0&&Number.isFinite(s)){let e=-1;const o=e=>{if(!Number.isFinite(e))return!1;const n=e+s;return t>=n-h&&t{if(e<0||e>=p)return null;const t=l(m,e);if(!Number.isFinite(t))return null;const i=n.scale(t);return Number.isFinite(i)?i:null};for(let n=o-1;n>=0;n--){const i=a(n);if(null===i)continue;const o=i+s,l=o+r;if(l+h<=t)break;t>=o-h&&tt)break;t=0){const t=l(m,e),n=u(m,e),r=c(m,e),o=void 0!==r?[t,n,r]:[t,n];d.push({seriesIndex:i,dataIndex:e,point:o});continue}}}}let h=-1,g=null,b=o;const v=(e,t)=>{if(!Number.isFinite(t)||!(t{const i=l(m,e);if(!Number.isFinite(i))return null;const r=n.scale(i);if(!Number.isFinite(r))return null;const o=r-t;return o*o};for(;i>=0||r=0&&null===o(i);)i--;for(;r=p)break;const e=i>=0?o(i)??Number.POSITIVE_INFINITY:Number.POSITIVE_INFINITY,t=rb&&t>b)break;e<=t?(i>=0&&e<=b&&v(i,e),i--,rArray.isArray(e),dn=e=>cn(e)?e[0]:e.timestamp,fn=new WeakMap;function mn(e,t,n,i){if(0===t.length)return 0;const r=(e=>{const t=fn.get(e);if(void 0!==t)return t;const n=[];for(let t=0;te-t);let i=Number.POSITIVE_INFINITY;for(let e=1;e0&&t0?i:1;return fn.set(e,r),r})(t);let o=0;if(Number.isFinite(r)&&r>0){let e=null;for(let n=0;n0&&(o=a)}}(!(o>0)||!Number.isFinite(o))&&(o=(Number.isFinite(i??Number.NaN)?i:0)/Math.max(1,t.length));let a=0;const s=e.barWidth;if("number"==typeof s)a=Number.isFinite(s)?Math.max(0,s):0;else if("string"==typeof s){const e=(e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null})(s);a=null==e?0:o*(e=>Math.min(1,Math.max(0,e)))(e)}const l=Number.isFinite(e.barMinWidth)?Math.max(0,e.barMinWidth):0,u=Number.isFinite(e.barMaxWidth)?Math.max(0,e.barMaxWidth):Number.POSITIVE_INFINITY,c=Math.max(l,u);return a=Math.min(Math.max(a,l),c),Number.isFinite(a)?a:0}const pn=new WeakMap,hn=e=>{const t=pn.get(e);if(void 0!==t)return t;let n=Number.NEGATIVE_INFINITY;for(let t=0;t{let n=0,i=e.length;for(;n>>1;dn(e[r])0))return null;const a=i.invert(t);if(!Number.isFinite(a))return null;const s=o/2;let l=null,u=Number.POSITIVE_INFINITY;const c=(e,t,n,i)=>{if(Number.isFinite(i)){if(i{const t=(e=>cn(e)?e[1]:e.open)(e),i=(e=>cn(e)?e[2]:e.close)(e);if(!Number.isFinite(t)||!Number.isFinite(i))return!1;const o=r.scale(t),a=r.scale(i);if(!Number.isFinite(o)||!Number.isFinite(a))return!1;const s=Math.min(o,a),l=Math.max(o,a);return n>=s&&n<=l};for(let n=0;ns||d(o)&&c(n,e,o,u)}continue}const l=gn(r,a);for(let e=l-1;e>=0;e--){const o=r[e],a=dn(o),l=i.scale(a);if(!Number.isFinite(l))continue;if(ls||d(o)&&c(n,e,o,u)}for(let e=l;et+s)break;const u=Math.abs(t-l);u>s||d(o)&&c(n,e,o,u)}}return l}const vn=2*Math.PI,yn=e=>{if(!Number.isFinite(e))return 0;const t=e%vn;return t<0?t+vn:t};function xn(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,a=Number.isFinite(r.outer)?Math.max(0,r.outer):0;if(!(a>0))return null;const s=e-i.x,l=i.y-t,u=Math.hypot(s,l);if(!Number.isFinite(u)||u<=o||u>a)return null;const c=yn(Math.atan2(l,s)),d=n.series,f=d.data;let m=0,p=0;for(let e=0;e0&&!1!==t.visible&&(m+=n,p++)}if(!(m>0)||0===p)return null;const h="number"==typeof d.startAngle&&Number.isFinite(d.startAngle)?d.startAngle:90;let g=yn(h*Math.PI/180),b=0,v=0;for(let e=0;e0))continue;const o=g,a=1===p?g+vn:yn(g+r);g=yn(g+r);let s=a-o;s<0&&(s+=vn);let l=c-o;if(l<0&&(l+=vn),l<=s)return{seriesIndex:n.seriesIndex,dataIndex:e,slice:t}}return null}const wn=(e,t)=>{if(!Number.isFinite(t))throw new Error(`${e} must be a finite number. Received: ${String(t)}`)};function Mn(){let e=0,t=1,n=0,i=1;const r={domain:(n,i)=>(wn("domain min",n),wn("domain max",i),e=n,t=i,r),range:(e,t)=>(wn("range min",e),wn("range max",t),n=e,i=t,r),scale:r=>Number.isFinite(r)?e===t?(n+i)/2:n+(r-e)/(t-e)*(i-n):Number.NaN,invert:r=>Number.isFinite(r)?e===t?e:n===i?(e+t)/2:e+(r-n)/(i-n)*(t-e):Number.NaN};return r}function Fn(e,t){const n=getComputedStyle(e),i=n.position,r=n.overflow,o=(null==t?void 0:t.clip)??!1,a="static"===i,s=!o&&("hidden"===r||"scroll"===r||"auto"===r),l=a?e.style.position:null,u=s?e.style.overflow:null;a&&(e.style.position="relative"),s&&(e.style.overflow="visible");const c=document.createElement("div");c.style.position="absolute",c.style.inset="0",c.style.pointerEvents="none",c.style.overflow=o?"hidden":"visible",c.style.zIndex="10",e.appendChild(c);let d=!1;return{clear:()=>{d||c.replaceChildren()},addLabel:(e,t,n,i)=>{if(d)return document.createElement("span");const r=document.createElement("span");r.textContent=e,r.style.position="absolute",r.style.left=`${t}px`,r.style.top=`${n}px`,r.style.pointerEvents="none",r.style.userSelect="none",r.style.whiteSpace="nowrap",r.style.lineHeight="1",null!=(null==i?void 0:i.fontSize)&&(r.style.fontSize=`${i.fontSize}px`),null!=(null==i?void 0:i.color)&&(r.style.color=i.color);const o=(null==i?void 0:i.rotation)??0,a=(null==i?void 0:i.anchor)??"start",{translateX:s,originX:l}=(e=>{switch(e){case"start":return{translateX:"0%",originX:"0%"};case"middle":return{translateX:"-50%",originX:"50%"};case"end":return{translateX:"-100%",originX:"100%"}}})(a);return r.style.transformOrigin=`${l} 50%`,r.style.transform=`translateX(${s}) translateY(-50%) rotate(${o}deg)`,c.appendChild(r),r},dispose:()=>{if(!d){d=!0;try{c.remove()}finally{null!==l&&(e.style.position=l),null!==u&&(e.style.overflow=u)}}}}}const Nn=(e,t)=>{var n;return(null==(n=e.name)?void 0:n.trim())||`Series ${t+1}`},Cn=(e,t,n)=>{var i;const r=null==(i=e.color)?void 0:i.trim();if(r)return r;const o=n.colorPalette;return o.length>0?o[t%o.length]??"#000000":"#000000"},Sn=(e,t)=>(null==e?void 0:e.trim())||`Slice ${t+1}`,An=(e,t,n,i)=>{const r=null==e?void 0:e.trim();if(r)return r;const o=i.colorPalette,a=o.length;return a>0?o[(t+n)%a]??"#000000":"#000000"},In=(e,t,n)=>nn?n:e;function Pn(e){const t="static"===getComputedStyle(e).position,n=t?e.style.position:null;t&&(e.style.position="relative");const i=document.createElement("div");i.style.position="absolute",i.style.left="0",i.style.top="0",i.style.pointerEvents="none",i.style.userSelect="none",i.style.boxSizing="border-box",i.style.zIndex="var(--chartgpu-tooltip-z, 10)",i.style.padding="var(--chartgpu-tooltip-padding, 6px 8px)",i.style.borderRadius="var(--chartgpu-tooltip-radius, 8px)",i.style.borderStyle="solid",i.style.borderWidth="var(--chartgpu-tooltip-border-width, 1px)",i.style.borderColor="var(--chartgpu-tooltip-border, rgba(224,224,224,0.35))",i.style.boxShadow="var(--chartgpu-tooltip-shadow, 0 6px 18px rgba(0,0,0,0.35))",i.style.maxWidth="var(--chartgpu-tooltip-max-width, min(320px, 100%))",i.style.overflow="hidden",i.style.fontFamily='var(--chartgpu-tooltip-font-family, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji")',i.style.fontSize="var(--chartgpu-tooltip-font-size, 12px)",i.style.lineHeight="var(--chartgpu-tooltip-line-height, 1.2)",i.style.color="var(--chartgpu-tooltip-color, #e0e0e0)",i.style.background="var(--chartgpu-tooltip-bg, rgba(26,26,46,0.95))",i.style.whiteSpace="normal",i.style.opacity="0",i.style.transitionProperty="opacity",i.style.transitionDuration="140ms",i.style.transitionTimingFunction="ease",i.style.willChange="opacity",i.style.display="none",i.style.visibility="hidden",i.setAttribute("role","tooltip"),e.appendChild(i);let r=!1,o=0,a=null,s=null;const l=()=>{null!=a&&(window.clearTimeout(a),a=null),null!=s&&(window.cancelAnimationFrame(s),s=null)};return{show:(t,n,a)=>{if(r)return;o+=1,l();const u="none"===i.style.display||"hidden"===i.style.visibility;i.innerHTML=a,i.style.display="block",i.style.visibility="hidden";const{width:c,height:d}=(()=>{const e=i.style.visibility;i.style.visibility="hidden";const t=i.offsetWidth,n=i.offsetHeight;return i.style.visibility=e,{width:t,height:n}})(),f=e.clientWidth,m=e.clientHeight;let p=t+12,h=n+12;if(p+c>f-8&&(p=t-12-c),h+d>m-8&&(h=n-12-d),p=In(p,8,f-8-c),h=In(h,8,m-8-d),i.style.left=`${p}px`,i.style.top=`${h}px`,i.style.visibility="visible",u){i.style.opacity="0";const e=o;s=window.requestAnimationFrame(()=>{s=null,!r&&e===o&&(i.style.opacity="1")})}else i.style.opacity="1"},hide:()=>{if(r)return;if(o+=1,l(),"none"===i.style.display||"hidden"===i.style.visibility)return i.style.opacity="0",i.style.visibility="hidden",void(i.style.display="none");i.style.opacity="0";const e=o;a=window.setTimeout(()=>{a=null,!r&&e===o&&(i.style.visibility="hidden",i.style.display="none")},190)},dispose:()=>{if(!r){r=!0;try{l(),i.remove()}finally{null!==n&&(e.style.position=n)}}}}}function Rn(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function En(e){if(!Number.isFinite(e))return"—";const t=(Object.is(e,-0)?0:e).toFixed(2).replace(/\.?0+$/,"");return"-0"===t?"0":t}function Bn(e){const t=e.seriesName.trim();return t.length>0?t:`Series ${e.seriesIndex+1}`}function Tn(e){const t=e.trim();return 0===t.length?"#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 Dn(e){return 5===e.length}function Un(e,t){const n=Rn(Bn(e)),i=Rn(t);return['
','',``,`${n}`,"",`${i}`,"
"].join("")}function kn(e){const[,t,n,i,r]=e.value,o=Rn(Bn(e)),a=Rn(Tn(e.color)),s=En(t),l=En(r),u=En(i),c=En(n),d=n>t,f=d?"▲":"▼",m=d?"#22c55e":"#ef4444",p=function(e,t){if(!Number.isFinite(e)||!Number.isFinite(t)||0===e)return"—";const n=(t-e)/e*100;return Number.isFinite(n)?`${n>0?"+":""}${n.toFixed(2)}%`:"—"}(t,n),h=Rn(`O: ${s} H: ${l} L: ${u} C: ${c}`),g=Rn(f),b=Rn(p),v=Rn(m);return['
','
',``,`${o}`,"
",`
${h}
`,'
',`${g}`,`${b}`,"
","
"].join("")}function Gn(e){return Dn(e.value)?function(e){return kn(e)}(e):Un(e,En(e.value[1]))}function zn(e){return 0===e.length?"":`
${Rn(`x: ${En(e[0].value[0])}`)}
${e.map(e=>Dn(e.value)?kn(e):Un(e,En(e.value[1]))).join('
')}`}const Vn=e=>Number.isFinite(e)?e:0;function Ln(){const e=new Map;return{animate:function(t,n,i,r,o,a){const s=Symbol("Animation");if(Array.isArray(t)||Array.isArray(n)){if(!Array.isArray(t)||!Array.isArray(n))throw new Error('Array animation requires both "from" and "to" to be arrays');if(t.length!==n.length)throw new Error(`Array animation length mismatch: from.length=${t.length}, to.length=${n.length}`);const l=new Array(t.length);return e.set(s,{kind:"array",from:t,to:n,duration:i,easing:r,onUpdate:o,onComplete:a,startTime:null,out:l}),s}return e.set(s,{kind:"scalar",from:t,to:n,duration:i,easing:r,onUpdate:o,onComplete:a,startTime:null}),s},cancel:function(t){e.delete(t)},cancelAll:function(){e.clear()},update:function(t){var n;const i=(e=>Number.isFinite(e)?e:null)(t);if(null===i)return;const r=Array.from(e.keys());for(const t of r){const r=e.get(t);if(!r)continue;const o=r.startTime??i;null===r.startTime&&e.set(t,{...r,startTime:o});const a=Vn(r.duration),s=Math.max(0,i-o),l=a<=0||s>=a,u=a<=0?1:s/a,c=l?1:r.easing(u);if("scalar"===r.kind){const n=r.from+(r.to-r.from)*c;if(r.onUpdate(n),!e.has(t))continue}else{const n=r.out.length;for(let e=0;eNumber.isNaN(e)||e<=0?0:e>=1?1:e;function On(e){return Wn(e)}function _n(e){const t=1-Wn(e);return 1-t*t*t}function Yn(e){const t=Wn(e);if(t<.5)return 4*t*t*t;const n=-2*t+2;return 1-n*n*n/2}function Xn(e){const t=Wn(e),n=7.5625,i=2.75;if(t<1/i)return n*t*t;if(t<2/i){const e=t-1.5/i;return n*e*e+.75}if(t<2.5/i){const e=t-2.25/i;return n*e*e+.9375}const r=t-2.625/i;return n*r*r+.984375}function $n(e){switch(e){case"linear":default:return On;case"cubicOut":return _n;case"cubicInOut":return Yn;case"bounceOut":return Xn}}const Hn=function(e){return typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement},qn=864e5,jn=30*qn,Zn=365*qn,Jn=e=>"number"==typeof e&&Number.isFinite(e)?e:null,Kn=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0,Qn=e=>{throw new Error(`RenderCoordinator: unreachable value: ${String(e)}`)},ei=e=>Array.isArray(e),ti=e=>{const t=s(e);if(0===t)return{x:[],y:[]};const n=new Array(t),i=new Array(t);let r,o=!1;for(let a=0;a{const n=f(t);if(!n)return e;if(!e)return n;let i=Math.min(e.xMin,n.xMin),r=Math.max(e.xMax,n.xMax),o=Math.min(e.yMin,n.yMin),a=Math.max(e.yMax,n.yMax);return i===r&&(r=i+1),o===a&&(a=o+1),{xMin:i,xMax:r,yMin:o,yMax:a}},ii=(e,t)=>{if(0===t.length)return e;let n=(null==e?void 0:e.xMin)??Number.POSITIVE_INFINITY,i=(null==e?void 0:e.xMax)??Number.NEGATIVE_INFINITY,r=(null==e?void 0:e.yMin)??Number.POSITIVE_INFINITY,o=(null==e?void 0:e.yMax)??Number.NEGATIVE_INFINITY;for(let e=0;ei&&(i=s),lo&&(o=u))}return Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(o)?(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o}):e},ri=(e,t)=>{let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(let a=0;ai&&(i=e.xMax),e.yMino&&(o=e.yMax);continue}}const f=c.rawBounds;if(f){const e=f;if(Number.isFinite(e.xMin)&&Number.isFinite(e.xMax)&&Number.isFinite(e.yMin)&&Number.isFinite(e.yMax)){e.xMini&&(i=e.xMax),e.yMino&&(o=e.yMax);continue}}if("candlestick"===c.type){const e=c.rawData??c.data;for(let t=0;ti&&(i=e),lo&&(o=u)}else{const e=a.timestamp,t=a.low,s=a.high;if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(s))continue;const l=Math.min(t,s),u=Math.max(t,s);ei&&(i=e),lo&&(o=u)}}continue}const m=c.data,p=s(m);for(let e=0;ei&&(i=t),ao&&(o=a))}}return Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(o)?(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o}):{xMin:0,xMax:1,yMin:0,yMax:1}},oi=(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 e=n;n=i,i=e}return{min:n,max:i}},ai=(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,a=n.height;if(!Number.isFinite(o)||!Number.isFinite(a))throw new Error(`RenderCoordinator: Invalid canvas dimensions: width=${o}, height=${a}. Canvas must be initialized with finite dimensions before rendering.`);const s=Math.max(1,Math.floor(o)),l=Math.max(1,Math.floor(a)),u=Number.isFinite(t.grid.left)?t.grid.left:0,c=Number.isFinite(t.grid.right)?t.grid.right:0,d=Number.isFinite(t.grid.top)?t.grid.top:0,f=Number.isFinite(t.grid.bottom)?t.grid.bottom:0;return{left:Math.max(0,u),right:Math.max(0,c),top:Math.max(0,d),bottom:Math.max(0,f),canvasWidth:s,canvasHeight:l,devicePixelRatio:r}},si=(e,t)=>{const n=_(e);if(!n)return e;const i=Math.max(0,Math.min(1,n[3]*t));return(e=>`rgba(${Math.max(0,Math.min(255,Math.round(255*e[0])))},${Math.max(0,Math.min(255,Math.round(255*e[1])))},${Math.max(0,Math.min(255,Math.round(255*e[2])))},${Math.max(0,Math.min(1,e[3]))})`)([n[0],n[1],n[2],i])},li=e=>Math.min(1,Math.max(0,e)),ui=(e,t,n)=>Math.min(n,Math.max(t,0|e)),ci=(e,t,n)=>e+(t-e)*li(n),di=(e,t,n)=>oi(ci(e.min,t.min,n),ci(e.max,t.max,n)),fi=(e,t)=>(e+1)/2*t,mi=(e,t)=>(1-e)/2*t,pi=A,hi=(e,t)=>{if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"!=typeof e)return null;const n=e.trim();if(0===n.length)return null;if(n.endsWith("%")){const e=Number.parseFloat(n.slice(0,-1));return Number.isFinite(e)?e/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},gi=(e,t,n)=>{const i=(null==e?void 0:e[0])??"50%",r=(null==e?void 0:e[1])??"50%",o=hi(i,t),a=hi(r,n);return{x:Number.isFinite(o)?o:.5*t,y:Number.isFinite(a)?a:.5*n}},bi=(e,t)=>{if(null==e)return{inner:0,outer:.7*t};if((e=>Array.isArray(e))(e)){const n=hi(e[0],t),i=hi(e[1],t),r=Math.max(0,Number.isFinite(n)?n:0),o=Math.max(r,Number.isFinite(i)?i:.7*t);return{inner:r,outer:Math.min(t,o)}}const n=hi(e,t),i=Math.max(0,Number.isFinite(n)?n:.7*t);return{inner:0,outer:Math.min(t,i)}},vi=e=>String(Math.trunc(e)).padStart(2,"0"),yi=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],xi=(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(),a=n.getHours(),s=n.getMinutes();return t{const i=Math.max(1,Math.floor(n)),r=new Array(i);for(let n=0;n{const n=ri(e.series,t),i=Kn(e.xAxis.min)??n.xMin,r=Kn(e.xAxis.max)??n.xMax;return oi(i,r)},Fi=(e,t,n)=>{const i=Kn(e.yAxis.min),r=Kn(e.yAxis.max);if(void 0!==i&&void 0!==r)return oi(i,r);let o;o="visible"===(e.yAxis.autoBounds??"visible")&&n?n:ri(e.series,t);const a=i??o.yMin,s=r??o.yMax;return oi(a,s)},Ni=(e,t)=>{if(!t)return{...e,spanFraction:1};const n=e.max-e.min;if(!Number.isFinite(n)||0===n)return{...e,spanFraction:1};const i=t.start,r=t.end,o=e.min+i/100*n,a=e.min+r/100*n,s=oi(o,a),l=(r-i)/100,u=Number.isFinite(l)?Math.max(0,Math.min(1,l)):1;return{min:s.min,max:s.max,spanFraction:u}},Ci=e=>{if(!1===e||null==e)return null;const t=!0===e?{}:e;if(!t)return null;const n=t.duration??300,i=t.delay??0;return{durationMs:Number.isFinite(n)?Math.max(0,n):300,delayMs:Number.isFinite(i)?Math.max(0,i):0,easing:$n(t.easing)}},Si=(e,t,n,i,r)=>{const o=e.point,a=pi(o)?o[0]:o.timestamp,s=pi(o)?o[1]:o.open,l=pi(o)?o[2]:o.close;if(!Number.isFinite(a)||!Number.isFinite(s)||!Number.isFinite(l))return null;const u=(s+l)/2,c=t.scale(a),d=n.scale(u);if(!Number.isFinite(c)||!Number.isFinite(d))return null;const f=i.left+c,m=i.top+d,p=Hn(r)?r.offsetLeft+f:f,h=Hn(r)?r.offsetTop+m:m;return Number.isFinite(p)&&Number.isFinite(h)?{x:p,y:h}:null},Ai=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;in&&(n=i))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t){const t=e.target.closest("[data-series-index]");if(t){const e=parseInt(t.dataset.seriesIndex,10);if(!isNaN(e)){const i=t.dataset.sliceIndex;if(void 0!==i){const t=parseInt(i,10);if(!isNaN(t))return void n(e,t)}n(e)}}}),a.addEventListener("keydown",e=>{if("Enter"===e.key||" "===e.key){const t=e.target.closest("[data-series-index]");if(t){e.preventDefault();const i=parseInt(t.dataset.seriesIndex,10);if(!isNaN(i)){const e=t.dataset.sliceIndex;if(void 0!==e){const t=parseInt(e,10);if(!isNaN(t))return void n(i,t)}n(i)}}}})),(e=>{switch(o.style.top="",o.style.right="",o.style.bottom="",o.style.left="",o.style.maxWidth="",a.style.flexDirection="",a.style.flexWrap="",a.style.alignItems="",e){case"right":return o.style.top="8px",o.style.right="8px",o.style.maxWidth="40%",a.style.flexDirection="column",a.style.flexWrap="nowrap",void(a.style.alignItems="flex-start");case"left":return o.style.top="8px",o.style.left="8px",o.style.maxWidth="40%",a.style.flexDirection="column",a.style.flexWrap="nowrap",void(a.style.alignItems="flex-start");case"top":return o.style.top="8px",o.style.left="8px",o.style.right="8px",a.style.flexDirection="row",a.style.flexWrap="wrap",void(a.style.alignItems="center");case"bottom":o.style.bottom="8px",o.style.left="8px",o.style.right="8px",a.style.flexDirection="row",a.style.flexWrap="wrap",a.style.alignItems="center"}})(t),e.appendChild(o);let s=!1;return{update:(e,t)=>{if(s)return;o.style.color=t.textColor,o.style.background=t.backgroundColor,o.style.borderColor=t.axisLineColor,o.style.fontFamily=t.fontFamily,o.style.fontSize=`${t.fontSize}px`;const i=[];for(let r=0;r{if(!s){s=!0;try{o.remove()}finally{null!==r&&(e.style.position=r)}}}}}(x,null==(r=t.legend)?void 0:r.position,(e,t)=>{if(P)return;const n=R.series;if(e<0||e>=n.length)return;const i=n[e];if(!i)return;if(void 0!==t&&"pie"===i.type){const r=i.data;if(t<0||t>=r.length)return;const o=r.map((e,n)=>n===t?{...e,visible:!1===e.visible}:e),a=n.map((t,n)=>n===e?{...t,data:o}:t);return void wn({...R,series:a})}const r=n.map((t,n)=>n===e?{...t,visible:!1===t.visible}:t);wn({...R,series:r})}):null,A=(()=>{if(typeof document>"u")return null;try{return document.createElement("canvas").getContext("2d")}catch{return null}})(),I=A?new Map:null;let P=!1,R=t,E=t.series.length,B="pending",T=0;const D=Ln();let z=null,V=!1;const L=Ln();let W=null,O=1,$=null;const j={cartesianDataBySeriesIndex:[],pieDataBySeriesIndex:[]},Z=()=>{j.cartesianDataBySeriesIndex.length=0,j.pieDataBySeriesIndex.length=0},J=(e,t,n,i,r)=>{if(0===n)return r??[];const o=r&&r.length===n?r:(()=>{const e=new Array(n);for(let i=0;i{var r,o;const a=e.data,s=t.data;if(a.length!==s.length)return t;const l=s.length,u=i&&i.length===l?i:(()=>{const e=new Array(l);for(let t=0;t{if(e.length!==t.length)return t;const r=new Array(t.length);for(let o=0;o2e4){r[o]=l;continue}const m=(null==i?void 0:i.cartesianDataBySeriesIndex[o])??null,p=J(u,c,d,n,m);p?(i&&(i.cartesianDataBySeriesIndex[o]=p),r[o]={...l,data:p}):r[o]=l}return r},te=new Set,fe=new Set;let he=new Array(t.series.length).fill(null),ge=new Array(t.series.length).fill(null),be=R.series,ve=R.series,ye=null;const xe=()=>{ye=(e=>{if("visible"!==(e.yAxis.autoBounds??"visible"))return!1;const t=Kn(e.yAxis.min),n=Kn(e.yAxis.max);return!(void 0!==t&&void 0!==n)})(R)?(e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;in&&(n=l)}continue}const o=r.data,a=s(o);for(let e=0;en&&(n=i))}}return Number.isFinite(t)&&Number.isFinite(n)?(t===n&&(n=t+1),{xMin:0,xMax:1,yMin:t,yMax:n}):{xMin:0,xMax:1,yMin:0,yMax:1}})(ve):null};let we=[],Me=!1,Fe=null,Te=null,De=null,ke=!1,Ve=!1;const Le=new Map;let _e=new Array(R.series.length).fill("unknown");const Ye=new Set;let Xe=x&&!1!==(null==(o=R.tooltip)?void 0:o.show)?Pn(x):null,He=null,qe=null,je=null;const Je=(e,t,n,i)=>{null==Xe||Xe.show(e,t,n)},Ke=()=>{null==Xe||Xe.hide()},Qe=()=>{He=null,qe=null,je=null,Ke()};var et,nt;et=R.series,nt=R.theme,null==F||F.update(et,nt);let it=function(e){const t=new Map;let n=!1;const i=()=>{if(n)throw new Error("DataStore is disposed.")},r=e=>{i();const n=t.get(e);if(!n)throw new Error(`Series ${e} has no data. Call setSeries(${e}, data) first.`);return n};return{setSeries:(n,r,o)=>{i();const a=(null==o?void 0:o.xOffset)??0,l=s(r),u=((e,t)=>{const n=s(e);if(0===n)return new Float32Array(0);const i=new ArrayBuffer(2*n*4),r=new Float32Array(i);return d(r,0,e,0,n,t),r})(r,a),c=v(u),f=h(u.byteLength),m=Math.max(4,f),p=t.get(n);if(p&&p.pointCount===l&&p.hash32===c)return;let b=(null==p?void 0:p.buffer)??null,y=(null==p?void 0:p.capacityBytes)??0;if(!b||m>y){const t=e.limits.maxBufferSize;if(m>t)throw new Error(`DataStore.setSeries(${n}): required buffer size ${m} exceeds device.limits.maxBufferSize (${t}).`);if(b)try{b.destroy()}catch{}const i=g(y,m);y=i>t?m:i,b=e.createBuffer({size:y,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST})}u.byteLength>0&&e.queue.writeBuffer(b,0,u.buffer,u.byteOffset,u.byteLength);const x=new Float32Array(y/4);x.set(u),t.set(n,{buffer:b,capacityBytes:y,pointCount:l,hash32:c,xOffset:a,stagingBuffer:x})},appendSeries:(n,o)=>{i();const a=s(o);if(0===a)return;const l=r(n),u=l.pointCount,c=u+a,f=h(2*c*4),m=Math.max(4,f);let p=l.buffer,y=l.capacityBytes,x=l.stagingBuffer;const w=e.limits.maxBufferSize;if(m>y){if(m>w)throw new Error(`DataStore.appendSeries(${n}): required buffer size ${m} exceeds device.limits.maxBufferSize (${w}).`);try{p.destroy()}catch{}const i=g(y,m);y=i>w?m:i,p=e.createBuffer({size:y,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});const r=new Float32Array(y/4);r.set(x.subarray(0,2*u)),d(r,2*u,o,0,a,l.xOffset);const s=r.subarray(0,2*c);return s.byteLength>0&&e.queue.writeBuffer(p,0,s.buffer,s.byteOffset,s.byteLength),void t.set(n,{buffer:p,capacityBytes:y,pointCount:c,hash32:v(s),xOffset:l.xOffset,stagingBuffer:r})}d(x,2*u,o,0,a,l.xOffset);const M=x.subarray(2*u,2*c);if(M.byteLength>0){const t=2*u*4;e.queue.writeBuffer(p,t,M.buffer,M.byteOffset,M.byteLength)}const F=new Uint32Array(M.buffer,M.byteOffset,M.byteLength/4),N=b(l.hash32,F);t.set(n,{buffer:p,capacityBytes:y,pointCount:c,hash32:N,xOffset:l.xOffset,stagingBuffer:x})},removeSeries:e=>{i();const n=t.get(e);if(n){try{n.buffer.destroy()}catch{}t.delete(e)}},getSeriesBuffer:e=>r(e).buffer,getSeriesPointCount:e=>r(e).pointCount,dispose:()=>{if(!n){n=!0;for(const e of t.values())try{e.buffer.destroy()}catch{}t.clear()}}}}(a);const rt=function(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,s=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),l=Ge(e,64,{label:"gridRenderer/vsUniforms"}),u=Ge(e,16,{label:"gridRenderer/fsUniforms"}),c=e.createBindGroup({layout:s,entries:[{binding:0,resource:{buffer:l}},{binding:1,resource:{buffer:u}}]}),d=Ue(e,{label:"gridRenderer/pipeline",bindGroupLayouts:[s],vertex:{code:Be,label:"grid.wgsl",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,format:"float32x2",offset:0}]}]},fragment:{code:Be,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:o}},a);let f=null,m=null,p=[];const h=()=>{if(n)throw new Error("GridRenderer is disposed.")};return{prepare:(t,n)=>{h();const i=null!=n&&"object"==typeof n&&("lineCount"in n||"color"in n||"append"in n),r=i?n:void 0,o=i?null==r?void 0:r.lineCount:n,a=(null==o?void 0:o.horizontal)??5,s=(null==o?void 0:o.vertical)??6,u=(null==r?void 0:r.color)??"rgba(255,255,255,0.15)",c=!0===(null==r?void 0:r.append);if(a<0||s<0)throw new Error("GridRenderer.prepare: line counts must be non-negative.");if(!(Number.isFinite(t.left)&&Number.isFinite(t.right)&&Number.isFinite(t.top)&&Number.isFinite(t.bottom)&&Number.isFinite(t.canvasWidth)&&Number.isFinite(t.canvasHeight)))throw new Error("GridRenderer.prepare: gridArea dimensions must be finite numbers.");if(t.canvasWidth<=0||t.canvasHeight<=0)throw new Error("GridRenderer.prepare: canvas dimensions must be positive.");if(0===a&&0===s)return void(c||(m=null,p=[]));const d=((e,t,n)=>{const{left:i,right:r,top:o,bottom:a,canvasWidth:s,canvasHeight:l}=e,u=Number.isFinite(e.devicePixelRatio)&&e.devicePixelRatio>0?e.devicePixelRatio:1,c=i*u,d=s-r*u,f=o*u,m=l-a*u,p=d-c,h=m-f,g=new Float32Array(2*(t+n)*2);let b=0;for(let e=0;e0&&p.length>0){v=m.byteLength;const e=new Float32Array(m.length+d.length);e.set(m,0),e.set(d,m.length),m=e,p=p.concat([{vertexOffsetBytes:v,vertexCount:g,rgba:b}])}else m=d,p=[{vertexOffsetBytes:0,vertexCount:g,rgba:b}];const y=m.byteLength,x=Math.max(4,y);if(!f||f.size{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})();ze(e,l,w)},render:t=>{if(h(),0!==p.length&&f){t.setPipeline(d),t.setBindGroup(0,c);for(const n of p){const i=new ArrayBuffer(16);new Float32Array(i).set([n.rgba[0],n.rgba[1],n.rgba[2],n.rgba[3]]),ze(e,u,i),t.setVertexBuffer(0,f,n.vertexOffsetBytes),t.draw(n.vertexCount)}}},dispose:()=>{if(!n){n=!0;try{l.destroy()}catch{}try{u.destroy()}catch{}if(f)try{f.destroy()}catch{}f=null,m=null,p=[]}}}}(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),ot=We(a,{targetFormat:m,pipelineCache:y}),at=We(a,{targetFormat:m,pipelineCache:y}),st=_t(a,{targetFormat:m,pipelineCache:y});st.setVisible(!1);const lt=function(e,t){let n=!1,i=!0;const r=(null==t?void 0:t.targetFormat)??"bgra8unorm",o=(null==t?void 0:t.sampleCount)??1,a=Number.isFinite(o)?Math.max(1,Math.floor(o)):1,s=null==t?void 0:t.pipelineCache,l=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}]}),u=Ge(e,48,{label:"highlightRenderer/uniforms"}),c=e.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:u}}]}),d=Ue(e,{label:"highlightRenderer/pipeline",bindGroupLayouts:[l],vertex:{code:Yt,label:"highlight.wgsl"},fragment:{code:Yt,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:a}},s);let f=0,m=0,p={x:0,y:0,w:0,h:0},h=!1;const g=()=>{if(n)throw new Error("HighlightRenderer is disposed.")};return{prepare:(t,n,i)=>{if(g(),!Number.isFinite(t.centerDeviceX)||!Number.isFinite(t.centerDeviceY))throw new Error("HighlightRenderer.prepare: point center must be finite.");if(!Number.isFinite(t.canvasWidth)||!Number.isFinite(t.canvasHeight)||t.canvasWidth<=0||t.canvasHeight<=0)throw new Error("HighlightRenderer.prepare: canvasWidth/canvasHeight must be positive finite numbers.");if(!(e=>Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&Number.isFinite(e.h))(t.scissor))throw new Error("HighlightRenderer.prepare: scissor must be finite.");if(!Number.isFinite(i)||i<0)throw new Error("HighlightRenderer.prepare: size must be a finite non-negative number.");const r=t.devicePixelRatio,o=i*(Number.isFinite(r)&&r>0?r:1),a=Math.max(1,1.5*o),s=Math.max(1,Math.round(Math.max(2,.25*a))),l=_(n)??Xt,c=(e=>{const t=Number.isFinite(1.25)?1.25:1;return[$t(e[0]*t),$t(e[1]*t),$t(e[2]*t),$t(e[3])]})(l),d=(e=>.2126*e[0]+.7152*e[1]+.0722*e[2])(l)>.7?[0,0,0,.9]:[1,1,1,.9],b=new ArrayBuffer(48);new Float32Array(b).set([t.centerDeviceX,t.centerDeviceY,a,s,c[0],c[1],c[2],1,d[0],d[1],d[2],d[3]]),ze(e,u,b),f=t.canvasWidth,m=t.canvasHeight;const v=Ht(Math.floor(t.scissor.x),0,Math.max(0,t.canvasWidth)),y=Ht(Math.floor(t.scissor.y),0,Math.max(0,t.canvasHeight)),x=Ht(Math.ceil(t.scissor.x+t.scissor.w),0,Math.max(0,t.canvasWidth)),w=Ht(Math.ceil(t.scissor.y+t.scissor.h),0,Math.max(0,t.canvasHeight));p={x:v,y,w:Math.max(0,x-v),h:Math.max(0,w-y)},h=!0},render:e=>{g(),i&&h&&(f<=0||m<=0||0===p.w||0===p.h||(e.setScissorRect(p.x,p.y,p.w,p.h),e.setPipeline(d),e.setBindGroup(0,c),e.draw(3),e.setScissorRect(0,0,f,m)))},setVisible:e=>{g(),i=!!e},dispose:()=>{if(!n){n=!0;try{u.destroy()}catch{}f=0,m=0,p={x:0,y:0,w:0,h:0},h=!1}}}}(a,{targetFormat:m,pipelineCache:y});lt.setVisible(!1);const ut=Zt(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),ct=en(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),ft=Zt(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),mt=en(a,{targetFormat:m,sampleCount:4,pipelineCache:y}),pt=function(e){const{device:t,targetFormat:n}=e,i={mainColorTexture:null,mainColorView:null,mainResolveTexture:null,mainResolveView:null,overlayMsaaTexture:null,overlayMsaaView:null,overlayBlitBindGroup:null,overlayTargetsWidth:0,overlayTargetsHeight:0,overlayTargetsFormat:null},r=t.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}}]}),o=Ue(t,{label:"textureManager/overlayBlitPipeline",bindGroupLayouts:[r],vertex:{code:Dt,label:"textureManager/overlayBlit.wgsl"},fragment:{code:Dt,label:"textureManager/overlayBlit.wgsl",formats:n},primitive:{topology:"triangle-list",cullMode:"none"},multisample:{count:4}},e.pipelineCache);let a=null;return{ensureTextures:function(e,o){const s=Number.isFinite(e)?Math.max(1,Math.floor(e)):1,l=Number.isFinite(o)?Math.max(1,Math.floor(o)):1;i.mainColorTexture&&i.mainResolveTexture&&i.overlayMsaaTexture&&i.overlayBlitBindGroup&&i.overlayTargetsWidth===s&&i.overlayTargetsHeight===l&&i.overlayTargetsFormat===n||(Ut(i.mainColorTexture),Ut(i.mainResolveTexture),Ut(i.overlayMsaaTexture),i.mainColorTexture=t.createTexture({label:"textureManager/mainColorTexture",size:{width:s,height:l},sampleCount:4,format:n,usage:GPUTextureUsage.RENDER_ATTACHMENT}),i.mainColorView=i.mainColorTexture.createView(),i.mainResolveTexture=t.createTexture({label:"textureManager/mainResolveTexture",size:{width:s,height:l},format:n,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),i.mainResolveView=i.mainResolveTexture.createView(),i.overlayMsaaTexture=t.createTexture({label:"textureManager/annotationOverlayMsaaTexture",size:{width:s,height:l},sampleCount:4,format:n,usage:GPUTextureUsage.RENDER_ATTACHMENT}),i.overlayMsaaView=i.overlayMsaaTexture.createView(),i.overlayBlitBindGroup=t.createBindGroup({label:"textureManager/overlayBlitBindGroup",layout:r,entries:[{binding:0,resource:i.mainResolveView}]}),i.overlayTargetsWidth=s,i.overlayTargetsHeight=l,i.overlayTargetsFormat=n,a=null)},getState:function(){return a||(a={mainColorView:i.mainColorView,mainResolveView:i.mainResolveView,overlayMsaaView:i.overlayMsaaView,overlayBlitBindGroup:i.overlayBlitBindGroup,overlayBlitPipeline:o,msaaSampleCount:4,mainSceneMsaaSampleCount:4}),a},dispose:function(){Ut(i.mainColorTexture),Ut(i.mainResolveTexture),Ut(i.overlayMsaaTexture),i.mainColorTexture=null,i.mainColorView=null,i.mainResolveTexture=null,i.mainResolveView=null,i.overlayMsaaTexture=null,i.overlayMsaaView=null,i.overlayBlitBindGroup=null,i.overlayTargetsWidth=0,i.overlayTargetsHeight=0,i.overlayTargetsFormat=null,a=null}}}({device:a,targetFormat:m,pipelineCache:y}),ht=ai(e,R),gt=Hn(e.canvas)?function(e,t){let n=!1,i=t;const r={mousemove:new Set,click:new Set,mouseleave:new Set};let o=null,a=null;const s=(t,n)=>{const o=(t=>{const n=e.getBoundingClientRect();if(0===n.width||0===n.height)return null;const r=t.clientX-n.left,o=t.clientY-n.top,a=i.left,s=i.top,l=n.width-i.left-i.right,u=n.height-i.top-i.bottom,c=r-a,d=o-s;return{x:r,y:o,gridX:c,gridY:d,plotWidthCss:l,plotHeightCss:u,isInGrid:c>=0&&c<=l&&d>=0&&d<=u,originalEvent:t}})(n);if(o)for(const e of r[t])e(o)},l=e=>{o&&e.isPrimary&&e.pointerId===o.pointerId&&(o=null)},u=e=>{n||s("mousemove",e)},c=e=>{n||(l(e),s("mouseleave",e))},d=e=>{n||(l(e),s("mouseleave",e))},f=e=>{if(!n){if(a===e.pointerId)return void(a=null);l(e),s("mouseleave",e)}},m=t=>{if(n||!t.isPrimary||"mouse"===t.pointerType&&0!==t.button)return;const i=e.getBoundingClientRect();if(0!==i.width&&0!==i.height){o={pointerId:t.pointerId,startClientX:t.clientX,startClientY:t.clientY,startTimeMs:t.timeStamp};try{e.setPointerCapture(t.pointerId)}catch{}}},p=t=>{if(n||!t.isPrimary||!o||t.pointerId!==o.pointerId)return;const i=t.timeStamp-o.startTimeMs,r=t.clientX-o.startClientX,l=t.clientY-o.startClientY,u=r*r+l*l;o=null;try{e.hasPointerCapture(t.pointerId)&&(a=t.pointerId,e.releasePointerCapture(t.pointerId))}catch{}i<=500&&u<=36&&s("click",t)};return e.addEventListener("pointermove",u,{passive:!0}),e.addEventListener("pointerleave",c,{passive:!0}),e.addEventListener("pointercancel",d,{passive:!0}),e.addEventListener("lostpointercapture",f,{passive:!0}),e.addEventListener("pointerdown",m,{passive:!0}),e.addEventListener("pointerup",p,{passive:!0}),{canvas:e,on:(e,t)=>{n||r[e].add(t)},off:(e,t)=>{r[e].delete(t)},updateGridArea:e=>{i=e},dispose:()=>{n||(n=!0,o=null,a=null,e.removeEventListener("pointermove",u),e.removeEventListener("pointerleave",c),e.removeEventListener("pointercancel",d),e.removeEventListener("lostpointercapture",f),e.removeEventListener("pointerdown",m),e.removeEventListener("pointerup",p),r.mousemove.clear(),r.click.clear(),r.mouseleave.clear())}}}(e.canvas,ht):null;let bt,vt={source:"mouse",x:0,y:0,gridX:0,gridY:0,isInGrid:!1,hasPointer:!1},yt=null;const xt=new Set;let Mt=null;const Ft=(e,t)=>{const n=null!==e&&Number.isFinite(e)?e:null;yt===n&&bt===t||(yt=n,bt=t,((e,t)=>{const n=Array.from(xt);for(const i of n)i(e,t)})(yt,bt))},Nt=()=>{var e;null==(e=null==n?void 0:n.onRequestRender)||e.call(n)},Ct=e=>!e||Number.isFinite(e.start)&&Number.isFinite(e.end)&&e.start<=0&&e.end>=100,St=()=>{null!==Fe&&(cancelAnimationFrame(Fe),Fe=null),null!==Te&&(clearTimeout(Te),Te=null),Me=!1},At=()=>{null!==De&&(clearTimeout(De),De=null)},kt=e=>{if(P)return;const t=(null==e?void 0:e.requestRenderAfter)??!0,n=(()=>{var e;if(0===Le.size)return!1;Ye.clear();const t=(null==jt?void 0:jt.getRange())??null,n=Ct(t),i=!0===R.autoScroll&&null!=jt&&null==R.xAxis.min&&null==R.xAxis.max,r=Mi(R,ge),o=t?Ni(r,t):null;let a=!1;for(const[e,t]of Le){if(0===t.length)continue;const i=R.series[e];if(i&&"pie"!==i.type){if(a=!0,"candlestick"===i.type){let n=he[e];if(!n){const t=i.rawData??i.data;n=0===t.length?[]:t.slice(),he[e]=n,ge[e]=i.rawBounds??null}for(const i of t){const t=i;n.push(...t),ge[e]=ii(ge[e],t)}}else{let r=he[e];if(!r){const t=i.rawData??i.data;r=ti(t),he[e]=r,ge[e]=i.rawBounds??f(t)}const o="line"===i.type&&"none"===i.sampling&&n&&"fullRawLine"===_e[e];for(const n of t){const t=n;if(o)try{it.appendSeries(e,t),Ye.add(e)}catch{}else"line"===i.type&&"none"!==i.sampling&&!fe.has(e)&&(fe.add(e),console.warn(`[ChartGPU] appendData() on series ${e} with sampling='${i.sampling}' causes full buffer re-upload every frame. For optimal streaming performance, use sampling='none'. See docs/internal/INCREMENTAL_APPEND_OPTIMIZATION.md for details.`));const a=s(t),d=r.x.length;for(let e=0;e=99.5){const t=e.end-e.start,n=jt;n.setRangeAnchored?n.setRangeAnchored(100-t,100,"end"):jt.setRange(100-t,100)}else{const e=Mi(R,ge),t=e.max-e.min;if(Number.isFinite(t)&&t>0){const n=(o.min-e.min)/t*100,i=(o.max-e.min)/t*100,r=Math.max(0,Math.min(100,n)),a=Math.max(0,Math.min(100,i));jt.setRange(r,a)}}}i&&(qt=void 0),fn();const d=(null==jt?void 0:jt.getRange())??null;return(null==d||Ct(d))&&(ve=be,xe()),!0})(),i=(null==jt?void 0:jt.getRange())??null,r=Ct(i),o=null!=i&&!r;let a=!1;ke?(ke=!1,At(),!i||r?(ve=be,xe()):pn(),a=!0):n&&o&&(ke=!1,At(),pn(),a=!0),(n||a)&&t&&Nt()},Gt=e=>{P||Me||(null!==Fe&&(cancelAnimationFrame(Fe),Fe=null),null!==Te&&(clearTimeout(Te),Te=null),Me=!0,Fe=requestAnimationFrame(()=>{Fe=null,P?St():(null!==Te&&(clearTimeout(Te),Te=null),Me=!1,kt())}),Te=(typeof self<"u"?self:window).setTimeout(()=>{P?St():Me&&(null!==Fe&&(cancelAnimationFrame(Fe),Fe=null),Me=!1,Te=null,kt())},16))},zt=(e,t)=>{let n,i;const r=e.getBoundingClientRect();if(!(r.width>0&&r.height>0))return null;n=r.width,i=r.height;const o=n-t.left-t.right,a=i-t.top-t.bottom;return o>0&&a>0?{plotWidthCss:o,plotHeightCss:a}:null},Vt=(e,t,n)=>{const i=R.series[e],{x:r,y:o}=(e=>ei(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y})(n);return{seriesName:(null==i?void 0:i.name)??"",seriesIndex:e,dataIndex:t,value:[r,o],color:(null==i?void 0:i.color)??"#888"}},Lt=(e,t,n)=>{const i=R.series[e];return pi(n)?{seriesName:(null==i?void 0:i.name)??"",seriesIndex:e,dataIndex:t,value:[n[0],n[1],n[2],n[3],n[4]],color:(null==i?void 0:i.color)??"#888"}:{seriesName:(null==i?void 0:i.name)??"",seriesIndex:e,dataIndex:t,value:[n.timestamp,n.open,n.close,n.low,n.high],color:(null==i?void 0:i.color)??"#888"}},Wt=(e,t,n,i,r)=>{const o=.5*Math.min(i,r);if(!(o>0))return null;for(let a=e.length-1;a>=0;a--){const s=e[a];if("pie"!==s.type||!1===s.visible)continue;const l=s,u=xn(t,n,{seriesIndex:a,series:l},gi(l.center,i,r),bi(l.radius,o));if(u)return u}return null},Ot=(e,t,n,i)=>{for(let r=e.length-1;r>=0;r--){const o=e[r];if("candlestick"!==o.type||!1===o.visible)continue;const a=o,s=mn(a,a.data,i.xScale,i.plotWidthCss),l=bn([a],t,n,i.xScale,i.yScale,s);if(l)return{params:Lt(r,l.dataIndex,l.point),match:{point:l.point},seriesIndex:r}}return null};gt&&(gt.on("mousemove",e=>{if(vt={source:"mouse",x:e.x,y:e.y,gridX:e.gridX,gridY:e.gridY,isInGrid:e.isInGrid,hasPointer:!0},e.isInGrid&&Mt){const t=Mt.xScale.invert(e.gridX);Ft(Number.isFinite(t)?t:null,"mouse")}else e.isInGrid||Ft(null,"mouse");st.setVisible(e.isInGrid),Nt()}),gt.on("mouseleave",e=>{"mouse"===vt.source&&(vt={...vt,isInGrid:!1,hasPointer:!1},st.setVisible(!1),Qe(),Ft(null,"mouse"),Nt())}));let qt,jt=null,Jt=null,Kt=null,Qt=null;const an=new Set,sn=e=>Math.min(100,Math.max(0,e)),ln=()=>{const e=(e=>{let t=null,n=null;const i=e.dataZoom??[];for(const e of i)if(e&&("inside"===e.type||"slider"===e.type)){if(Number.isFinite(e.minSpan)){const n=sn(e.minSpan);t=null==t?n:Math.max(t,n)}if(Number.isFinite(e.maxSpan)){const t=sn(e.maxSpan);n=null==n?t:Math.min(n,t)}}return{minSpan:t??void 0,maxSpan:n??void 0}})(R),t=(()=>{if("category"===R.xAxis.type)return null;let e=0;for(let t=0;t{var e;const t=(e=>{var t,n;const i=null==(t=e.dataZoom)?void 0:t.find(e=>"inside"===(null==e?void 0:e.type)),r=null==(n=e.dataZoom)?void 0:n.find(e=>"slider"===(null==e?void 0:e.type)),o=i??r;return o?{start:Number.isFinite(o.start)?o.start:0,end:Number.isFinite(o.end)?o.end:100,hasInside:!!i}:null})(R);if(!t)return null==Jt||Jt.dispose(),Jt=null,null==Kt||Kt(),Kt=null,jt=null,void(Qt=null);if(jt){const n=ln(),i=jt;null==(e=i.setSpanConstraints)||e.call(i,n.minSpan,n.maxSpan),(null==Qt||Qt.start!==t.start||Qt.end!==t.end)&&(jt.setRange(t.start,t.end),Qt={start:t.start,end:t.end})}else{const e=ln();jt=function(e,t,n){let i=0,r=100,o=null;const a=new Set;let s=(()=>{const e=Number.isFinite(null==n?void 0:n.minSpan)?n.minSpan:.5;return nn(Number.isFinite(e)?e:0,0,100)})(),l=(()=>{const e=Number.isFinite(null==n?void 0:n.maxSpan)?n.maxSpan:100;return nn(Number.isFinite(e)?e:100,0,100)})(),u=Math.min(s,l),c=Math.max(s,l);const d=(e,t,n)=>{if(n){if("string"==typeof n)switch(n){case"start":return{center:e,ratio:0};case"end":return{center:t,ratio:1};case"center":return{center:.5*(e+t),ratio:.5}}if(n&&Number.isFinite(n.center)&&Number.isFinite(n.ratio))return{center:n.center,ratio:n.ratio}}},f=(e,t,n)=>{if(!Number.isFinite(e)||!Number.isFinite(t))return;let s=e,l=t;if(s>l){const e=s;s=l,l=e}let d=l-s;if(!Number.isFinite(d)||d<0)return;const f=nn(d,u,c);if(f!==d&&(s=(null!=n&&n.anchor&&Number.isFinite(n.anchor.center)?nn(n.anchor.center,0,100):.5*(s+l))-(null!=n&&n.anchor&&Number.isFinite(n.anchor.ratio)?rn(n.anchor.ratio):.5)*f,l=s+f,d=f),d>100&&(s=0,l=100,d=100),s<0){const e=-s;s+=e,l+=e}if(l>100){const e=l-100;s-=e,l-=e}s=nn(s,0,100),l=nn(l,0,100),s=on(s),l=on(l),(s!==i||l!==r)&&(i=s,r=l,!1!==(null==n?void 0:n.emit)&&(()=>{const e={start:i,end:r};if(null!==o&&o.start===e.start&&o.end===e.end)return;o=(e=>({start:e.start,end:e.end}))(e);const t=Array.from(a);for(const e of t)e({start:i,end:r})})())};return f(e,t,{emit:!1}),{getRange:()=>({start:i,end:r}),setRange:(e,t)=>{f(e,t)},setRangeAnchored:(e,t,n)=>{f(e,t,{anchor:d(e,t,n)})},setSpanConstraints:(e,t)=>{const n="number"==typeof e&&Number.isFinite(e)?nn(e,0,100):s,o="number"==typeof t&&Number.isFinite(t)?nn(t,0,100):l;if(n===s&&o===l)return;s=n,l=o,u=Math.min(s,l),c=Math.max(s,l);const a=1e-6;f(i,r,{anchor:d(i,r,r>=100-a?"end":i<=0+a?"start":"center")})},zoomIn:(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||t<=1)return;const n=nn(e,0,100),o=r-i,a=0===o?.5:rn((n-i)/o),s=o/t,l=n-a*s;f(l,l+s,{anchor:{center:n,ratio:a}})},zoomOut:(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||t<=1)return;const n=nn(e,0,100),o=r-i,a=0===o?.5:rn((n-i)/o),s=o*t,l=n-a*s;f(l,l+s,{anchor:{center:n,ratio:a}})},pan:e=>{Number.isFinite(e)&&f(i+e,r+e)},onChange:e=>(a.add(e),()=>{a.delete(e)})}}(t.start,t.end,e),Qt={start:t.start,end:t.end},Kt=jt.onChange(e=>{Ve=!0,Nt(),P||(At(),ke=!1,De=(typeof self<"u"?self:window).setTimeout(()=>{De=null,!P&&(ke=!0,Gt())},100));const t=qt;((e,t)=>{const n=Array.from(an);for(const i of n)i(e,t)})({start:e.start,end:e.end},t),qt=void 0})}t.hasInside&>?Jt||(Jt=function(e,t){let n=!1,i=!1,r=null,o=!1,a=0;const s=typeof navigator<"u"&&navigator.maxTouchPoints>0,l=new Map;let u=0,c="";const d=()=>{u=0},f=()=>{o=!1,a=0},m=e=>{if(r=e,!i)return;const n=e.originalEvent;if(!e.isInGrid||!(e=>"mouse"===e.pointerType&&e.shiftKey&&!!(1&e.buttons))(n)&&!(e=>"mouse"===e.pointerType&&!!(4&e.buttons))(n))return void f();const s=e.plotWidthCss;if(!(s>0&&Number.isFinite(s)))return void f();if(!o)return o=!0,void(a=e.gridX);const l=e.gridX-a;if(a=e.gridX,!Number.isFinite(l)||0===l)return;const{start:u,end:c}=t.getRange(),d=c-u;if(!Number.isFinite(d)||0===d)return;const m=-l/s*d;!Number.isFinite(m)||0===m||t.pan(m)},p=e=>{r=null,f()},h=e=>{if(!i||n)return;const o=r;if(!o||!o.isInGrid)return;const a=o.plotWidthCss,s=o.plotHeightCss;if(!(a>0&&s>0))return;const l=((e,t)=>{const n=e.deltaY;if(!Number.isFinite(n)||0===n)return 0;switch(e.deltaMode){case WheelEvent.DOM_DELTA_PIXEL:return n;case WheelEvent.DOM_DELTA_LINE:return 16*n;case WheelEvent.DOM_DELTA_PAGE:return n*(Number.isFinite(t)&&t>0?t:800);default:return n}})(e,s),u=((e,t)=>{const n=e.deltaX;if(!Number.isFinite(n)||0===n)return 0;switch(e.deltaMode){case WheelEvent.DOM_DELTA_PIXEL:return n;case WheelEvent.DOM_DELTA_LINE:return 16*n;case WheelEvent.DOM_DELTA_PAGE:return n*(Number.isFinite(t)&&t>0?t:800);default:return n}})(e,a);if(Math.abs(u)>Math.abs(l)&&0!==u){const{start:n,end:i}=t.getRange(),r=i-n;if(!Number.isFinite(r)||0===r)return;const o=u/a*r;if(!Number.isFinite(o)||0===o)return;return e.preventDefault(),void t.pan(o)}if(0===l)return;const c=(e=>{const t=Math.abs(e);if(!Number.isFinite(t)||0===t)return 1;const n=Math.min(t,200);return Math.exp(.002*n)})(l);if(!(c>1))return;const{start:d,end:f}=t.getRange(),m=f-d;if(!Number.isFinite(m)||0===m)return;const p=tn(o.gridX/a,0,1),h=tn(d+p*m,0,100);e.preventDefault(),l<0?t.zoomIn(h,c):t.zoomOut(h,c)},g=t=>{!i||n||"touch"!==t.pointerType||(t.preventDefault(),!(r?r.isInGrid:((e,t)=>{const n=t.getBoundingClientRect();if(0===n.width||0===n.height)return!1;const i=e.clientX-n.left,r=e.clientY-n.top;return i>=0&&i<=n.width&&r>=0&&r<=n.height})(t,e.canvas)))||l.size>=2||(l.set(t.pointerId,{x:t.clientX,y:t.clientY}),e.canvas.setPointerCapture(t.pointerId),d())},b=o=>{if(!i||n||"touch"!==o.pointerType||!l.has(o.pointerId))return;const a=l.size;if(1===a){const e=l.get(o.pointerId);if(!e)return;const n=o.clientX-e.x;if(l.set(o.pointerId,{x:o.clientX,y:o.clientY}),!Number.isFinite(n)||0===n)return;const i=(null==r?void 0:r.plotWidthCss)??0;if(!(i>0))return;const{start:a,end:s}=t.getRange(),u=s-a;if(!Number.isFinite(u)||0===u)return;const c=-n/i*u;if(!Number.isFinite(c)||0===c)return;t.pan(c)}else if(2===a){l.set(o.pointerId,{x:o.clientX,y:o.clientY});const n=l.values(),i=n.next().value,a=n.next().value,s=Math.hypot(i.x-a.x,i.y-a.y),c=(i.x+a.x)/2;if(!Number.isFinite(s)||0===s)return;if(u>0&&Number.isFinite(u)){const n=u/s,i=e.canvas.getBoundingClientRect(),o=(null==r?void 0:r.plotWidthCss)??0;if(!(o>0)||0===i.width)return void(u=s);const a=r?r.x-r.gridX:0,l=c-i.left-a,d=tn(l/o,0,1),{start:f,end:m}=t.getRange(),p=m-f;if(!Number.isFinite(p)||0===p)return void(u=s);const h=tn(f+d*p,0,100);n>1?t.zoomOut(h,n):n>0&&n<1&&t.zoomIn(h,1/n)}u=s}},v=e=>{!i||n||"touch"===e.pointerType&&(l.delete(e.pointerId),d())},y=e=>{!i||n||"touch"===e.pointerType&&(l.delete(e.pointerId),d())},x=()=>{if(!n&&i){if(i=!1,e.off("mousemove",m),e.off("mouseleave",p),e.canvas.removeEventListener("wheel",h),s){const t=e.canvas;t.style.touchAction=c,t.removeEventListener("pointerdown",g),t.removeEventListener("pointermove",b),t.removeEventListener("pointerup",v),t.removeEventListener("pointercancel",y)}l.clear(),d(),r=null,f()}};return{enable:()=>{if(!n&&!i&&(i=!0,e.on("mousemove",m),e.on("mouseleave",p),e.canvas.addEventListener("wheel",h,{passive:!1}),s)){const t=e.canvas;c=t.style.touchAction,t.style.touchAction="none",t.addEventListener("pointerdown",g,{passive:!1}),t.addEventListener("pointermove",b,{passive:!1}),t.addEventListener("pointerup",v),t.addEventListener("pointercancel",y)}},disable:x,dispose:()=>{n||(x(),n=!0)}}}(gt,jt),Jt.enable()):(null==Jt||Jt.dispose(),Jt=null)},dn=()=>{const e=R.series.length;he=new Array(e).fill(null),ge=new Array(e).fill(null),Le.clear();for(let t=0;t{const e=new Array(R.series.length);for(let t=0;tn.samplingThreshold?C(i,n.samplingThreshold):i;e[t]={...n,rawData:i,rawBounds:r,data:o};continue}const i=he[t]??n.rawData??n.data,r=ge[t]??n.rawBounds??void 0,o=N(i,n.sampling,n.samplingThreshold);e[t]={...n,rawData:i,rawBounds:r,data:o}}be=e};function pn(){const e=(null==jt?void 0:jt.getRange())??null,t=Mi(R,ge),n=Ni(t,e),i=.1*(n.max-n.min),r=n.min-i,o=n.max+i,a=2e5,s=Math.max(.001,Math.min(1,n.spanFraction)),l=new Array(be.length);for(let t=0;t=100){l[t]=i;continue}if("candlestick"===i.type){const e=G(he[t]??i.rawData??i.data,r,o),u=i.sampling,c=i.samplingThreshold,d=Number.isFinite(c)?Math.max(1,0|c):1,f=Math.min(a,Math.max(2,32*d)),m=ui(Math.round(d/s),2,f),p="ohlc"===u&&e.length>m?C(e,m):e;we[t]={data:p,cachedRange:{min:r,max:o},timestamp:Date.now()};const h=G(p,n.min,n.max);l[t]={...i,data:h};continue}const u=U(he[t]??i.rawData??i.data,r,o),c=i.sampling,d=i.samplingThreshold,f=Number.isFinite(d)?Math.max(1,0|d):1,m=Math.min(a,Math.max(2,32*f)),p=N(u,c,ui(Math.round(f/s),2,m));we[t]={data:p,cachedRange:{min:r,max:o},timestamp:Date.now()};const h=U(p,n.min,n.max);l[t]={...i,data:h}}ve=l,xe()}dn(),fn(),cn(),pn(),we=new Array(R.series.length).fill(null);const hn=function(e){const{device:t,targetFormat:n,pipelineCache:i,sampleCount:r}=e,o=[],a=[],c=[],d=[],f=[],m=[],p=function(e,t){let n=!1;const i=(null==t?void 0:t.targetFormat)??"bgra8unorm",r=null==t?void 0:t.sampleCount,o=Number.isFinite(r)?Math.max(1,Math.floor(r)):1,a=null==t?void 0:t.pipelineCache,c=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),d=Ge(e,64,{label:"barRenderer/vsUniforms"});ze(e,d,(()=>{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})());const f=e.createBindGroup({layout:c,entries:[{binding:0,resource:{buffer:d}}]}),m=Ue(e,{label:"barRenderer/pipeline",bindGroupLayouts:[c],vertex:{code:Pt,label:"bar.wgsl",buffers:[{arrayStride:32,stepMode:"instance",attributes:[{shaderLocation:0,format:"float32x4",offset:0},{shaderLocation:1,format:"float32x4",offset:16}]}]},fragment:{code:Pt,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:o}},a);let p=null,h=0,g=new ArrayBuffer(0),b=new Float32Array(g);const v=[],y=()=>{if(n)throw new Error("BarRenderer is disposed.")},x=e=>{let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;for(let i=0;in&&(n=i))}}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0&&0<=n?0:Math.abs(t){if(y(),0===t.length)return void(h=0);const a=(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?{plotWidthCss:r,plotHeightCss:o}:null})(o);if(!a)return void(h=0);const c=(e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:a,devicePixelRatio:s}=e;return{left:t*s/o*2-1,right:(o-n*s)/o*2-1,top:1-i*s/a*2,bottom:1-(a-r*s)/a*2}})(o),d=c.right-c.left,f=a.plotWidthCss>0?d/a.plotWidthCss:0,m=new Map,w=new Array(t.length);let M=0;for(let e=0;e{v.length=0;for(let t=0;te-t);let t=Number.POSITIVE_INFINITY;for(let e=1;e0&&n0?t:1})(t),N=(e=>{let t,n,i;for(let r=0;r{if(Number.isFinite(t)&&t>0){const n=e.scale(0),i=e.scale(0+t),r=Math.abs(i-n);if(Number.isFinite(r)&&r>0)return r}const r=Math.abs(n.right-n.left);return r>0?r/Math.max(1,Math.floor(i)):0})(i,F,c,A),P=Math.max(0,I*(1-S)),R=M+Math.max(0,M-1)*C,E=R>0?P/R:0;let B=0;const T=N.barWidth;if("number"==typeof T)B=Math.max(0,T)*f,B=Math.min(B,E);else if("string"==typeof T){const e=(e=>{const t=e.trim().match(/^(\d+(?:\.\d+)?)%$/);if(!t)return null;const n=Number(t[1])/100;return Number.isFinite(n)?n:null})(T);B=null==e?0:E*Rt(e)}B>0||(B=E);const D=B*C,U=M*B+Math.max(0,M-1)*D;let k=((e,t,n)=>{const i=t.invert(n.bottom),r=t.invert(n.top),o=Math.min(i,r),a=Math.max(i,r);return Number.isFinite(o)&&Number.isFinite(a)?o<=0&&0<=a?0:o>0?o:a<0?a:x(e):x(e)})(t,r,c),G=r.scale(k);if(!Number.isFinite(G)){const e=x(t);if(k=e,G=r.scale(e),Number.isFinite(G)||(k=0,G=r.scale(0)),!Number.isFinite(G))return void(h=0)}let z=0;for(let e=0;e{if(e<=b.length)return;const t=Math.max(8,Bt(e));g=new ArrayBuffer(4*t),b=new Float32Array(g)})(8*z);const V=b;let L=0;const W=new Map;for(let e=0;e0&&Number.isFinite(s)?Math.round((s-c.left)/I):Number.isFinite(F)&&F>0?Math.round(t/F):Math.round(1e6*t);let o,a,l=i.get(e);l||(l={posSum:k,negSum:k},i.set(e,l)),n>=0?(o=l.posSum,a=o+n,l.posSum=a):(o=l.negSum,a=o+n,l.negSum=a);const u=r.scale(o),d=r.scale(a);if(!Number.isFinite(u)||!Number.isFinite(d))continue;b=u,v=d-u}else{const e=r.scale(n);if(!Number.isFinite(e))continue;v=e-G}V[L+0]=g,V[L+1]=b,V[L+2]=B,V[L+3]=v,V[L+4]=a,V[L+5]=d,V[L+6]=f,V[L+7]=m,L+=8}}h=L/8;const O=Math.max(4,32*h);if(!p||p.size0&&e.queue.writeBuffer(p,0,g,0,32*h)},render:e=>{y(),p&&0!==h&&(e.setPipeline(m),e.setBindGroup(0,f),e.setVertexBuffer(0,p),e.draw(6,h))},dispose:()=>{if(!n){if(n=!0,p)try{p.destroy()}catch{}p=null,h=0;try{d.destroy()}catch{}}}}}(t,{targetFormat:n,pipelineCache:i,sampleCount:r});let h=null;return{ensureAreaRendererCount:function(e){for(;o.length>e;){const e=o.pop();null==e||e.dispose()}for(;o.lengthe;){const e=a.pop();null==e||e.dispose()}for(;a.lengthe;){const e=c.pop();null==e||e.dispose()}for(;c.lengthe;){const e=d.pop();null==e||e.dispose()}for(;d.lengthe;){const e=f.pop();null==e||e.dispose()}for(;f.lengthe;){const e=m.pop();null==e||e.dispose()}for(;m.length{if(P)throw new Error("RenderCoordinator is disposed.")},vn=()=>{if(W)try{L.cancel(W)}catch{}W=null,O=1,$=null,Z()},yn=(e,t)=>e.min===t.min&&e.max===t.max,wn=e=>{var t;gn();const n=(null==jt?void 0:jt.getRange())??null,i=(()=>{if($&&W){try{L.update(performance.now())}catch{}return((e,t,n)=>{const i=di(e.from.xBaseDomain,e.to.xBaseDomain,t),r=Ni(i,n),o=di(e.from.yBaseDomain,e.to.yBaseDomain,t),a=Q(e.from.series,e.to.series,t,null);return{xBaseDomain:i,xVisibleDomain:{min:r.min,max:r.max},yBaseDomain:o,series:a}})($,O,n)}const e=Mi(R,ge),t=Ni(e,n),i=Fi(R,ge,ye);return{xBaseDomain:e,xVisibleDomain:{min:t.min,max:t.max},yBaseDomain:i,series:ve}})();vn();const r=((e,t)=>{if(e.length!==t.length)return!0;for(let n=0;nCi(e))(R.animation);if(!f)return;$={from:{xBaseDomain:i.xBaseDomain,xVisibleDomain:i.xVisibleDomain,yBaseDomain:i.yBaseDomain,series:i.series},to:{xBaseDomain:s,xVisibleDomain:{min:l.min,max:l.max},yBaseDomain:u,series:c}},Z();const m=f.delayMs+f.durationMs;O=0;const p=L.animate(0,1,m,e=>{const t=li(e);if(!(m>0))return 1;const n=t*m;if(n<=f.delayMs)return 0;if(!(f.durationMs>0))return 1;const i=(n-f.delayMs)/f.durationMs;return f.easing(i)},e=>{P||W!==p||(O=li(e),O<1&&Nt())},()=>{P||W!==p||(O=1,$=null,W=null,Z())});W=p,Nt()};return{setOptions:wn,appendData:(e,t)=>{if(gn(),!Number.isFinite(e)||e<0||e>=R.series.length||!t)return;const n=R.series[e];if("pie"===n.type)return void(te.has(e)||(te.add(e),console.warn(`RenderCoordinator.appendData(${e}, ...): pie series are not supported by streaming append.`)));if(0===("candlestick"===n.type?t.length:s(t)))return;const i=Le.get(e);i?i.push(t):Le.set(e,[t]),Gt()},getInteractionX:()=>yt,setInteractionX:(e,t)=>{gn();const n=null!==e&&Number.isFinite(e)?e:null;vt={...vt,source:null===n?"mouse":"sync"},Ft(n,t),null===n&&!1===vt.hasPointer&&(st.setVisible(!1),lt.setVisible(!1),Ke()),Nt()},onInteractionXChange:e=>(gn(),xt.add(e),()=>{xt.delete(e)}),getZoomRange:()=>(null==jt?void 0:jt.getRange())??null,setZoomRange:(e,t)=>{gn(),jt&&jt.setRange(e,t)},onZoomRangeChange:e=>(gn(),an.add(e),()=>{an.delete(e)}),render:()=>{var t,n,i;if(gn(),!e.canvasContext||!e.canvas)return;(Le.size>0||ke)&&(St(),kt({requestRenderAfter:!1})),Ve&&(Ve=!1,function(){const e=(null==jt?void 0:jt.getRange())??null,t=Mi(R,ge),n=Ni(t,e);if(null==e||Number.isFinite(e.start)&&Number.isFinite(e.end)&&e.start<=0&&e.end>=100)return ve=be,void xe();const i=new Array(be.length);for(let e=0;e=r.cachedRange.min&&n.max<=r.cachedRange.max?"candlestick"===t.type?i[e]={...t,data:G(r.data,n.min,n.max)}:i[e]={...t,data:U(r.data,n.min,n.max)}:"candlestick"===t.type?i[e]={...t,data:G(t.data,n.min,n.max)}:i[e]={...t,data:U(t.data,n.min,n.max)}}ve=i,xe()}());const r=R.series.some(e=>"pie"!==e.type),o=ve;if("done"!==B){const e=(e=>Ci(e))(R.animation),t=(()=>{for(let e=0;e"number"==typeof(null==e?void 0:e.value)&&Number.isFinite(e.value)&&e.value>0))return!0;break;case"line":case"area":case"bar":case"scatter":if(s(t.data)>0)return!0;break;case"candlestick":if(t.data.length>0)return!0;break;default:Qn(t)}}return!1})();if("pending"===B&&e&&t){const t=e.delayMs+e.durationMs,n=n=>{const i=li(n);if(!(t>0))return 1;const r=i*t;if(r<=e.delayMs)return 0;if(!(e.durationMs>0))return 1;const o=(r-e.delayMs)/e.durationMs;return e.easing(o)};T=0,B="running",z=D.animate(0,1,t,n,e=>{P||"running"!==B||(T=li(e),T<1&&Nt())},()=>{P||(B="done",T=1,z=null)})}D.update(performance.now())}null!==$&&W&&L.update(performance.now());const u=ai(e,R);null==gt||gt.updateGridArea(u);const c=(null==jt?void 0:jt.getRange())??null,d=$?li(O):1,f=$?di($.from.xBaseDomain,$.to.xBaseDomain,d):Mi(R,ge),m=$?di($.from.yBaseDomain,$.to.yBaseDomain,d):Fi(R,ge,ye),h=Ni(f,c),g=(e=>{const{left:t,right:n,top:i,bottom:r,canvasWidth:o,canvasHeight:a,devicePixelRatio:s}=e;return{left:t*s/o*2-1,right:(o-n*s)/o*2-1,top:1-i*s/a*2,bottom:1-(a-r*s)/a*2}})(u),b=(e=>{const{canvasWidth:t,canvasHeight:n,devicePixelRatio:i}=e,r=e.left*i,o=t-e.right*i,a=e.top*i,s=n-e.bottom*i,l=ui(Math.floor(r),0,Math.max(0,t)),u=ui(Math.floor(a),0,Math.max(0,n)),c=ui(Math.ceil(o),0,Math.max(0,t)),d=ui(Math.ceil(s),0,Math.max(0,n));return{x:l,y:u,w:Math.max(0,c-l),h:Math.max(0,d-u)}})(u),v=Mn().domain(h.min,h.max).range(g.left,g.right),y=Mn().domain(m.min,m.max).range(g.bottom,g.top),F=e.canvas,N=function(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}}(F),C=N.width,E=N.height,Z=C>0?fi(g.left,C):0,J=C>0?fi(g.right,C):0,K=E>0?mi(g.top,E):0,te=E>0?mi(g.bottom,E):0,fe=Math.max(0,J-Z),he=Math.max(0,te-K),Me=function(e){var t,n,i,r,o,a,s,l,u,c,d,f,m,p;const{annotations:h,xScale:g,yScale:b,plotBounds:v,canvasCssWidth:y,canvasCssHeight:x,theme:w,offsetX:M=0,offsetY:F=0}=e,{leftCss:N,topCss:C,widthCss:S,heightCss:A}=v,I=[],P=[],R=[],E=[],B=[];if(0===h.length||y<=0||x<=0||S<=0||A<=0)return{linesBelow:I,linesAbove:P,markersBelow:R,markersAbove:E,labels:B};for(let e=0;ev.leftCss+v.widthCss+j||Yv.topCss+v.heightCss+j)continue;const Z=_+((null==(f=null==O?void 0:O.offset)?void 0:f[0])??0),J=Y+((null==(m=null==O?void 0:O.offset)?void 0:m[1])??0),K=(null==O?void 0:O.text)??(null!=O&&O.template?Ie(O.template,$,O.decimals):O?(()=>{const e="lineX"===T.type?"x={x}":"lineY"===T.type?"y={y}":"point"===T.type?"({x}, {y})":"text"===T.type?T.text:"";return e.includes("{")?Ie(e,$,O.decimals):e})():"text"===T.type?T.text:""),Q="string"==typeof K?K.trim():"";if(0===Q.length)continue;const ee=Pe(null==O?void 0:O.anchor),te=(null==(p=T.style)?void 0:p.color)??w.textColor,ne=w.fontSize,ie=null==O?void 0:O.background,re=null!=(null==ie?void 0:ie.color)?Ae(ie.color,ie.opacity??1):void 0,oe=(()=>{const e=null==ie?void 0:ie.padding;return"number"==typeof e&&Number.isFinite(e)?[e,e,e,e]:Array.isArray(e)&&4===e.length&&e.every(e=>"number"==typeof e&&Number.isFinite(e))?[e[0],e[1],e[2],e[3]]:ie?[2,4,2,4]:void 0})(),ae="number"==typeof(null==ie?void 0:ie.borderRadius)&&Number.isFinite(ie.borderRadius)?ie.borderRadius:void 0,se={text:Q,x:M+Z,y:F+J,anchor:ee,color:te,fontSize:ne,...re?{background:{backgroundColor:re,...oe?{padding:oe}:{},...null!=ae?{borderRadius:ae}:{}}}:{}};B.push(se)}return{linesBelow:I,linesAbove:P,markersBelow:R,markersAbove:E,labels:B}}({annotations:r?R.annotations??[]:[],xScale:v,yScale:y,plotBounds:{leftCss:Z,rightCss:J,topCss:K,bottomCss:te,widthCss:fe,heightCss:he},canvasCssWidth:C,canvasCssHeight:E,theme:R.theme}),Fe=Me.linesBelow.length+Me.linesAbove.length>0?[...Me.linesBelow,...Me.linesAbove]:[],Be=Me.markersBelow.length+Me.markersAbove.length>0?[...Me.markersBelow,...Me.markersAbove]:[],Te=Me.linesBelow.length,De=Me.linesAbove.length,Ue=Me.markersBelow.length,Ge=Me.markersAbove.length,ze=function(e){return e?e.clientWidth:0}(e.canvas),We=Math.abs(h.max-h.min);let Oe=5,Xe=[];if("time"===R.xAxis.type){const e=(e=>{const{axisMin:t,axisMax:n,xScale:i,plotClipLeft:r,plotClipRight:o,canvasCssWidth:a,visibleRangeMs:s,measureCtx:l,measureCache:u,fontSize:c,fontFamily:d,tickFormatter:f}=e,m=Jn(t)??i.invert(r),p=Jn(n)??i.invert(o);if(!l||a<=0)return{tickCount:5,tickValues:wi(m,p,5)};l.font=`${c}px ${d}`,u&&u.size>2e3&&u.clear();const h=u?`${c}px ${d}@@`:null;for(let e=9;e>=1;e--){const t=wi(m,p,e);let n=Number.NEGATIVE_INFINITY,r=!0;for(let o=0;o{if(!h)return l.measureText(d).width;const e=h+d,t=u.get(e);if(null!=t)return t;const n=l.measureText(d).width;return u.set(e,n),n})(),p=i.scale(c),g=fi(p,a),b=1===e?"middle":0===o?"start":o===t.length-1?"end":"middle",v="start"===b?g+m:"end"===b?g:g+.5*m;if(("start"===b?g:"end"===b?g-m:g-.5*m){const i=e.canvas;if(!i)return null;const r=zt(i,t);return r?{xScale:Mn().domain(n.xDomain.min,n.xDomain.max).range(0,r.plotWidthCss),yScale:Mn().domain(n.yDomain.min,n.yDomain.max).range(r.plotHeightCss,0),plotWidthCss:r.plotWidthCss,plotHeightCss:r.plotHeightCss}:null})(u,{xDomain:{min:h.min,max:h.max},yDomain:m});Mt=$e;const Ze=$&&d<1?Q($.from.series,$.to.series,d,j):ve;if("mouse"===vt.source&&vt.hasPointer&&vt.isInGrid&&$e){const e=$e.xScale.invert(vt.gridX);Ft(Number.isFinite(e)?e:null,"mouse")}let Ke=vt;if("sync"===vt.source)if(null!==yt&&$e){const e=$e.xScale.scale(yt),t=.5*$e.plotHeightCss,n=Number.isFinite(e)&&Number.isFinite(t)&&e>=0&&e<=$e.plotWidthCss&&t>=0&&t<=$e.plotHeightCss;Ke={source:"sync",gridX:Number.isFinite(e)?e:0,gridY:Number.isFinite(t)?t:0,x:u.left+(Number.isFinite(e)?e:0),y:u.top+(Number.isFinite(t)?t:0),isInGrid:n,hasPointer:n}}else Ke={...vt,hasPointer:!1,isInGrid:!1};if(Ce({gridRenderer:rt,xAxisRenderer:ot,yAxisRenderer:at,crosshairRenderer:st,highlightRenderer:lt},{currentOptions:R,xScale:v,yScale:y,gridArea:u,xTickCount:Oe,hasCartesianSeries:r,effectivePointer:Ke,interactionScales:$e,seriesForRender:Ze,withAlpha:si}),Ke.hasPointer&&Ke.isInGrid&&!1!==(null==(t=R.tooltip)?void 0:t.show)){const t=e.canvas;if($e&&t&&Hn(t)){const e=null==(n=R.tooltip)?void 0:n.formatter,r=(null==(i=R.tooltip)?void 0:i.trigger)??"item",o=t.offsetLeft+Ke.x,a=t.offsetTop+Ke.y;if("sync"===Ke.source){const t=un(Ze,Ke.gridX,$e.xScale);if(0===t.length)Qe();else if("axis"===r){const n=t.map(e=>Vt(e.seriesIndex,e.dataIndex,e.point)),i=e?e(n):zn(n);!i||i===He&&o===qe&&a===je?i||Qe():(He=i,qe=o,je=a,Je(o,a,i))}else{const n=t[0],i=Vt(n.seriesIndex,n.dataIndex,n.point),r=e?e(i):Gn(i);!r||r===He&&o===qe&&a===je?r||Qe():(He=r,qe=o,je=a,Je(o,a,r))}}else if("axis"===r){const n=Wt(Ze,Ke.gridX,Ke.gridY,$e.plotWidthCss,$e.plotHeightCss);if(n){const t={seriesName:n.slice.name,seriesIndex:n.seriesIndex,dataIndex:n.dataIndex,value:[0,n.slice.value],color:n.slice.color},i=e?e([t]):Gn(t);!i||i===He&&o===qe&&a===je?i||Qe():(He=i,qe=o,je=a,Je(o,a,i))}else{const n=Ot(Ze,Ke.gridX,Ke.gridY,$e),i=un(Ze,Ke.gridX,$e.xScale);if(0===i.length)if(n){const i=[n.params],r=e?e(i):zn(i);if(r){const e=Si(n.match,$e.xScale,$e.yScale,u,t),i=(null==e?void 0:e.x)??o,s=(null==e?void 0:e.y)??a;(r!==He||i!==qe||s!==je)&&(He=r,qe=i,je=s,Je(i,s,r))}else Qe()}else Qe();else{const r=i.map(e=>Vt(e.seriesIndex,e.dataIndex,e.point));n&&r.push(n.params);const s=e?e(r):zn(r);if(s){let e=o,i=a;if(n){const r=Si(n.match,$e.xScale,$e.yScale,u,t);r&&(e=r.x,i=r.y)}(s!==He||e!==qe||i!==je)&&(He=s,qe=e,je=i,Je(e,i,s))}else Qe()}}}else{const n=Wt(Ze,Ke.gridX,Ke.gridY,$e.plotWidthCss,$e.plotHeightCss);if(n){const t={seriesName:n.slice.name,seriesIndex:n.seriesIndex,dataIndex:n.dataIndex,value:[0,n.slice.value],color:n.slice.color},i=e?e(t):Gn(t);!i||i===He&&o===qe&&a===je?i||Qe():(He=i,qe=o,je=a,Je(o,a,i))}else{const n=Ot(Ze,Ke.gridX,Ke.gridY,$e);if(n){const i=e?e(n.params):Gn(n.params);if(i){const e=Si(n.match,$e.xScale,$e.yScale,u,t),r=(null==e?void 0:e.x)??o,s=(null==e?void 0:e.y)??a;(i!==He||r!==qe||s!==je)&&(He=i,qe=r,je=s,Je(r,s,i,n.params))}else Qe();return}const i=Ne(Ze,Ke.gridX,Ke.gridY,$e.xScale,$e.yScale);if(i){const t=Vt(i.seriesIndex,i.dataIndex,i.point),n=e?e(t):Gn(t);!n||n===He&&o===qe&&a===je?n||Qe():(He=n,qe=o,je=a,Je(o,a,n))}else Qe()}}}else Qe()}else Qe();const et=$e??(F&&Hn(F)?zt(F,u):null),tt=et&&"number"==typeof et.plotWidthCss&&"number"==typeof et.plotHeightCss?.5*Math.min(et.plotWidthCss,et.plotHeightCss):0,nt=hn.getState(),dt=function(e,t){const{currentOptions:n,seriesForRender:i,xScale:r,yScale:o,gridArea:a,dataStore:u,appendedGpuThisFrame:c,gpuSeriesKindByIndex:d,zoomState:f,visibleXDomain:m,introPhase:h,introProgress01:g,withAlpha:b,maxRadiusCss:v}=t,y=n.yAxis.min??n.yAxis.min??0,x=[],w="running"===h?Re(g):1;for(let t=0;t{if("time"!==n.xAxis.type)return 0;const e=h.data,t=s(e);for(let n=0;n=100)&&"none"===h.sampling?d[t]="fullRawLine":d[t]="other",h.areaStyle){const n={type:"area",name:h.name,rawData:h.data,data:m,color:h.areaStyle.color,areaStyle:h.areaStyle,sampling:h.sampling,samplingThreshold:h.samplingThreshold,connectNulls:h.connectNulls};e.areaRenderers[t].prepare(n,n.data,r,o,y)}break}case"bar":x.push(h);break;case"scatter":if("density"===h.mode){const n=h.rawData??h.data,i=k(n,m.min,m.max);c.has(t)||u.setSeries(t,n);const s=u.getSeriesBuffer(t),l=u.getSeriesPointCount(t);e.scatterDensityRenderers[t].prepare(h,s,l,i.start,i.end,r,o,a,h.rawBounds),d[t]="other"}else{const n=w<1?{...h,color:b(h.color,w)}:h;e.scatterRenderers[t].prepare(n,h.data,r,o,a)}break;case"pie":if(w<1&&v>0){const n=ee(h.radius,v),i=Math.max(0,n.inner)*w,r=Math.max(i,n.outer)*w,o={...h,radius:[i,r]};e.pieRenderers[t].prepare(o,a);break}e.pieRenderers[t].prepare(h,a);break;case"candlestick":e.candlestickRenderers[t].prepare(h,h.data,r,o,a,n.theme.backgroundColor);break;default:throw new Error(`Unhandled series type: ${h.type}`)}}const M=i.map((e,t)=>({series:e,originalIndex:t})).filter(({series:e})=>!1!==e.visible),F=x.filter(e=>!1!==e.visible);return{visibleSeriesForRender:M,barSeriesConfigs:x,visibleBarSeriesConfigs:F}}(nt,{currentOptions:R,seriesForRender:Ze,xScale:v,yScale:y,gridArea:u,dataStore:it,appendedGpuThisFrame:Ye,gpuSeriesKindByIndex:_e,zoomState:jt,visibleXDomain:h,introPhase:B,introProgress01:T,withAlpha:si,maxRadiusCss:tt}),{visibleBarSeriesConfigs:ht}=dt,bt="running"===B?li(T):1,xt=bt<1?((e,t,n,i)=>{const r=li(i);if(r>=1)return e;const o=((e,t,n)=>{const i=t.invert(n.bottom),r=t.invert(n.top),o=Math.min(i,r),a=Math.max(i,r);return Number.isFinite(o)&&Number.isFinite(a)?o<=0&&0<=a?0:o>0?o:a<0?a:Ai(e):Ai(e)})(n,e,t),a=e.scale(o),s={domain:(t,n)=>(e.domain(t,n),s),range:(t,n)=>(e.range(t,n),s),scale(t){const n=e.scale(t);return Number.isFinite(n)&&Number.isFinite(a)?a+(n-a)*r:n},invert:t=>e.invert(t)};return s})(y,g,ht,bt):y;nt.barRenderer.prepare(ht,it,v,xt,u),r?(ut.prepare(u,Fe),ft.prepare(u,Fe),ct.prepare({canvasWidth:u.canvasWidth,canvasHeight:u.canvasHeight,devicePixelRatio:u.devicePixelRatio,instances:Be}),mt.prepare({canvasWidth:u.canvasWidth,canvasHeight:u.canvasHeight,devicePixelRatio:u.devicePixelRatio,instances:Be})):(ut.prepare(u,[]),ft.prepare(u,[]),ct.prepare({canvasWidth:u.canvasWidth,canvasHeight:u.canvasHeight,devicePixelRatio:u.devicePixelRatio,instances:[]}),mt.prepare({canvasWidth:u.canvasWidth,canvasHeight:u.canvasHeight,devicePixelRatio:u.devicePixelRatio,instances:[]})),pt.ensureTextures(u.canvasWidth,u.canvasHeight);const wt=pt.getState(),Ct=e.canvasContext.getCurrentTexture().createView(),At=a.createCommandEncoder({label:"renderCoordinator/commandEncoder"}),It=((e,t={r:0,g:0,b:0,a:1})=>{const n=_(e);if(!n)return t;const[i,r,o,a]=n;return{r:i,g:r,b:o,a}})(R.theme.backgroundColor,{r:0,g:0,b:0,a:1});!function(e,t,n){for(let i=0;i0&&s.h>0&&(c>0||d>0)&&(a.setScissorRect(s.x,s.y,s.w,s.h),c>0&&t.referenceLineRenderer.render(a,0,c),d>0&&t.annotationMarkerRenderer.render(a,0,d),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight));for(let t=0;t0&&s.h>0&&(a.setScissorRect(s.x,s.y,t,s.h),e.areaRenderers[i].render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight))}else a.setScissorRect(s.x,s.y,s.w,s.h),e.areaRenderers[i].render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight)}s.w>0&&s.h>0&&(a.setScissorRect(s.x,s.y,s.w,s.h),e.barRenderer.render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight));for(let t=0;t0&&s.h>0&&(a.setScissorRect(s.x,s.y,t,s.h),e.lineRenderers[i].render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight))}else a.setScissorRect(s.x,s.y,s.w,s.h),e.lineRenderers[i].render(a),a.setScissorRect(0,0,o.canvasWidth,o.canvasHeight)}}(nt,{referenceLineRenderer:ut,annotationMarkerRenderer:ct},{hasCartesianSeries:r,gridArea:u,mainPass:Pt,plotScissor:b,introPhase:B,introProgress01:T,referenceLineBelowCount:Te,markerBelowCount:Ue},dt),Pt.end();const Rt=At.beginRenderPass({label:"renderCoordinator/annotationOverlayMsaaPass",colorAttachments:[{view:wt.overlayMsaaView,resolveTarget:Ct,clearValue:It,loadOp:"clear",storeOp:"discard"}]});Rt.setPipeline(wt.overlayBlitPipeline),Rt.setBindGroup(0,wt.overlayBlitBindGroup),Rt.draw(3),function(e,t){const{hasCartesianSeries:n,gridArea:i,overlayPass:r,plotScissor:o,referenceLineBelowCount:a,referenceLineAboveCount:s,markerBelowCount:l,markerAboveCount:u}=t;if(n&&o.w>0&&o.h>0&&(s>0||u>0)){const t=a,n=l;r.setScissorRect(o.x,o.y,o.w,o.h),s>0&&e.referenceLineRendererMsaa.render(r,t,s),u>0&&e.annotationMarkerRendererMsaa.render(r,n,u),r.setScissorRect(0,0,i.canvasWidth,i.canvasHeight)}}({referenceLineRendererMsaa:ft,annotationMarkerRendererMsaa:mt},{hasCartesianSeries:r,gridArea:u,overlayPass:Rt,plotScissor:b,referenceLineBelowCount:Te,referenceLineAboveCount:De,markerBelowCount:Ue,markerAboveCount:Ge}),Rt.end();const Et=At.beginRenderPass({label:"renderCoordinator/topOverlayPass",colorAttachments:[{view:Ct,loadOp:"load",storeOp:"store"}]});lt.render(Et),r&&(ot.render(Et),at.render(Et)),st.render(Et),Et.end(),a.queue.submit([At.finish()]),V=!0,function(e,t,n){var i,r,o;const{gpuContext:a,currentOptions:s,xScale:l,yScale:u,xTickValues:c,plotClipRect:d,visibleXRangeMs:f}=n;if(!s.series.some(e=>"pie"!==e.type)||!e||!t)return;const m=a.canvas;if(!m)return;const p=function(e){return e?e.clientWidth:0}(m),h=function(e){return e?e.clientHeight:0}(m);if(p<=0||h<=0)return;const g=m.offsetLeft||0,b=m.offsetTop||0,v=oe(d.left,p),y=oe(d.right,p),x=ae(d.top,h),w=ae(d.bottom,h);e.clear();const M=w+(s.xAxis.tickLength??6)+4+.5*s.theme.fontSize,F="time"===s.xAxis.type,N=(()=>{if(F)return null;const e=Y(s.xAxis.min)??l.invert(d.left),t=Y(s.xAxis.max)??l.invert(d.right),n=c.length;return ie(1===n?0:(t-e)/(n-1))})(),C=s.xAxis.tickFormatter;for(let t=0;t0){const t=(v+y)/2,n=(M+.5*s.theme.fontSize+((null==(r=s.dataZoom)?void 0:r.some(e=>"slider"===(null==e?void 0:e.type)))?h-32:h))/2;se(e.addLabel(D,g+t,b+n,{fontSize:T,color:s.theme.textColor,anchor:"middle"}),!0,s.theme)}const U=(null==(o=s.yAxis.name)?void 0:o.trim())??"";if(U.length>0){const t=(x+w)/2,n=R-(0===E.length?0:E.reduce((e,t)=>Math.max(e,t.getBoundingClientRect().width),0))-4-.5*T;se(e.addLabel(U,g+n,b+t,{fontSize:T,color:s.theme.textColor,anchor:"middle",rotation:-90}),!0,s.theme)}}(w,x,{gpuContext:e,currentOptions:R,xScale:v,yScale:y,xTickValues:Xe,plotClipRect:g,visibleXRangeMs:We}),function(e,t,n){var i,r,o;const{currentOptions:a,xScale:s,yScale:l,canvasCssWidthForAnnotations:u,canvasCssHeightForAnnotations:c,plotLeftCss:d,plotTopCss:f,plotWidthCss:m,plotHeightCss:p,canvas:h}=n;if(!a.series.some(e=>"pie"!==e.type)||!e||!t)return;if(!h||u<=0||c<=0||m<=0||p<=0)return void e.clear();const g=le(h)?h.offsetLeft:0,b=le(h)?h.offsetTop:0;e.clear();const v=a.annotations??[];if(0!==v.length)for(let t=0;td+m+M||xf+p+M)continue;const F=y+((null==(i=null==h?void 0:h.offset)?void 0:i[0])??0),N=x+((null==(r=null==h?void 0:h.offset)?void 0:r[1])??0),C=(null==h?void 0:h.text)??(null!=h&&h.template?me(h.template,w,h.decimals):h?(()=>{const e="lineX"===n.type?"x={x}":"lineY"===n.type?"y={y}":"point"===n.type?"({x}, {y})":"text"===n.type?n.text:"";return e.includes("{")?me(e,w,h.decimals):e})():"text"===n.type?n.text:""),S="string"==typeof C?C.trim():"";if(0===S.length)continue;const A=pe(null==h?void 0:h.anchor),I=(null==(o=n.style)?void 0:o.color)??a.theme.textColor,P=a.theme.fontSize,R=null==h?void 0:h.background,E=null!=(null==R?void 0:R.color)?de(R.color,R.opacity??1):void 0,B=(()=>{const e=null==R?void 0:R.padding;return"number"==typeof e&&Number.isFinite(e)?[e,e,e,e]:Array.isArray(e)&&4===e.length&&e.every(e=>"number"==typeof e&&Number.isFinite(e))?[e[0],e[1],e[2],e[3]]:R?[2,4,2,4]:void 0})(),T="number"==typeof(null==R?void 0:R.borderRadius)&&Number.isFinite(R.borderRadius)?R.borderRadius:void 0,D={x:g+F,y:b+N,...E?{background:{backgroundColor:E,...B?{padding:B}:{},...null!=T?{borderRadius:T}:{}}}:{}},U=e.addLabel(S,D.x,D.y,{fontSize:P,color:I,anchor:A});if(D.background){if(U.style.backgroundColor=D.background.backgroundColor,U.style.display="inline-block",U.style.boxSizing="border-box",D.background.padding){const[e,t,n,i]=D.background.padding;U.style.padding=`${e}px ${t}px ${n}px ${i}px`}null!=D.background.borderRadius&&(U.style.borderRadius=`${D.background.borderRadius}px`)}}}(M,x,{currentOptions:R,xScale:v,yScale:y,canvasCssWidthForAnnotations:C,canvasCssHeightForAnnotations:E,plotLeftCss:Z,plotTopCss:K,plotWidthCss:fe,plotHeightCss:he,canvas:F})},dispose:()=>{if(!P){P=!0;try{z&&D.cancel(z),D.cancelAll()}catch{}z=null,B="done",T=1;try{W&&L.cancel(W),L.cancelAll()}catch{}W=null,O=1,$=null,St(),At(),ke=!1,Le.clear(),null==Jt||Jt.dispose(),Jt=null,null==Kt||Kt(),Kt=null,jt=null,Qt=null,an.clear(),null==gt||gt.dispose(),st.dispose(),lt.dispose(),hn.dispose(),rt.dispose(),ot.dispose(),at.dispose(),ut.dispose(),ct.dispose(),ft.dispose(),mt.dispose(),pt.dispose(),it.dispose(),null==Xe||Xe.dispose(),Xe=null,null==F||F.dispose(),null==w||w.dispose(),null==M||M.dispose()}}}}const Pi=["#5470C6","#91CC75","#FAC858","#EE6666","#73C0DE","#3BA272","#FC8452","#9A60B4","#EA7CCC"],Ri="#22c55e",Ei="#ef4444",Bi="#22c55e",Ti="#ef4444",Di=1,Ui=5,ki=6,Gi={grid:{left:60,right:20,top:40,bottom:40},xAxis:{type:"value"},yAxis:{type:"value",autoBounds:"visible"},autoScroll:!1,theme:"dark",palette:Pi,series:[]},zi={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:["#00E5FF","#FF2D95","#B026FF","#00F5A0","#FFD300","#FF6B00","#4D5BFF","#FF3D3D"],fontFamily:'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',fontSize:12},Vi={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:["#1F77B4","#FF7F0E","#2CA02C","#D62728","#9467BD","#8C564B","#E377C2","#17BECF"],fontFamily:'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"',fontSize:12};function Li(e){return"dark"===e?zi:Vi}const Wi=e=>{if(!Array.isArray(e))return;const t=[];for(const n of e){if(null===n||"object"!=typeof n||Array.isArray(n))continue;const e=n,i=e.type;if("inside"!==i&&"slider"!==i)continue;const r=e.xAxisIndex,o=e.start,a=e.end,s=e.minSpan,l=e.maxSpan,u="number"==typeof r&&Number.isFinite(r)?r:void 0,c="number"==typeof o&&Number.isFinite(o)?o:void 0,d="number"==typeof a&&Number.isFinite(a)?a:void 0,f="number"==typeof s&&Number.isFinite(s)?s:void 0,m="number"==typeof l&&Number.isFinite(l)?l:void 0;t.push({type:i,xAxisIndex:u,start:c,end:d,minSpan:f,maxSpan:m})}return t},Oi=e=>{if(!Array.isArray(e))return;const t=[],n=e=>"start"===e||"center"===e||"end"===e,i=e=>"circle"===e||"rect"===e||"triangle"===e,r=e=>{if("string"!=typeof e)return;const t=e.trim();return t.length>0?t:void 0},o=e=>"number"==typeof e&&Number.isFinite(e)?e:void 0,a=e=>{const t=o(e);if(null!=t)return Math.min(1,Math.max(0,t))},s=e=>{if(!Array.isArray(e))return;const t=e.filter(e=>"number"==typeof e&&Number.isFinite(e)).map(e=>e);return 0!==t.length?(Object.freeze(t),t):void 0},l=e=>{if("number"==typeof e&&Number.isFinite(e))return e;if(!Array.isArray(e)||4!==e.length)return;const t=o(e[0]),n=o(e[1]),i=o(e[2]),r=o(e[3]);return null!=t&&null!=n&&null!=i&&null!=r?[t,n,i,r]:void 0};for(const u of e){if(null===u||"object"!=typeof u||Array.isArray(u))continue;const e=u,c=e.type;if("lineX"!==c&&"lineY"!==c&&"point"!==c&&"text"!==c)continue;const d=r(e.id),f=e.layer,m="belowSeries"===f||"aboveSeries"===f?f:void 0,p=e.style,h=p&&"object"==typeof p&&!Array.isArray(p)?(()=>{const e=p,t=r(e.color),n=o(e.lineWidth),i=s(e.lineDash),l=a(e.opacity),u={...t?{color:t}:{},...null!=n?{lineWidth:n}:{},...i?{lineDash:i}:{},...null!=l?{opacity:l}:{}};return Object.keys(u).length>0?u:void 0})():void 0,g=e.label,b=g&&"object"==typeof g&&!Array.isArray(g)?(()=>{const e=g,t=r(e.text),i=r(e.template),s=e.decimals,u="number"==typeof s&&Number.isFinite(s)&&s>=0?Math.min(20,Math.floor(s)):void 0,c=e.offset,d=Array.isArray(c)&&2===c.length&&"number"==typeof c[0]&&Number.isFinite(c[0])&&"number"==typeof c[1]&&Number.isFinite(c[1])?[c[0],c[1]]:void 0,f=e.anchor,m=n(f)?f:void 0,p=e.background,h=p&&"object"==typeof p&&!Array.isArray(p)?(()=>{const e=p,t=r(e.color),n=a(e.opacity),i=l(e.padding),s=o(e.borderRadius),u={...t?{color:t}:{},...null!=n?{opacity:n}:{},...null!=i?{padding:i}:{},...null!=s?{borderRadius:s}:{}};return Object.keys(u).length>0?u:void 0})():void 0,b={...t?{text:t}:{},...i?{template:i}:{},...null!=u?{decimals:u}:{},...d?{offset:d}:{},...m?{anchor:m}:{},...h?{background:h}:{}};return Object.keys(b).length>0?b:void 0})():void 0;if("lineX"===c){const n=o(e.x);if(null==n)continue;const i={type:"lineX",x:n,...d?{id:d}:{},...m?{layer:m}:{},...h?{style:h}:{},...b?{label:b}:{}};t.push(i);continue}if("lineY"===c){const n=o(e.y);if(null==n)continue;const i={type:"lineY",y:n,...d?{id:d}:{},...m?{layer:m}:{},...h?{style:h}:{},...b?{label:b}:{}};t.push(i);continue}if("point"===c){const n=o(e.x),l=o(e.y);if(null==n||null==l)continue;const u=e.marker,c=u&&"object"==typeof u&&!Array.isArray(u)?(()=>{const e=u,t=e.symbol,n=i(t)?t:void 0,l=o(e.size),c=e.style,d=c&&"object"==typeof c&&!Array.isArray(c)?(()=>{const e=c,t=r(e.color),n=a(e.opacity),i=o(e.lineWidth),l=s(e.lineDash),u={...t?{color:t}:{},...null!=n?{opacity:n}:{},...null!=i?{lineWidth:i}:{},...l?{lineDash:l}:{}};return Object.keys(u).length>0?u:void 0})():void 0,f={...n?{symbol:n}:{},...null!=l?{size:l}:{},...d?{style:d}:{}};return Object.keys(f).length>0?f:void 0})():void 0,f={type:"point",x:n,y:l,...c?{marker:c}:{},...d?{id:d}:{},...m?{layer:m}:{},...h?{style:h}:{},...b?{label:b}:{}};t.push(f);continue}{const n=e.position,i=r(e.text);if(!i||!n||"object"!=typeof n||Array.isArray(n))continue;const a=n,s=a.space;if("data"!==s&&"plot"!==s)continue;const l=o(a.x),u=o(a.y);if(null==l||null==u)continue;const c={type:"text",position:{space:s,x:l,y:u},text:i,...d?{id:d}:{},...m?{layer:m}:{},...h?{style:h}:{},...b?{label:b}:{}};t.push(c);continue}}return 0!==t.length?(Object.freeze(t),t):void 0},_i=e=>Array.isArray(e)?e.filter(e=>"string"==typeof e).map(e=>e.trim()).filter(e=>e.length>0):[],Yi=e=>{if("string"!=typeof e)return;const t=e.trim();return t.length>0?t:void 0},Xi=e=>{if("number"!=typeof e||!Number.isFinite(e))return;const t=Math.floor(e);return t>0?t:void 0},$i=e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"global"===t||"visible"===t?t:void 0};let Hi=!1;function qi(e={}){var t,n,i,r;const o=(e=>{const t=Li("dark");if("string"==typeof e)return Li("light"===e.trim().toLowerCase()?"light":"dark");if(null===e||"object"!=typeof e||Array.isArray(e))return t;const n=e,i=e=>{const t=n[e];if("string"!=typeof t)return;const i=t.trim();return i.length>0?i:void 0},r=n.fontSize,o="number"==typeof r&&Number.isFinite(r)?r:void 0,a=_i(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:a.length>0?a:Array.from(t.colorPalette),fontFamily:i("fontFamily")??t.fontFamily,fontSize:o??t.fontSize}})(e.theme),a=e.autoScroll,s="boolean"==typeof a?a:Gi.autoScroll,l=e.animation,u=("boolean"==typeof l||null!==l&&"object"==typeof l&&!Array.isArray(l)?l:void 0)??!0,c=_i(e.palette),d=c.length>0?{...o,colorPalette:c}:o,p=_i(d.colorPalette),h=p.length>0?p:_i(Gi.palette??Pi).length>0?_i(Gi.palette??Pi):Array.from(Pi),g=h.length>0?h:["#000000"],b={...d,colorPalette:g.slice()},v={left:(null==(t=e.grid)?void 0:t.left)??Gi.grid.left,right:(null==(n=e.grid)?void 0:n.right)??Gi.grid.right,top:(null==(i=e.grid)?void 0:i.top)??Gi.grid.top,bottom:(null==(r=e.grid)?void 0:r.bottom)??Gi.grid.bottom},y=((e,t)=>{const n=!1!==(null==e?void 0:e.show),i=Yi(null==e?void 0:e.color)??t.gridLineColor,r="number"==typeof(null==e?void 0:e.opacity)&&Number.isFinite(e.opacity)?Math.min(1,Math.max(0,e.opacity)):1,o=(e,t)=>{if(1===t)return e;const n=_(e);return n?`rgba(${Math.round(255*n[0])}, ${Math.round(255*n[1])}, ${Math.round(255*n[2])}, ${n[3]*t})`:e},a=o(i,r),s=(e,t)=>{if(!1===e)return{show:!1,count:0,color:a};if(!0===e||void 0===e)return{show:n,count:t,color:a};const i=!1!==e.show&&n,s="number"==typeof e.count&&Number.isFinite(e.count)&&e.count>=0?Math.floor(e.count):t,l=Yi(e.color);return{show:i,count:s,color:null!=l?o(l,r):a}};return{show:n,color:a,opacity:r,horizontal:s(null==e?void 0:e.horizontal,Ui),vertical:s(null==e?void 0:e.vertical,ki)}})(e.gridLines,b),x=e.xAxis?{...Gi.xAxis,...e.xAxis,type:e.xAxis.type??Gi.xAxis.type,autoBounds:$i(e.xAxis.autoBounds)??Gi.xAxis.autoBounds}:{...Gi.xAxis},w=e.yAxis?{...Gi.yAxis,...e.yAxis,type:e.yAxis.type??Gi.yAxis.type,autoBounds:$i(e.yAxis.autoBounds)??Gi.yAxis.autoBounds}:{...Gi.yAxis},M=(e.series??[]).map((e,t)=>{var n,i,r,o,a,s,l,u,c,d;const p=Yi(e.color),h=b.colorPalette[t%b.colorPalette.length],g=p??h,v=!1!==e.visible,y=(e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"none"===t||"lttb"===t||"average"===t||"max"===t||"min"===t||"ohlc"===t?t:void 0})(e.sampling)??"lttb",x=Xi(e.samplingThreshold)??5e3;switch(e.type){case"area":{const t=Yi(null==(n=e.areaStyle)?void 0:n.color)??p??h,r={opacity:(null==(i=e.areaStyle)?void 0:i.opacity)??.25,color:t},o=f(e.data)??void 0,a=m(e.data)?e.data:N(e.data,y,x);return{...e,visible:v,rawData:e.data,data:a,color:t,areaStyle:r,sampling:y,samplingThreshold:x,rawBounds:o,connectNulls:e.connectNulls??!1}}case"line":{const t=Yi(null==(r=e.lineStyle)?void 0:r.color)??p??h,n={width:(null==(o=e.lineStyle)?void 0:o.width)??2,opacity:(null==(a=e.lineStyle)?void 0:a.opacity)??1,color:t},{areaStyle:i,...s}=e,l=f(e.data)??void 0,u=m(e.data)?e.data:N(e.data,y,x);return{...s,visible:v,rawData:e.data,data:u,color:t,lineStyle:n,...e.areaStyle?{areaStyle:{opacity:e.areaStyle.opacity??.25,color:Yi(e.areaStyle.color)??t}}:{},sampling:y,samplingThreshold:x,rawBounds:l,connectNulls:e.connectNulls??!1}}case"bar":{const t=f(e.data)??void 0;return{...e,visible:v,rawData:e.data,data:N(e.data,y,x),color:g,sampling:y,samplingThreshold:x,rawBounds:t}}case"scatter":{const t=f(e.data)??void 0,n=(e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"points"===t||"density"===t?t:void 0})(e.mode)??"points",i=(e=>{if("number"!=typeof e||!Number.isFinite(e))return;const t=Math.floor(e);return t>0?Math.max(1,t):void 0})(e.binSize)??2,r=(e=>{if("string"==typeof e){const t=e.trim().toLowerCase();return"viridis"===t||"plasma"===t||"inferno"===t?t:void 0}if(!Array.isArray(e))return;if(e.length>0&&e.every(e=>"string"==typeof e&&e.length>0&&e===e.trim())){const t=e;return Object.isFrozen(t)||Object.freeze(t),t}const t=e.filter(e=>"string"==typeof e).map(e=>e.trim()).filter(e=>e.length>0);return 0!==t.length?(Object.freeze(t),t):void 0})(e.densityColormap)??"viridis",o=(e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"linear"===t||"sqrt"===t||"log"===t?t:void 0})(e.densityNormalization)??"log";return{...e,visible:v,rawData:e.data,data:N(e.data,y,x),color:g,mode:n,binSize:i,densityColormap:r,densityNormalization:o,sampling:y,samplingThreshold:x,rawBounds:t}}case"pie":{const{sampling:n,samplingThreshold:i,...r}=e;return{...r,visible:v,color:g,data:(e.data??[]).map((e,n)=>{const i=Yi(null==e?void 0:e.color),r=b.colorPalette[(t+n)%b.colorPalette.length],o=!1!==(null==e?void 0:e.visible);return{...e,color:i??r,visible:o}})}}case"candlestick":{Hi||(console.warn("ChartGPU: Candlestick series rendering is not yet implemented. Series will be skipped."),Hi=!0);const t=(e=>{if("string"!=typeof e)return;const t=e.trim().toLowerCase();return"none"===t||"ohlc"===t?t:void 0})(e.sampling)??"ohlc",n=Xi(e.samplingThreshold)??5e3,i={upColor:Yi(null==(s=e.itemStyle)?void 0:s.upColor)??Ri,downColor:Yi(null==(l=e.itemStyle)?void 0:l.downColor)??Ei,upBorderColor:Yi(null==(u=e.itemStyle)?void 0:u.upBorderColor)??Bi,downBorderColor:Yi(null==(c=e.itemStyle)?void 0:c.downBorderColor)??Ti,borderWidth:"number"==typeof(null==(d=e.itemStyle)?void 0:d.borderWidth)&&Number.isFinite(e.itemStyle.borderWidth)?e.itemStyle.borderWidth:Di},r=(e=>{if(0===e.length)return;let t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY;if((e=>Array.isArray(e))(e[0])){const o=e;for(let e=0;en&&(n=s),cr&&(r=d)}}else{const o=e;for(let e=0;en&&(n=s),cr&&(r=d)}}return Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)?(t===n&&(n=t+1),i===r&&(r=i+1),{xMin:t,xMax:n,yMin:i,yMax:r}):void 0})(e.data),o="ohlc"===t&&e.data.length>n?C(e.data,n):e.data;return{...e,visible:v,rawData:e.data,data:o,color:g,style:e.style??"classic",itemStyle:i,barWidth:e.barWidth??"80%",barMinWidth:e.barMinWidth??1,barMaxWidth:e.barMaxWidth??50,sampling:t,samplingThreshold:n,rawBounds:r}}default:return(e=>{throw new Error(`Unhandled series type: ${(null==e?void 0:e.type)??"unknown"}`)})(e)}});return{grid:v,gridLines:y,xAxis:x,yAxis:w,autoScroll:s,dataZoom:Wi(e.dataZoom),annotations:Oi(e.annotations),animation:u,theme:b,palette:b.colorPalette,series:M,legend:e.legend}}function ji(e={}){const t={...qi(e),tooltip:e.tooltip};return(e=>{var t;return(null==(t=e.dataZoom)?void 0:t.some(e=>"slider"===(null==e?void 0:e.type)))??!1})(e)?{...t,grid:{...t.grid,bottom:t.grid.bottom+40}}:t}const Zi=(e,t,n)=>Math.min(n,Math.max(t,e));function Ji(e,t,n){const i=null==n?void 0:n.height,r=null==n?void 0:n.marginTop,o=(null==n?void 0:n.zIndex)??4,a=(null==n?void 0:n.showPreview)??!1,s=document.createElement("div");s.style.display="block",s.style.width="100%",s.style.height=`${i}px`,s.style.marginTop=`${r}px`,s.style.boxSizing="border-box",s.style.position="relative",s.style.zIndex=`${o}`,s.style.userSelect="none",s.style.touchAction="none";const l=document.createElement("div");l.style.position="relative",l.style.height="100%",l.style.width="100%",l.style.boxSizing="border-box",l.style.borderRadius="8px",l.style.borderStyle="solid",l.style.borderWidth="1px",l.style.overflow="hidden",s.appendChild(l);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=a?"block":"none",l.appendChild(u);const c=document.createElement("div");c.style.position="absolute",c.style.top="0",c.style.bottom="0",c.style.left="0%",c.style.width="100%",c.style.boxSizing="border-box",c.style.cursor="grab",l.appendChild(c);const d=document.createElement("div");d.style.position="absolute",d.style.left="0",d.style.top="0",d.style.bottom="0",d.style.width="10px",d.style.cursor="ew-resize",c.appendChild(d);const f=document.createElement("div");f.style.position="absolute",f.style.right="0",f.style.top="0",f.style.bottom="0",f.style.width="10px",f.style.cursor="ew-resize",c.appendChild(f);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",c.appendChild(m),e.appendChild(s);let p=!1,h=null;const g=e=>{const t=(e=>{let{start:t,end:n}=e;if(t>n){const e=t;t=n,n=e}return{start:Zi(t,0,100),end:Zi(n,0,100)}})(e),n=Zi(t.end-t.start,0,100);c.style.left=`${t.start}%`,c.style.width=`${n}%`},b=(e,n)=>{if(p||0!==e.button)return;e.preventDefault(),null==h||h(),h=null;const i=e.clientX,r=t.getRange(),o=e.currentTarget instanceof Element?e.currentTarget:c;((e,t)=>{try{e.setPointerCapture(t)}catch{}})(o,e.pointerId),"pan-window"===n&&(c.style.cursor="grabbing",m.style.cursor="grabbing");const a=o=>{if(p||o.pointerId!==e.pointerId)return;o.preventDefault();const a=(e=>{const t=(()=>{const e=l.getBoundingClientRect().width;return Number.isFinite(e)&&e>0?e:null})();if(null===t)return null;const n=e/t*100;return Number.isFinite(n)?n:null})(o.clientX-i);if(null!==a)switch(n){case"left-handle":{const e=Math.min(r.end,r.start+a),n=t;return void(n.setRangeAnchored?n.setRangeAnchored(e,r.end,"end"):t.setRange(e,r.end))}case"right-handle":{const e=Math.max(r.start,r.end+a),n=t;return void(n.setRangeAnchored?n.setRangeAnchored(r.start,e,"start"):t.setRange(r.start,e))}case"pan-window":return void t.setRange(r.start+a,r.end+a)}};let s=!1;const u=()=>{s||(s=!0,window.removeEventListener("pointermove",a),window.removeEventListener("pointerup",d),window.removeEventListener("pointercancel",d),"pan-window"===n&&(c.style.cursor="grab",m.style.cursor="grab"),((e,t)=>{try{e.releasePointerCapture(t)}catch{}})(o,e.pointerId),h===u&&(h=null))},d=t=>{t.pointerId===e.pointerId&&u()};h=u,window.addEventListener("pointermove",a,{passive:!1}),window.addEventListener("pointerup",d,{passive:!0}),window.addEventListener("pointercancel",d,{passive:!0})},v=e=>b(e,"left-handle"),y=e=>b(e,"right-handle"),x=e=>b(e,"pan-window");d.addEventListener("pointerdown",v,{passive:!1}),f.addEventListener("pointerdown",y,{passive:!1}),m.addEventListener("pointerdown",x,{passive:!1});const w=t.onChange(e=>{p||g(e)});return g(t.getRange()),{update:e=>{if(p)return;l.style.background=e.backgroundColor,l.style.borderColor=e.axisLineColor,u.style.background=e.gridLineColor,c.style.background=e.gridLineColor,c.style.border=`1px solid ${e.axisTickColor}`,c.style.borderRadius="8px",c.style.boxSizing="border-box";const t=`1px solid ${e.axisLineColor}`;d.style.background=e.axisTickColor,d.style.borderRight=t,f.style.background=e.axisTickColor,f.style.borderLeft=t,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(!p){p=!0,null==h||h(),h=null;try{w()}catch{}d.removeEventListener("pointerdown",v),f.removeEventListener("pointerdown",y),m.removeEventListener("pointerdown",x),s.remove()}}}}let Ki=null;const Qi=120,er=e=>Array.isArray(e),tr=e=>(e=>Array.isArray(e))(e)?{x:e[0],y:e[1]}:{x:e.x,y:e.y},nr=e=>{const t=s(e);if(0===t)return{x:[],y:[]};const n=new Array(t),i=new Array(t),r=[];let o=!1;for(let a=0;aer(e)?e[0]:e.timestamp,rr=e=>er(e)?e[2]:e.close,or=(e,t,n)=>Math.min(n,Math.max(t,e)),ar=(e,t)=>{let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(let a=0;ai&&(i=e.xMax),e.yMino&&(o=e.yMax);continue}}const u=s.rawBounds??null;if(u){const e=u;if(Number.isFinite(e.xMin)&&Number.isFinite(e.xMax)&&Number.isFinite(e.yMin)&&Number.isFinite(e.yMax)){e.xMini&&(i=e.xMax),e.yMino&&(o=e.yMax);continue}}if("candlestick"===s.type){const e=s.data;for(let t=0;ti&&(i=s),lo&&(o=u))}continue}const c=f(s.data);c&&(c.xMini&&(i=c.xMax),c.yMino&&(o=c.yMax))}return Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(o)?(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o}):{xMin:0,xMax:1,yMin:0,yMax:1}},sr=(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 e=n;n=i,i=e}return{min:n,max:i}},lr=(e,t)=>{if("number"==typeof e)return Number.isFinite(e)?e:null;if("string"!=typeof e)return null;const n=e.trim();if(0===n.length)return null;if(n.endsWith("%")){const e=Number.parseFloat(n.slice(0,-1));return Number.isFinite(e)?e/100*t:null}const i=Number.parseFloat(n);return Number.isFinite(i)?i:null},ur=(e,t,n)=>{const i=(null==e?void 0:e[0])??"50%",r=(null==e?void 0:e[1])??"50%",o=lr(i,t),a=lr(r,n);return{x:Number.isFinite(o)?o:.5*t,y:Number.isFinite(a)?a:.5*n}},cr=(e,t)=>{if(null==e)return{inner:0,outer:.7*t};if((e=>Array.isArray(e))(e)){const n=lr(e[0],t),i=lr(e[1],t),r=Math.max(0,Number.isFinite(n)?n:0),o=Math.max(r,Number.isFinite(i)?i:.7*t);return{inner:r,outer:Math.min(t,o)}}const n=lr(e,t),i=Math.max(0,Number.isFinite(n)?n:.7*t);return{inner:0,outer:Math.min(t,i)}},dr={create:async function(e,t,n){var r;if(n){if(typeof navigator>"u"||!navigator.gpu)throw new Error("ChartGPU: Shared device mode requires WebGPU globals (navigator.gpu) to be available.")}else{const e=await async function(){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}`)):t=e instanceof Error?`Failed to request WebGPU adapter: ${e.message}`:`Failed to request WebGPU adapter: ${String(e)}`,{supported:!1,reason:t}}})(),Ki)}();if(!e.supported){const t=e.reason||"Unknown reason";throw new Error(`ChartGPU: WebGPU is not available.\nReason: ${t}\nBrowser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.\nResources:\n - MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API\n - Browser compatibility: https://caniuse.com/webgpu\n - WebGPU specification: https://www.w3.org/TR/webgpu/\n - Check your system: https://webgpureport.org/`)}}if(null!=n&&n.pipelineCache&&n.pipelineCache.device!==n.device)throw new Error("ChartGPU: pipelineCache.device must match the GPUDevice in the creation context. Create the pipeline cache with the same device: createPipelineCache(device).");const o=document.createElement("canvas");o.style.display="block",o.style.width="100%",o.style.height="100%",e.appendChild(o);const a=!!n;let d,m=!1,p=t.renderMode??"auto",h=!1,g=!1,b=null,v=null,y=null,x=null,w=null,M=!1,F=null,N=null,C=null,S=t,A=ji(S),I=new Array(A.series.length).fill(null).map(()=>({x:[],y:[]})),P=new Array(A.series.length).fill(null),R=null;const E=()=>{I=new Array(A.series.length).fill(null).map(()=>({x:[],y:[]})),P=new Array(A.series.length).fill(null),R=null;for(let e=0;eR||(R=A.series.map((e,t)=>{if("pie"===e.type)return e;if("candlestick"===e.type)return{...e,data:I[t]??e.data};const n=I[t];return{...e,data:n}}),R);E();let T=ar(A.series,P),D=null;const U={click:new Set,mouseover:new Set,mouseout:new Set,crosshairMove:new Set,zoomRangeChange:new Set,deviceLost:new Set,dataAppend:new Set};let k=!1,G=null,z=null,V=null;const L=new Set;let W=null,O=null,_=!0;const Y=new Float64Array(Qi);let X=0,$=0,H=0,q=0,j=0,Z=0;const J=performance.now();let K=0,Q=0;const ee=new Set,te=()=>U.mouseover.size>0||U.mouseout.size>0,ne=()=>U.click.size>0,ie=()=>{null!==W&&(cancelAnimationFrame(W),W=null)},re=e=>{if(m||g||h)return;h=!0;const t=performance.now();try{if(Y[X]=t,X=(X+1)%Qi,$0&&(t-K>25?(q++,j++,Z=t):j=0),K=t),ye(!1),!v||null==b||!b.device)return;if(_){_=!1;try{v.render()}catch{_=!0}}Q=performance.now()-t;const n=we();for(const e of ee)try{e(n)}catch(e){console.error("Error in performance update callback:",e)}}finally{h=!1}},oe=()=>{m||(_=!0,"external"!==p&&null===W&&(W=requestAnimationFrame(()=>{W=null,!m&&re(!0)})))},ae=()=>{if(x)try{x()}finally{x=null}},se=()=>{if(w)try{w()}finally{w=null}},le=()=>{null==N||N.dispose(),N=null},ue=()=>{le(),null==F||F.remove(),F=null},ce=(e,t)=>{const n=e.end-e.start;return Number.isFinite(n)&&0!==n?or((t-e.start)/n,0,1):.5},de=()=>({getRange:()=>(null==v?void 0:v.getZoomRange())??{start:0,end:100},setRange:(e,t)=>{null==v||v.setZoomRange(e,t)},zoomIn:(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||t<=1)return;const n=null==v?void 0:v.getZoomRange();if(!n)return;const i=or(e,0,100),r=ce(n,i),o=(n.end-n.start)/t,a=i-r*o;null==v||v.setZoomRange(a,a+o)},zoomOut:(e,t)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||t<=1)return;const n=null==v?void 0:v.getZoomRange();if(!n)return;const i=or(e,0,100),r=ce(n,i),o=(n.end-n.start)*t,a=i-r*o;null==v||v.setZoomRange(a,a+o)},pan:e=>{if(!Number.isFinite(e))return;const t=null==v?void 0:v.getZoomRange();t&&(null==v||v.setZoomRange(t.start+e,t.end+e))},onChange:e=>(null==v?void 0:v.onZoomRangeChange(e))??(()=>{})}),fe=()=>{if(!(e=>{var t;return(null==(t=e.dataZoom)?void 0:t.some(e=>"slider"===(null==e?void 0:e.type)))??!1})(S))return void ue();if(!v||!v.getZoomRange())return;const t=(()=>{if(F)return F;try{"static"===window.getComputedStyle(e).position&&(e.style.position="relative")}catch{}const t=document.createElement("div");return t.style.position="absolute",t.style.left="0",t.style.right="0",t.style.bottom="0",t.style.height="40px",t.style.paddingTop="8px",t.style.boxSizing="border-box",t.style.pointerEvents="auto",t.style.zIndex="5",e.appendChild(t),F=t,t})();N||(N=Ji(t,de(),{height:32,marginTop:0})),N.update(A.theme)},me=()=>{null==C||C.dispose(),C=null},pe=()=>{(e=>{var t;return(null==(t=e.dataZoom)?void 0:t.some(e=>"inside"===(null==e?void 0:e.type)))??!1})(S)?v&&v.getZoomRange()&&(C?C.update(A.theme):C=function(e,t,n){let i=!1;const r=typeof navigator<"u"&&navigator.maxTouchPoints>0,o=document.createElement("button");o.setAttribute("data-chartgpu-zoom-reset",""),o.setAttribute("aria-label","Reset zoom"),o.type="button",o.style.position="absolute",o.style.top="8px",o.style.right="8px",o.style.zIndex="10",o.style.width="32px",o.style.height="32px",o.style.border="none",o.style.borderRadius="6px",o.style.cursor="pointer",o.style.display="none",o.style.alignItems="center",o.style.justifyContent="center",o.style.fontSize="16px",o.style.lineHeight="1",o.style.padding="0",o.style.touchAction="manipulation",o.textContent="↺";const a=e=>{o.style.backgroundColor=e.backgroundColor,o.style.opacity="0.8",o.style.color=e.textColor};a(n);const s=()=>{if(!r)return void(o.style.display="none");const{start:e,end:n}=t.getRange();o.style.display=((e,t)=>e<=.01&&t>=99.99)(e,n)?"none":"flex"};s();const l=()=>{i||t.setRange(0,100)};o.addEventListener("click",l);const u=t.onChange(()=>{i||s()});return e.appendChild(o),{update(e){i||a(e)},dispose(){if(!i){i=!0,o.removeEventListener("click",l);try{u()}catch{}o.remove()}}}}(e,de(),A.theme)):me()},he={x:null,source:void 0},ge={start:0,end:100,source:void 0,sourceKind:void 0},be={seriesIndex:0,count:0,xExtent:{min:0,max:0}},ve=()=>{if(m||!b||!b.initialized)return;const e=(null==v?void 0:v.getZoomRange())??null;ae(),se(),le(),me(),null==v||v.dispose(),M=!1,d=void 0;const t={onRequestRender:oe,pipelineCache:null==n?void 0:n.pipelineCache};v=Ii(b,A,t),y=b.preferredFormat,ae(),!m&&v&&(x=v.onInteractionXChange((e,t)=>{he.x=e,he.source=t,Fe("crosshairMove",he)})),se(),!m&&v&&(w=v.onZoomRangeChange((e,t)=>{const n=M,i=d;M=!1,d=void 0;const r=void 0!==i?i:void 0,o=t??(n?"api":void 0);ge.start=e.start,ge.end=e.end,ge.source=r,ge.sourceKind=o,Fe("zoomRangeChange",ge)})),e&&v.setZoomRange(e.start,e.end),fe(),pe()},ye=e=>{var t;if(m)return;const n=o.getBoundingClientRect(),i=window.devicePixelRatio||1,r=(null==(t=null==b?void 0:b.device)?void 0:t.limits.maxTextureDimension2D)??8192,a=Math.min(r,Math.max(1,Math.round(n.width*i))),s=Math.min(r,Math.max(1,Math.round(n.height*i))),l=o.width!==a||o.height!==s;l&&(o.width=a,o.height=s);const u=null==b?void 0:b.device,c=null==b?void 0:b.canvasContext,d=null==b?void 0:b.preferredFormat;let f=!1;u&&c&&d&&(l||!O||O.width!==o.width||O.height!==o.height||O.format!==d)&&(c.configure({device:u,format:d,alphaMode:"opaque"}),O={width:o.width,height:o.height,format:d},f=!0,v&&y!==d&&ve()),e&&(l||f)&&oe()},xe=e=>{const t=o.getBoundingClientRect();if(!(t.width>0&&t.height>0))return{match:null,isInGrid:!1};const n=e.clientX-t.left,i=e.clientY-t.top,r=A.grid.left,a=A.grid.top,s=t.width-A.grid.left-A.grid.right,l=t.height-A.grid.top-A.grid.bottom;if(!(s>0&&l>0))return{match:null,isInGrid:!1};const u=n-r,c=i-a;if(!(u>=0&&u<=s&&c>=0&&c<=l))return{match:null,isInGrid:!1};const d=A.xAxis.min??T.xMin,f=A.xAxis.max??T.xMax,m=A.yAxis.min??T.yMin,p=A.yAxis.max??T.yMax,h=sr(d,f),g=(null==v?void 0:v.getZoomRange())??null,b=(()=>{if(!g)return h;const e=h.max-h.min;if(!Number.isFinite(e)||0===e)return h;const t=g.start,n=g.end,i=h.min+t/100*e,r=h.min+n/100*e;return sr(i,r)})(),y=sr(m,p);if(null===D||D.rectWidthCss!==t.width||D.rectHeightCss!==t.height||D.plotWidthCss!==s||D.plotHeightCss!==l||D.xDomainMin!==b.min||D.xDomainMax!==b.max||D.yDomainMin!==y.min||D.yDomainMax!==y.max){const e=Mn().domain(b.min,b.max).range(0,s),n=Mn().domain(y.min,y.max).range(l,0);D={rectWidthCss:t.width,rectHeightCss:t.height,plotWidthCss:s,plotHeightCss:l,xDomainMin:b.min,xDomainMax:b.max,yDomainMin:y.min,yDomainMax:y.max,xScale:e,yScale:n}}const x=D,w=(()=>{const e=.5*Math.min(s,l);if(!(e>0))return null;for(let t=A.series.length-1;t>=0;t--){const n=A.series[t];if("pie"!==n.type||!1===n.visible)continue;const i=n,r=ur(i.center,s,l),o=cr(i.radius,e),a=xn(u,c,{seriesIndex:t,series:i},r,o);if(!a)continue;const d=a.slice.value;return{kind:"pie",seriesIndex:a.seriesIndex,dataIndex:a.dataIndex,sliceValue:"number"==typeof d&&Number.isFinite(d)?d:0}}return null})();if(w)return{match:w,isInGrid:!0};for(let e=A.series.length-1;e>=0;e--){const t=A.series[e];if("candlestick"!==(null==t?void 0:t.type)||!1===t.visible)continue;const n=t,i=mn(n,n.data,x.xScale,s),r=bn([n],u,c,x.xScale,x.yScale,i);if(r)return{match:{kind:"candlestick",seriesIndex:e,dataIndex:r.dataIndex,point:r.point},isInGrid:!0}}const M=Ne(B(),u,c,x.xScale,x.yScale);return{match:M?{kind:"cartesian",match:M}:null,isInGrid:!0}},we=()=>{const e=(()=>{if($<2)return 0;const e=(X-$+Qi)%Qi;let t=0;for(let n=1;n<$;n++){const i=(e+n-1)%Qi;t+=Y[(e+n)%Qi]-Y[i]}const n=t/($-1);return n>0?1e3/n:0})(),t=(()=>{if($<2)return{min:0,max:0,avg:0,p50:0,p95:0,p99:0};const e=(X-$+Qi)%Qi,t=new Array($-1);let n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=0;for(let o=1;o<$;o++){const a=(e+o-1)%Qi,s=Y[(e+o)%Qi]-Y[a];t[o-1]=s,si&&(i=s),r+=s}const o=r/t.length;t.sort((e,t)=>e-t);const a=Math.floor(.5*t.length),s=Math.floor(.95*t.length),l=Math.floor(.99*t.length);return{min:n,max:i,avg:o,p50:t[a],p95:t[s],p99:t[l]}})(),n={enabled:!1,cpuTime:Q,gpuTime:0},i="external"===p?{totalDrops:0,consecutiveDrops:0,lastDropTimestamp:0}:{totalDrops:q,consecutiveDrops:j,lastDropTimestamp:Z},r=performance.now()-J;return{fps:e,frameTimeStats:t,gpuTiming:n,memory:{used:0,peak:0,allocated:0},frameDrops:i,totalFrames:H,elapsedTime:r}},Me=(e,t)=>{if(!e)return{seriesIndex:null,dataIndex:null,value:null,seriesName:null,event:t};const n="cartesian"===e.kind?e.match.seriesIndex:e.seriesIndex,i="cartesian"===e.kind?e.match.dataIndex:e.dataIndex,r=A.series[n],o=(null==r?void 0:r.name)??null,a=o&&o.trim().length>0?o:null;if("pie"===e.kind)return{seriesIndex:n,dataIndex:i,value:[0,e.sliceValue],seriesName:a,event:t};if("candlestick"===e.kind)return{seriesIndex:n,dataIndex:i,value:[ir(e.point),rr(e.point)],seriesName:a,event:t};const{x:s,y:l}=tr(e.match.point);return{seriesIndex:n,dataIndex:i,value:[s,l],seriesName:a,event:t}},Fe=(e,t)=>{if(!m)for(const n of U[e])n(t)},Ce=(e,t)=>{const n=V;if(V=e,null===n&&null===e)return;if(null===n&&null!==e)return void Fe("mouseover",Me(e,t));if(null!==n&&null===e)return void Fe("mouseout",Me(n,t));if(null===n||null===e)return;const i="cartesian"===n.kind?n.match.seriesIndex:n.seriesIndex,r="cartesian"===n.kind?n.match.dataIndex:n.dataIndex,o="cartesian"===e.kind?e.match.seriesIndex:e.seriesIndex,a="cartesian"===e.kind?e.match.dataIndex:e.dataIndex;i===o&&r===a||(Fe("mouseout",Me(n,t)),Fe("mouseover",Me(e,t)))},Se=e=>{G&&e.isPrimary&&e.pointerId===G.pointerId&&(G=null)},Ae=e=>{if(m||!te())return;const{match:t,isInGrid:n}=xe(e);Ce(n?t:null,e)},Ie=e=>{m||!te()&&!G||(Se(e),Ce(null,e))},Pe=e=>{m||!te()&&!G||(Se(e),Ce(null,e))},Re=e=>{if(!m&&(te()||G||z===e.pointerId)){if(z===e.pointerId)return void(z=null);Se(e),Ce(null,e)}},Ee=e=>{if(!m&&ne()&&e.isPrimary&&("mouse"!==e.pointerType||0===e.button)){G={pointerId:e.pointerId,startClientX:e.clientX,startClientY:e.clientY,startTimeMs:e.timeStamp};try{o.setPointerCapture(e.pointerId)}catch{}}},Be=e=>{if(m||!ne()||!e.isPrimary||!G||e.pointerId!==G.pointerId)return;const t=e.timeStamp-G.startTimeMs,n=e.clientX-G.startClientX,i=e.clientY-G.startClientY,r=n*n+i*i;G=null;try{o.hasPointerCapture(e.pointerId)&&(z=e.pointerId,o.releasePointerCapture(e.pointerId))}catch{}if(!(t<=500&&r<=36))return;const{match:a}=xe(e);Fe("click",Me(a,e))};o.addEventListener("pointermove",Ae,{passive:!0}),o.addEventListener("pointerleave",Ie,{passive:!0}),o.addEventListener("pointercancel",Pe,{passive:!0}),o.addEventListener("lostpointercapture",Re,{passive:!0}),o.addEventListener("pointerdown",Ee,{passive:!0}),o.addEventListener("pointerup",Be,{passive:!0});const Te=()=>{if(!m){m=!0;try{ie(),ue(),me(),ae(),se(),null==v||v.dispose(),v=null,y=null,null==b||b.destroy()}finally{G=null,z=null,V=null,D=null,M=!1,d=void 0,o.removeEventListener("pointermove",Ae),o.removeEventListener("pointerleave",Ie),o.removeEventListener("pointercancel",Pe),o.removeEventListener("lostpointercapture",Re),o.removeEventListener("pointerdown",Ee),o.removeEventListener("pointerup",Be),U.click.clear(),U.mouseover.clear(),U.mouseout.clear(),U.crosshairMove.clear(),U.zoomRangeChange.clear(),U.deviceLost.clear(),U.dataAppend.clear(),k=!1,b=null,o.remove()}}},De={get options(){return S},get disposed(){return m},setOption(e){m||(S=e,A=ji(e),null==v||v.setOptions(A),E(),T=ar(A.series,P),D=null,fe(),pe(),oe())},appendData(e,t){if(m||!Number.isFinite(e)||e<0||e>=A.series.length)return;const n=A.series[e];if("pie"===n.type)return void(L.has(e)||(L.add(e),console.warn(`ChartGPU.appendData(${e}, ...): pie series are not supported by streaming append. Use setOption(...) to replace pie data.`)));let i=0;if("candlestick"===n.type){if(!Array.isArray(t))return;i=t.length}else i=s(t);if(0===i)return;null==v||v.appendData(e,t);let r=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;if("candlestick"===n.type){const n=I[e],a=Array.isArray(n)?n:[],s=t;if(k)for(let e=0;eo&&(o=t))}a.push(...s),I[e]=a,P[e]=((e,t)=>{if(0===t.length)return e;let n=(null==e?void 0:e.xMin)??Number.POSITIVE_INFINITY,i=(null==e?void 0:e.xMax)??Number.NEGATIVE_INFINITY,r=(null==e?void 0:e.yMin)??Number.POSITIVE_INFINITY,o=(null==e?void 0:e.yMax)??Number.NEGATIVE_INFINITY;for(let e=0;ei&&(i=s),lo&&(o=u))}return Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(r)&&Number.isFinite(o)?(n===i&&(i=n+1),r===o&&(o=r+1),{xMin:n,xMax:i,yMin:r,yMax:o}):e})(P[e],s)}else{const n=I[e],a=t,d="object"==typeof a&&null!==a&&!Array.isArray(a)&&"x"in a&&"y"in a,m="object"==typeof a&&null!==a&&!Array.isArray(a)&&ArrayBuffer.isView(a);let p=!1;const h=new Array(i);if(d){const e=a;for(let t=0;to&&(o=i))}if(e.size){p=!0;for(let t=0;to&&(o=i))}}else for(let e=0;eo&&(o=t))}(n.size||p)&&(n.size||(n.size=new Array(n.x.length-i)),n.size.push(...h)),P[e]=((e,t)=>{const n=s(t);if(0===n)return e;let i=e;if(!i)return f(t);let r=i.xMin,o=i.xMax,a=i.yMin,c=i.yMax;const d="object"==typeof t&&null!==t&&!Array.isArray(t)&&"x"in t&&"y"in t,m="object"==typeof t&&null!==t&&!Array.isArray(t)&&ArrayBuffer.isView(t);if(d){const e=t;for(let t=0;to&&(o=n),ic&&(c=i))}}else if(m){const e=t;for(let t=0;to&&(o=n),ic&&(c=i))}}else for(let e=0;eo&&(o=n),ic&&(c=i))}return r===o&&(o=r+1),a===c&&(c=a+1),{xMin:r,xMax:o,yMin:a,yMax:c}})(P[e],a)}T=ar(A.series,P),R=null,D=null,oe(),k&&((!Number.isFinite(r)||!Number.isFinite(o))&&(r=0,o=0),be.seriesIndex=e,be.count=i,be.xExtent.min=r,be.xExtent.max=o,Fe("dataAppend",be))},renderFrame(){if(m||g)return!1;if("auto"===p)return console.warn('renderFrame() called in auto mode - this is a no-op. Set renderMode to "external" to use manual rendering.'),!1;if(h||!v||null==b||!b.device||!_)return!1;try{return re(!1),!0}catch{return!1}},needsRender:()=>!m&&_,getRenderMode:()=>p,setRenderMode(e){if(!m){if("auto"!==e&&"external"!==e)return void console.warn(`setRenderMode(): invalid mode '${String(e)}', ignoring.`);p!==e&&(K=0,q=0,j=0,Z=0,X=0,$=0,p=e,"external"===e?ie():_&&oe())}},resize:()=>ye(!0),dispose:Te,on(e,t){m||(U[e].add(t),"dataAppend"===e&&(k=!0))},off(e,t){U[e].delete(t),"dataAppend"===e&&(k=U.dataAppend.size>0)},getInteractionX:()=>m?null:(null==v?void 0:v.getInteractionX())??null,setInteractionX(e,t){m||null==v||v.setInteractionX(e,t)},setCrosshairX(e,t){m||null==v||v.setInteractionX(e,t)},onInteractionXChange:e=>m?()=>{}:(null==v?void 0:v.onInteractionXChange(e))??(()=>{}),getZoomRange:()=>m?null:(null==v?void 0:v.getZoomRange())??null,setZoomRange(e,t,n){if(m||!v)return;const i=v.getZoomRange();if(!i)return;M=!0,d=n,v.setZoomRange(e,t);const r=v.getZoomRange();(!r||r.start===i.start&&r.end===i.end)&&(M=!1,d=void 0)},getPerformanceMetrics:()=>m?null:we(),getPerformanceCapabilities:()=>m?null:{gpuTimingSupported:!1,highResTimerSupported:typeof performance<"u"&&"function"==typeof performance.now,performanceMetricsSupported:!0},onPerformanceUpdate:e=>m?()=>{}:(ee.add(e),()=>{ee.delete(e)}),hitTest(e){const t=o.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(m||!(t.width>0)||!(t.height>0))return{isInGrid:!1,canvasX:n,canvasY:i,gridX:0,gridY:0,match:null};const r=A.grid.left,a=A.grid.top,s=t.width-A.grid.left-A.grid.right,l=t.height-A.grid.top-A.grid.bottom,u=n-r,c=i-a;if(!(s>0&&l>0))return{isInGrid:!1,canvasX:n,canvasY:i,gridX:u,gridY:c,match:null};if(!(u>=0&&u<=s&&c>=0&&c<=l))return{isInGrid:!1,canvasX:n,canvasY:i,gridX:u,gridY:c,match:null};const d=A.xAxis.min??T.xMin,f=A.xAxis.max??T.xMax,p=A.yAxis.min??T.yMin,h=A.yAxis.max??T.yMax,g=sr(d,f),b=(null==v?void 0:v.getZoomRange())??null,y=(()=>{if(!b)return g;const e=g.max-g.min;if(!Number.isFinite(e)||0===e)return g;const t=b.start,n=b.end,i=g.min+t/100*e,r=g.min+n/100*e;return sr(i,r)})(),x=sr(p,h);if(null===D||D.rectWidthCss!==t.width||D.rectHeightCss!==t.height||D.plotWidthCss!==s||D.plotHeightCss!==l||D.xDomainMin!==y.min||D.xDomainMax!==y.max||D.yDomainMin!==x.min||D.yDomainMax!==x.max){const e=Mn().domain(y.min,y.max).range(0,s),n=Mn().domain(x.min,x.max).range(l,0);D={rectWidthCss:t.width,rectHeightCss:t.height,plotWidthCss:s,plotHeightCss:l,xDomainMin:y.min,xDomainMax:y.max,yDomainMin:x.min,yDomainMax:x.max,xScale:e,yScale:n}}const w=D,M=(()=>{const e=.5*Math.min(s,l);if(!(e>0))return null;for(let t=A.series.length-1;t>=0;t--){const n=A.series[t];if("pie"!==n.type||!1===n.visible)continue;const i=n,r=ur(i.center,s,l),o=cr(i.radius,e),a=xn(u,c,{seriesIndex:t,series:i},r,o);if(!a)continue;const d=a.slice.value;return{kind:"pie",seriesIndex:a.seriesIndex,dataIndex:a.dataIndex,sliceValue:"number"==typeof d&&Number.isFinite(d)?d:0}}return null})();if(M)return{isInGrid:!0,canvasX:n,canvasY:i,gridX:u,gridY:c,match:{kind:"pie",seriesIndex:M.seriesIndex,dataIndex:M.dataIndex,value:[0,M.sliceValue]}};for(let e=A.series.length-1;e>=0;e--){const t=A.series[e];if("candlestick"!==(null==t?void 0:t.type)||!1===t.visible)continue;const r=t,o=mn(r,r.data,w.xScale,s),a=bn([r],u,c,w.xScale,w.yScale,o);if(!a)continue;const l=ir(a.point),d=rr(a.point);return{isInGrid:!0,canvasX:n,canvasY:i,gridX:u,gridY:c,match:{kind:"candlestick",seriesIndex:e,dataIndex:a.dataIndex,value:[l,d]}}}const F=Ne(B(),u,c,w.xScale,w.yScale);if(F){const{x:e,y:t}=tr(F.point);return{isInGrid:!0,canvasX:n,canvasY:i,gridX:u,gridY:c,match:{kind:"cartesian",seriesIndex:F.seriesIndex,dataIndex:F.dataIndex,value:[e,t]}}}return{isInGrid:!0,canvasX:n,canvasY:i,gridX:u,gridY:c,match:null}}};try{ye(!1);try{const e=n?{device:n.device,adapter:n.adapter}:void 0;b=await i.create(o,e)}catch(e){const t=e instanceof Error?e.message:String(e);throw new Error(`ChartGPU: WebGPU is not available.\nReason: ${t}\nBrowser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.\nResources:\n - MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API\n - Browser compatibility: https://caniuse.com/webgpu\n - WebGPU specification: https://www.w3.org/TR/webgpu/\n - Check your system: https://webgpureport.org/`)}return null==(r=b.device)||r.lost.then(e=>{g=!0,!m&&("destroyed"!==e.reason&&console.warn("WebGPU device lost:",e),a&&"destroyed"!==e.reason&&Fe("deviceLost",{reason:e.reason,message:e.message}),Te())}),ye(!1),ve(),fe(),pe(),"auto"===p&&oe(),De}catch(e){throw De.dispose(),e}}},fr={};HTMLWidgets.widget({name:"chartgpu",type:"output",factory:function(e,t,n){let i=null;return{renderValue:function(t){var n=t.options,r=t.syncGroup||null,o=t.syncZoom||!1;const a=document.getElementById(e.id);null===i?(i=dr.create(a,n),r&&(fr[r]||(fr[r]=[]),fr[r].push(i),Promise.all(fr[r]).then(function(e){!function(e,t){const n=(null==t?void 0:t.syncCrosshair)??!0,i=(null==t?void 0:t.syncZoom)??!1,r=Symbol("ChartGPU.connectCharts");const o=[];let a=!1,s=null,l=!1,u=0,c=100;const d=(t,n)=>{if(!a||n!==s){a=!0,s=n;for(const i of e)i!==t&&(i.disposed||i.setCrosshairX(n,r))}},f=(t,n,i)=>{if(!l||n!==u||i!==c){l=!0,u=n,c=i;for(const o of e)o!==t&&(o.disposed||o.setZoomRange(n,i,r))}};for(const t of e)if(!t.disposed){if(n){const e=e=>{e.source!==r&&(t.disposed||d(t,e.x))};t.on("crosshairMove",e);const n=()=>t.off("crosshairMove",e);o.push(n)}if(i){const e=e=>{e.source!==r&&"auto-scroll"!==e.sourceKind&&(t.disposed||f(t,e.start,e.end))};t.on("zoomRangeChange",e);const n=()=>t.off("zoomRangeChange",e);o.push(n)}}}(e,{syncZoom:o})}))):i.then(function(e){e.setOption(n)})},resize:function(e,t){i&&i.then(function(e){e.resize()})}}}})})(); \ No newline at end of file diff --git a/srcjs/widgets/chartgpu.js b/srcjs/widgets/chartgpu.js index 0590014..eefa0e0 100644 --- a/srcjs/widgets/chartgpu.js +++ b/srcjs/widgets/chartgpu.js @@ -1,43 +1,42 @@ import "widgets"; -import { ChartGPU } from "chartgpu"; - +import { ChartGPU, connectCharts } from "chartgpu"; +const _registry = {}; HTMLWidgets.widget({ - name: "chartgpu", - type: "output", - factory: function(el, width, height) { - let chart = null; - return { - renderValue: function(x) { - - var options = x.options - + var options = x.options; + var groupId = x.syncGroup || null; + var syncZoom = x.syncZoom || false; const container = document.getElementById(el.id); - console.log(chart); + if (chart === null) { chart = ChartGPU.create(container, options); + + if (groupId) { + if (!_registry[groupId]) _registry[groupId] = []; + _registry[groupId].push(chart); + + Promise.all(_registry[groupId]).then(function(instances) { + connectCharts(instances, { syncZoom: syncZoom }); + }); + } } else { - chart.then(function(x) { - x.setOption(options); + chart.then(function(instance) { + instance.setOption(options); }); } - }, - resize: function(width, height) { - - // TODO: code to re-render the widget with a new size - + if (chart) { + chart.then(function(instance) { instance.resize(); }); + } } - }; } -}); - +}); \ No newline at end of file From f81ccb921e78882fcf597a40a88721925fc29fbb Mon Sep 17 00:00:00 2001 From: Othman Beqqal Date: Tue, 5 May 2026 16:22:12 +0200 Subject: [PATCH 2/3] Ajout d'un exemple shiny --- .DS_Store | Bin 8196 -> 10244 bytes examples/.DS_Store | Bin 0 -> 6148 bytes examples/connect_charts_shiny.R | 51 ++++++++++++++++++++++++++++++++ inst/.DS_Store | Bin 6148 -> 6148 bytes 4 files changed, 51 insertions(+) create mode 100644 examples/.DS_Store create mode 100644 examples/connect_charts_shiny.R diff --git a/.DS_Store b/.DS_Store index 7d46b097a527ffcfb7bce23e5f2fa474dead445e..d59749eea92c2184e35169c3dd9a5ef26a71517a 100644 GIT binary patch literal 10244 zcmeHMU2Ggz6+UO|Bs1~U9w$!Y1dqDSrfQoyj^q5d4PCEeS|^R|dhL4c{A_1;CiWz= zGuxTjwNp33Lh4IPgWv^JpwJgUAo@_X5b**MPzn++5Rh6SkSaickXi|Z1XO}^@15Q5 zpTz?~6fq;sJ@@B)=kERHoH_T-0syAV=0Si20LXMRsi{=7x!5?nTP`W;*+miw53nD6 zFkofE@d_>4aYxKR%s|XQ%s|XQ%)keM0m|9zlDmYA%b00jpPg_Ct`3+IGA?5VVg_0nU}tw3OggoPbl08V^NyFNF&0i~x`+P3FRB4_!6_Jr z42;1HOu#hEQaJ^a?9^X}dZh^^g9WQJM-fWkP(5hW$36c_Kfe-`BKtS;CC3iJ;o+a7 z)X}+V^A>rF+$CSgEPE@N&1xvTN^n#JeW9m^x(C@#M+4wsvkad^x8E=-jO`;z)bFn zQ*^y&89ns!iC$80n`qa{=cv}ggA-K7#JV~%)pfm9U6-=8OTA5>&n_&UQ*+w33N2u& z6xyB}JZ|{`$(+^`&_X8)o;&SZY<#}pIpv}o}HSFyKQ@)sxA_vZfIY!Eq`vsHpArwBPdv|X}e4F6+5u=jy3BVMXMJF z73F46|E}F18qoEPRI}y0{bbn=uWCtI=5r+O)YbDQ{id^?$!0ON*JQFov)^^6uAgHg zW4=YD83FFyr>nC8EnYJs#i0YLI(vm&K?~SVAn2jPsy^o!dCSpEMa*;jgsRV11pnHZ zsPkl>s%Hycu}Dh{qQ23zu3u!+K57KvRLOGbC%qBP{Sg{l43-Vwnpz=OjCxN~FMp)e z&p_j*9eR9_*qEeMEHHDUrpec^yMI@Yp3&!I?I&_h(`>h5ll#+S6;U83tB)p`+9#^X z@7U|S#)(d*hDEnRZmGiv1@@!x1bxI?gXiHh@DjWV--p-XXYfn-J-h>dMa0dh;8yIy zKHQCaaS)H-F+7eZFpX3A7|vh@&*L)Mco_p+#iwu$pT=kKS^PLYkJs_j_<8&Sei2{7 zui`8CD!zu_z;ELl_(S{={uJNFU*m7^xA+eJ4gZesNt>jdQopoI+9M50`=uf2m~>pa zUwS~Al%}MtWJs4KPg)fVkg6efLA0x-bd_rDLN0ohNH4b!xq*itnK*sse<$SL>=r?` zhds9TCdPg-4h{^-6rh^Ko9e-VLkfkV)*+gM1IH9uL(#ZjeNdr* z)H+2|S5u0j0dEY94UEeaRGNINy!}mh8-54x!h7WH-MAh5@opR@AOA2uf|KOs%*W^O zBIeM*JepWU7fbjg`TNs&4L^$O_%VEr{QWw90zZi_;Aio3_#%E8zd}C$HT*hx{5SCi zeha^g-^17O2a)gpf;|5Z_@^dsK3nx;A@R@cyt$I`UB`2mXpBWcC)nUZ0AW*t{S=MW zr}3KJe><@r896eTICNt8-%PBv_1J|<6y5maYIOff(;8B$2$$Zz-W@wAWXQL759GA% zd82S;$!A*tN_(E4cFI;Q^VKEFZB2SJmU;30uGy<4N~V49cW_$|`sl>e8ja z3bS?fg_hjAaGodi&?-*2m%I%Ve?uzIE*QRVxJy?0>II&!rrfj_hF+29lZGtoSSwT8ffPoe?N{-QEYIaGG|A%di61;RW~- z+@M7A7W@(Zf}MCf?!o);FrLJRD5NHE5ep(^2z>2Tu1EGFfdN%&54p+dw@~7mpdINr zOwzpLjjk`T!(zSbZ*A0uA=;IiO&Grk(?L20xQ$wTZ~S82-dLgeN8v2rA5T+_eo+&G z?ThOXDg~=YJ8%nfGy|)ZH{2iB<9cZyZ9oC8P`O0t{e<#(dk8L5_ zVFMgzuO5dm)3_#yaaFI;LtBUfJ$-{@NWZQ`YZ{`{LW$ZQTy8`&4zas|!x`dllr|%b z$2QLfh{FcNCR#6>k=EU4o1H2eG<(S-Ey&kaK13*wcxTMJG*_zyVy(eKcZ&t~>?-ZB zjJXDEPYYHsVzxySs|{!(Ilf{BZW#j|!cu~L{~zD@|NmPyUu-C5AZFl$#{hPo%ABGk z%uf&PejcSUNYMQR-RxqgjCCRTv6~8}!ut8=cxtfE@q8CaebF}tKAwv7)`jG7!f`lB d@iqTH{$~Jva*NOZ^cgHZ|F`+t_5X4H|0e=gW`+O& delta 96 zcmZn(XmOBWU|?W$DortDU;r^WfEYvza8E20o2aMAD7rCVH$S83WFCQ;o9~Gyu?sQ- kWr09~8%Vf<6mBg1&ODi4C6I#=qMc!KJkQk4W-{!|04}@{761SM diff --git a/examples/.DS_Store b/examples/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ab95dc2074b30f7978288a4564a06f4b0e16f4ce GIT binary patch literal 6148 zcmeHKQA@)x5WZ|vTSVA{!X5*@4xP>k;!BzO2UgJsmD;-DinWoobI2IqeV&(U2HXL+mjA}ZC|!s3#% z@#;9_{awJA(fEi#0=9K|^o;l0&x&VG}W`G&^H3sN>kf?;7#loOI zI)!Z10NZvnrfZ$|IzpN|BpdjV+NRkf5m{P9r}k|T$0VLpB6{CR-#^_ ql8|3v@GS%lor=+yQgH)S3${x#5Iu{9L2NB!ku~2NHo+2a5#(>?7ixZfc7+EGOFiUM#V-jJk&rB{WNXp4iVqjoA zn^cgKSzKaZa9==xk%^gwm5rT)lZ%^&mycgSP)Jx%L{L;zR7_k#Qc6lDUO+f0F*!TE zD8Do>#W_DGzsM=4G&LeKIX^Ervnn;BB(6w04fqeh=2`q zFG@|#i%u`fOz}@kD^4wmKw?M63-A{w7v<;V1mqWImSpDVMaC3oE*+6;~iUJStu84TqNeGIc0mND#LILdH~;SIw#MixdfMkPjVMiWL`MtepN zMo-2l#$?6}#!SX6uz3tjj1ZbZ7D_`Y#$sSBf7#5=!OsCq1DgYxzcWwf7jfhODrW*I K*&HFVh8X~ovyPJh delta 72 zcmZoMXfc=|#>B)qu~2NHo+2aj#(>?7jLef2Sfw_rv4}8E)@8r7S%Kp-^JaDqeh#3z a&4L`?nJ4p$IC3xm0V4wg%jO7?HOv5!#So1E From 8bcf553e4cb13095e8dd4131f1724d1370c4811d Mon Sep 17 00:00:00 2001 From: Othman Beqqal Date: Wed, 6 May 2026 14:56:56 +0200 Subject: [PATCH 3/3] Ajout de pie/donnut et bar --- NAMESPACE | 3 ++ R/bar.R | 20 +++++++++ R/chartgpu.R | 2 + R/pie.R | 97 +++++++++++++++++++++++++++++++++++++++++ examples/chartgpu_bar.R | 6 +++ examples/chartgpu_pie.R | 13 ++++++ examples/shiny.R | 24 +++++++--- man/bargpu.Rd | 39 +++++++++++++++++ man/chartgpu-shiny.Rd | 22 ++++++++-- man/chartgpu.Rd | 7 +++ man/donutgpu.Rd | 64 +++++++++++++++++++++++++++ man/piegpu.Rd | 64 +++++++++++++++++++++++++++ 12 files changed, 352 insertions(+), 9 deletions(-) create mode 100644 R/bar.R create mode 100644 R/pie.R create mode 100644 examples/chartgpu_bar.R create mode 100644 examples/chartgpu_pie.R create mode 100644 man/bargpu.Rd create mode 100644 man/donutgpu.Rd create mode 100644 man/piegpu.Rd diff --git a/NAMESPACE b/NAMESPACE index 1289656..7c6aab5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,6 +2,7 @@ export(JS) export(aes) +export(bargpu) export(chartgpu) export(chartgpuOutput) export(chartgpu_axis_x) @@ -12,6 +13,8 @@ export(chartgpu_theme) export(chartgpu_theme_dark) export(chartgpu_theme_light) export(chartgpu_zoom) +export(donutgpu) +export(piegpu) export(renderChartgpu) export(scattergpu) importFrom(ggplot2,aes) diff --git a/R/bar.R b/R/bar.R new file mode 100644 index 0000000..4fba537 --- /dev/null +++ b/R/bar.R @@ -0,0 +1,20 @@ +#' Bar Chart with ChartGPU +#' +#' @param data A `data.frame`. +#' @inheritParams chartgpu +#' @inheritParams htmlwidgets::createWidget +#' +#' @returns A [chartgpu()] `htmlwidget` object. +#' @export +#' +#' @example examples/chartgpu_bar.R +bargpu <- function(data, mapping = NULL, width = NULL, height = NULL, elementId = NULL) { + chartgpu( + data = data, + mapping = mapping, + type = "bar", + width = width, + height = height, + elementId = elementId + ) +} \ No newline at end of file diff --git a/R/chartgpu.R b/R/chartgpu.R index 61124d7..ea0a1ef 100644 --- a/R/chartgpu.R +++ b/R/chartgpu.R @@ -8,6 +8,8 @@ #' @param mapping Optional mapping of variables to use if `data` is a `data.frame` #' @param type Type of chart, if `data` is a `data.frame`. #' @param ... Additional parameters. +#' @param group Group ID to link multiple charts together. +#' @param sync_zoom Whether to sync zoom/pan across charts in the same group. #' @inheritParams htmlwidgets::createWidget #' #' @return A [chartgpu()] `htmlwidget` object. diff --git a/R/pie.R b/R/pie.R new file mode 100644 index 0000000..89b22a9 --- /dev/null +++ b/R/pie.R @@ -0,0 +1,97 @@ +#' Pie Chart with ChartGPU +#' +#' @param data A `data.frame`. +#' @param name Series name shown in the tooltip. +#' @param radius Length-2 vector `c(inner, outer)`, e.g. `c(0, "72%")`. +#' @param center Length-2 vector for the chart centre, e.g. `c("50%", "50%")`. +#' @param start_angle Starting angle in degrees (default 90 = top). +#' @inheritParams chartgpu +#' @inheritParams htmlwidgets::createWidget +#' +#' @returns A [chartgpu()] `htmlwidget` object. +#' @export +#' +#' @example examples/chartgpu_pie.R +piegpu <- function(data, + mapping = NULL, + name = NULL, + radius = c(0, "72%"), + center = c("50%", "50%"), + start_angle = 90, + width = NULL, + height = NULL, + elementId = NULL) { + + if (is.null(mapping)) { + nms <- colnames(data) + mapping <- list( + label = nms[1], + value = nms[2], + color = if (length(nms) >= 3) nms[3] else NULL + ) + } + + slices <- lapply(seq_len(nrow(data)), function(i) { + s <- list(name = as.character(data[[mapping$label]][i]), + value = data[[mapping$value]][i]) + if (!is.null(mapping$color) && !is.na(data[[mapping$color]][i])) + s$color <- data[[mapping$color]][i] + s + }) + + serie <- dropNulls(list( + type = "pie", + name = name, + data = slices, + radius = as.list(radius), + center = as.list(center), + startAngle = start_angle + )) + + chartgpu( + data = list( + series = list(serie), + xAxis = list(type = "value", min = 0, max = 1, tickLength = 0, name = ""), + yAxis = list(type = "value", min = 0, max = 1, tickLength = 0, name = "") + ), + width = width, + height = height, + elementId = elementId + ) +} + +#' Donut Chart with ChartGPU +#' +#' @param data A `data.frame`. +#' @param name Series name shown in the tooltip. +#' @param radius Length-2 vector `c(inner, outer)`, e.g. `c("40%", "72%")`. +#' @param center Length-2 vector for the chart centre, e.g. `c("50%", "50%")`. +#' @param start_angle Starting angle in degrees (default 90 = top). +#' @inheritParams chartgpu +#' @inheritParams htmlwidgets::createWidget +#' +#' @returns A [chartgpu()] `htmlwidget` object. +#' @export +#' +#' @example examples/chartgpu_pie.R +donutgpu <- function(data, + mapping = NULL, + name = NULL, + radius = c("40%", "72%"), + center = c("50%", "50%"), + start_angle = 90, + width = NULL, + height = NULL, + elementId = NULL) { + piegpu( + data = data, + mapping = mapping, + name = name, + radius = radius, + center = center, + start_angle = start_angle, + width = width, + height = height, + elementId = elementId + ) +} \ No newline at end of file diff --git a/examples/chartgpu_bar.R b/examples/chartgpu_bar.R new file mode 100644 index 0000000..347880f --- /dev/null +++ b/examples/chartgpu_bar.R @@ -0,0 +1,6 @@ +library(rchartgpu) + +bargpu( + ggplot2::economics[, c("date", "unemploy")], + height = "400px" +) \ No newline at end of file diff --git a/examples/chartgpu_pie.R b/examples/chartgpu_pie.R new file mode 100644 index 0000000..f762de5 --- /dev/null +++ b/examples/chartgpu_pie.R @@ -0,0 +1,13 @@ +library(rchartgpu) + +gpu_share <- data.frame( + label = c("Compute", "Memory", "Raster", "Upload", "Sync", "Other"), + value = c(42, 30, 18, 12, 9, 6), + color = c("#00E5FF", "#FF2D95", "#B026FF", "#00F5A0", "#FFD300", "#FF6B00") +) + +# Pie +piegpu(gpu_share, name = "GPU budget") + +# Donut +donutgpu(gpu_share, name = "GPU budget") diff --git a/examples/shiny.R b/examples/shiny.R index 54f3122..10197ee 100644 --- a/examples/shiny.R +++ b/examples/shiny.R @@ -1,7 +1,12 @@ - library(shiny) library(rchartgpu) +gpu_share <- data.frame( + label = c("Compute", "Memory", "Raster", "Upload", "Sync", "Other"), + value = c(42, 30, 18, 12, 9, 6), + color = c("#00E5FF", "#FF2D95", "#B026FF", "#00F5A0", "#FFD300", "#FF6B00") +) + ui <- fluidPage( fluidRow( column( @@ -12,19 +17,28 @@ ui <- fluidPage( label = "Variable:", choices = names(ggplot2::economics)[-1] ), - chartgpuOutput(outputId = "chart", height = "500px") + chartgpuOutput(outputId = "chart", height = "500px"), + chartgpuOutput(outputId = "pie", height = "350px"), + br(), + chartgpuOutput(outputId = "donut", height = "350px") ) ) ) server <- function(input, output, session) { - output$chart <- renderChartgpu({ chartgpu(ggplot2::economics[, c("date", input$variable)]) |> chartgpu_theme_light() }) - + + output$pie <- renderChartgpu({ + piegpu(gpu_share, name = "GPU budget") + }) + + output$donut <- renderChartgpu({ + donutgpu(gpu_share, name = "GPU budget") + }) } if (interactive()) - shinyApp(ui, server) + shinyApp(ui, server) \ No newline at end of file diff --git a/man/bargpu.Rd b/man/bargpu.Rd new file mode 100644 index 0000000..1bde9d9 --- /dev/null +++ b/man/bargpu.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/bar.R +\name{bargpu} +\alias{bargpu} +\title{Bar Chart with ChartGPU} +\usage{ +bargpu(data, mapping = NULL, width = NULL, height = NULL, elementId = NULL) +} +\arguments{ +\item{data}{A \code{data.frame}.} + +\item{mapping}{Default list of aesthetic mappings to use for chart.} + +\item{width}{Fixed width for widget (in css units). The default is +\code{NULL}, which results in intelligent automatic sizing based on the +widget's container.} + +\item{height}{Fixed height for widget (in css units). The default is +\code{NULL}, which results in intelligent automatic sizing based on the +widget's container.} + +\item{elementId}{Use an explicit element ID for the widget (rather than an +automatically generated one). Useful if you have other JavaScript that +needs to explicitly discover and interact with a specific widget instance.} +} +\value{ +A \code{\link[=chartgpu]{chartgpu()}} \code{htmlwidget} object. +} +\description{ +Bar Chart with ChartGPU +} +\examples{ +library(rchartgpu) + +bargpu( + ggplot2::economics[, c("date", "unemploy")], + height = "400px" +) +} diff --git a/man/chartgpu-shiny.Rd b/man/chartgpu-shiny.Rd index 18cfb76..d67934e 100644 --- a/man/chartgpu-shiny.Rd +++ b/man/chartgpu-shiny.Rd @@ -30,10 +30,15 @@ Output and render functions for using \code{\link[=chartgpu]{chartgpu()}} within applications and interactive Rmd documents. } \examples{ - library(shiny) library(rchartgpu) +gpu_share <- data.frame( + label = c("Compute", "Memory", "Raster", "Upload", "Sync", "Other"), + value = c(42, 30, 18, 12, 9, 6), + color = c("#00E5FF", "#FF2D95", "#B026FF", "#00F5A0", "#FFD300", "#FF6B00") +) + ui <- fluidPage( fluidRow( column( @@ -44,18 +49,27 @@ ui <- fluidPage( label = "Variable:", choices = names(ggplot2::economics)[-1] ), - chartgpuOutput(outputId = "chart", height = "500px") + chartgpuOutput(outputId = "chart", height = "500px"), + chartgpuOutput(outputId = "pie", height = "350px"), + br(), + chartgpuOutput(outputId = "donut", height = "350px") ) ) ) server <- function(input, output, session) { - output$chart <- renderChartgpu({ chartgpu(ggplot2::economics[, c("date", input$variable)]) |> chartgpu_theme_light() }) - + + output$pie <- renderChartgpu({ + piegpu(gpu_share, name = "GPU budget") + }) + + output$donut <- renderChartgpu({ + donutgpu(gpu_share, name = "GPU budget") + }) } if (interactive()) diff --git a/man/chartgpu.Rd b/man/chartgpu.Rd index c53af2b..112dd8b 100644 --- a/man/chartgpu.Rd +++ b/man/chartgpu.Rd @@ -9,6 +9,8 @@ chartgpu( mapping = NULL, type = NULL, ..., + group = NULL, + sync_zoom = FALSE, width = NULL, height = NULL, elementId = NULL @@ -23,6 +25,10 @@ chartgpu( \item{...}{Additional parameters.} +\item{group}{Group ID to link multiple charts together.} + +\item{sync_zoom}{Whether to sync zoom/pan across charts in the same group.} + \item{width}{Fixed width for widget (in css units). The default is \code{NULL}, which results in intelligent automatic sizing based on the widget's container.} @@ -94,4 +100,5 @@ chartgpu(list( dataZoom = list(list(type = "inside"), list(type = "slider")), theme = "light" )) + } diff --git a/man/donutgpu.Rd b/man/donutgpu.Rd new file mode 100644 index 0000000..1911ab1 --- /dev/null +++ b/man/donutgpu.Rd @@ -0,0 +1,64 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/pie.R +\name{donutgpu} +\alias{donutgpu} +\title{Donut Chart with ChartGPU} +\usage{ +donutgpu( + data, + mapping = NULL, + name = NULL, + radius = c("40\%", "72\%"), + center = c("50\%", "50\%"), + start_angle = 90, + width = NULL, + height = NULL, + elementId = NULL +) +} +\arguments{ +\item{data}{A \code{data.frame}.} + +\item{mapping}{Optional mapping of variables to use if \code{data} is a \code{data.frame}} + +\item{name}{Series name shown in the tooltip.} + +\item{radius}{Length-2 vector \code{c(inner, outer)}, e.g. \code{c("40\%", "72\%")}.} + +\item{center}{Length-2 vector for the chart centre, e.g. \code{c("50\%", "50\%")}.} + +\item{start_angle}{Starting angle in degrees (default 90 = top).} + +\item{width}{Fixed width for widget (in css units). The default is +\code{NULL}, which results in intelligent automatic sizing based on the +widget's container.} + +\item{height}{Fixed height for widget (in css units). The default is +\code{NULL}, which results in intelligent automatic sizing based on the +widget's container.} + +\item{elementId}{Use an explicit element ID for the widget (rather than an +automatically generated one). Useful if you have other JavaScript that +needs to explicitly discover and interact with a specific widget instance.} +} +\value{ +A \code{\link[=chartgpu]{chartgpu()}} \code{htmlwidget} object. +} +\description{ +Donut Chart with ChartGPU +} +\examples{ +library(rchartgpu) + +gpu_share <- data.frame( + label = c("Compute", "Memory", "Raster", "Upload", "Sync", "Other"), + value = c(42, 30, 18, 12, 9, 6), + color = c("#00E5FF", "#FF2D95", "#B026FF", "#00F5A0", "#FFD300", "#FF6B00") +) + +# Pie +piegpu(gpu_share, name = "GPU budget") + +# Donut +donutgpu(gpu_share, name = "GPU budget") +} diff --git a/man/piegpu.Rd b/man/piegpu.Rd new file mode 100644 index 0000000..380bfc4 --- /dev/null +++ b/man/piegpu.Rd @@ -0,0 +1,64 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/pie.R +\name{piegpu} +\alias{piegpu} +\title{Pie Chart with ChartGPU} +\usage{ +piegpu( + data, + mapping = NULL, + name = NULL, + radius = c(0, "72\%"), + center = c("50\%", "50\%"), + start_angle = 90, + width = NULL, + height = NULL, + elementId = NULL +) +} +\arguments{ +\item{data}{A \code{data.frame}.} + +\item{mapping}{Optional mapping of variables to use if \code{data} is a \code{data.frame}} + +\item{name}{Series name shown in the tooltip.} + +\item{radius}{Length-2 vector \code{c(inner, outer)}, e.g. \code{c(0, "72\%")}.} + +\item{center}{Length-2 vector for the chart centre, e.g. \code{c("50\%", "50\%")}.} + +\item{start_angle}{Starting angle in degrees (default 90 = top).} + +\item{width}{Fixed width for widget (in css units). The default is +\code{NULL}, which results in intelligent automatic sizing based on the +widget's container.} + +\item{height}{Fixed height for widget (in css units). The default is +\code{NULL}, which results in intelligent automatic sizing based on the +widget's container.} + +\item{elementId}{Use an explicit element ID for the widget (rather than an +automatically generated one). Useful if you have other JavaScript that +needs to explicitly discover and interact with a specific widget instance.} +} +\value{ +A \code{\link[=chartgpu]{chartgpu()}} \code{htmlwidget} object. +} +\description{ +Pie Chart with ChartGPU +} +\examples{ +library(rchartgpu) + +gpu_share <- data.frame( + label = c("Compute", "Memory", "Raster", "Upload", "Sync", "Other"), + value = c(42, 30, 18, 12, 9, 6), + color = c("#00E5FF", "#FF2D95", "#B026FF", "#00F5A0", "#FFD300", "#FF6B00") +) + +# Pie +piegpu(gpu_share, name = "GPU budget") + +# Donut +donutgpu(gpu_share, name = "GPU budget") +}