@protomaze/time 1.8.3 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -67,6 +67,44 @@ export type TimeSliderSelectionRange = {
67
67
  startTime: number;
68
68
  endTime: number;
69
69
  };
70
+ /** How a selection range (or the box while drawing one) looks in one state. CSS colours; widths and sizes in CSS pixels (drawn on whole device pixels). */
71
+ export type TimeSliderSelectionRangeStyle = {
72
+ /** CSS background of the range, e.g. '#9AC0A633'. */
73
+ fill?: string;
74
+ /** Frame around the range; its start and end sides are centred on the range's start and end. */
75
+ border?: {
76
+ color?: string;
77
+ width?: number;
78
+ style?: 'solid' | 'dashed' | 'dotted';
79
+ };
80
+ /** Grab strips on the start and end, centred on them (editing only). 'bar' runs the full height, 'grip' is a short pill in the middle. Whatever their width, they can be grabbed 8px wide. */
81
+ handle?: {
82
+ color?: string;
83
+ width?: number;
84
+ look?: 'bar' | 'grip';
85
+ };
86
+ /** A soft outer glow around the frame (a bloom), in the border colour unless given. intensity 0..1 scales its opacity. false or undefined: none. */
87
+ glow?: {
88
+ color?: string;
89
+ size?: number;
90
+ intensity?: number;
91
+ } | false;
92
+ };
93
+ /** Selection range styles per state: idle, editing (selected) and drawing (the box while dragging out a range). Anything left out keeps its default. */
94
+ export type TimeSliderSelectionStyle = {
95
+ idle?: TimeSliderSelectionRangeStyle;
96
+ editing?: TimeSliderSelectionRangeStyle;
97
+ drawing?: TimeSliderSelectionRangeStyle;
98
+ };
99
+ /** 'front' (default): the ranges are drawn over the layers. 'behind': their fill goes under the layers; the frame, handles, glow and the dimming outside stay in front. */
100
+ export type TimeSliderSelectionOrder = 'front' | 'behind';
101
+ /**
102
+ * 'always' (default): every selection range can be moved and resized.
103
+ * 'click': ranges are idle (pointer events pass through to the layers) until a click inside one,
104
+ * on no element, selects it for editing; Escape, a click outside it or drawing a new range ends that.
105
+ * 'never': ranges are always idle. editSelection() selects one from code in any mode.
106
+ */
107
+ export type TimeSliderSelectionEditMode = 'always' | 'click' | 'never';
70
108
  export type TimeSliderSelectionChangePhase = 'start' | 'drag' | 'end';
71
109
  export type TimeSliderSelectRangeMode = 'zoom' | 'select' | 'createSelection';
72
110
  /** A tick box on the ticks bar, as passed to TimeSliderOptions.tickTooltip and the 'tickhover' event. */
@@ -147,6 +185,12 @@ export interface TimeSliderOptions {
147
185
  gridOrder?: TimeSliderGridOrder;
148
186
  /** Style of the box drawn while drag-selecting a range (startSelectingRange / right- or ctrl-drag). See also setSelectingRangeStyle(). */
149
187
  selectingRangeStyle?: TimeSliderSelectingRangeStyle;
188
+ /** How selection ranges (setSelection) become editable, see TimeSliderSelectionEditMode. See also setSelectionEditMode() and editSelection(). */
189
+ selectionEditMode?: TimeSliderSelectionEditMode;
190
+ /** Selection range styles per state (idle, editing, drawing). Switchable at runtime with setSelectionStyle(). */
191
+ selectionStyle?: TimeSliderSelectionStyle;
192
+ /** Selection range fill in front of the layers (default) or behind them. See also setSelectionOrder(). */
193
+ selectionOrder?: TimeSliderSelectionOrder;
150
194
  }
151
195
  export type TimeSliderGridOrder = 'front' | 'behind';
152
196
  /** CSS values for the drag-select box; anything left out keeps its default (background '#df04', border '3px solid #df0'). */
@@ -179,6 +223,11 @@ export declare class TimeSlider extends TypedEventEmitter<{
179
223
  tickclick: TimeSliderTickClickInfo;
180
224
  /** Fires when the pointer moves onto another tick box on the ticks bar, and with null when it leaves them. Carries the box's client rect, to render your own tooltip. */
181
225
  tickhover: TimeSliderTickHoverInfo | null;
226
+ /** Fires when a selection range becomes the one being edited (selected), and with null when editing ends. */
227
+ selectionedit: {
228
+ index: number;
229
+ range: TimeSliderSelectionRange;
230
+ } | null;
182
231
  }> {
183
232
  valueRanges: Map<string, {
184
233
  min: number;
@@ -221,6 +270,13 @@ export declare class TimeSlider extends TypedEventEmitter<{
221
270
  private selectionOverlayContainer;
222
271
  private _selectionRanges;
223
272
  private selectionRangeElements;
273
+ /** Under the engine's canvas (in the slider element): the ranges' fill with selectionOrder 'behind'. */
274
+ private selectionBehindContainer;
275
+ private _selectionEditMode;
276
+ /** In 'click' (and any) mode: the range being edited, or null. */
277
+ private editingIndex;
278
+ private selectionStyle;
279
+ private _selectionOrder;
224
280
  private shadingElements;
225
281
  private columnBandOverlayContainer;
226
282
  private columnBandElements;
@@ -262,8 +318,28 @@ export declare class TimeSlider extends TypedEventEmitter<{
262
318
  get background(): string | undefined;
263
319
  /** Sets the background colour behind the layers and the ticks bar (see TimeSliderOptions.background); undefined goes back to the theme's. */
264
320
  setBackground(background: string | undefined): void;
265
- /** Sets the style of the drag-select box, see TimeSliderSelectingRangeStyle. */
321
+ /** Sets the style of the drag-select box, see TimeSliderSelectingRangeStyle. selectionStyle.drawing takes precedence where it sets something. */
266
322
  setSelectingRangeStyle(style: TimeSliderSelectingRangeStyle): void;
323
+ /** Styles the box drawn while dragging out a range: selectionStyle.drawing, then selectingRangeStyle, then the defaults. */
324
+ private applyDrawingStyle;
325
+ get selectionEditMode(): TimeSliderSelectionEditMode;
326
+ /** Sets how selection ranges become editable, see TimeSliderSelectionEditMode. Ends any editing. */
327
+ setSelectionEditMode(mode: TimeSliderSelectionEditMode): void;
328
+ /** The index of the selection range being edited (selected), or null. */
329
+ get editingSelection(): number | null;
330
+ /** Selects a selection range for editing (any edit mode), or ends editing with null. Fires 'selectionedit'. */
331
+ editSelection(index: number | null): void;
332
+ /** Sets the selection range styles per state, see TimeSliderSelectionStyle. Applied to the ranges as they are, also mid-drag. */
333
+ setSelectionStyle(style: TimeSliderSelectionStyle): void;
334
+ get selectionOrder(): TimeSliderSelectionOrder;
335
+ /** Draws the selection ranges' fill in front of the layers ('front', default) or behind them ('behind'). */
336
+ setSelectionOrder(order: TimeSliderSelectionOrder): void;
337
+ private isRangeEditable;
338
+ private resolveSelectionStyle;
339
+ /** Applies a state's style to a range's elements (colours, border style, glow, handle look); sizes and positions are set by renderSelectionOverlay. */
340
+ private styleSelectionRange;
341
+ /** Lays the overlays over the layers' area only (not the ticks bar or current-time strip). */
342
+ private layoutOverlays;
267
343
  get gridOrder(): TimeSliderGridOrder;
268
344
  /** Draws the y-axis grid lines in front of the layers ('front', default) or behind them ('behind'). */
269
345
  setGridOrder(gridOrder: TimeSliderGridOrder): void;
@@ -344,6 +420,8 @@ export declare class TimeSlider extends TypedEventEmitter<{
344
420
  x: number;
345
421
  y: number;
346
422
  } | null, range?: TimeSliderTimeRange): void;
423
+ /** Edit mode 'click': a click inside a selection range on no element selects it for editing; any other click ends editing. */
424
+ private onSelectionRangeClick;
347
425
  listenToClicks(): () => void;
348
426
  getSliderBounds(): {
349
427
  top: number;
@@ -1 +1 @@
1
- import{v4 as e}from"uuid";import{Disposables as t}from"../common/Disposables.js";import{animateRangeTransition as i}from"../common/Easing.js";import{describeTimeSpan as s,formatDate as n,formatDateRange as l,formatDuration as o,formatTimeSpanDates as a,getDefaultLocale as r,getLargeTimeUnitRange as h,getMatchingTimeUnit as d,getTimeUnitRange as m,setDefaultLocale as c}from"../common/TimeTools.js";import{TimeSliderDynamicHistogram as g}from"../data/histogram/TimeSliderDynamicHistogram.js";import{getTimeArray as u}from"../data/TimeSliderElement.js";import{TimeSliderIntervalsModel as p}from"../data/TimeSliderIntervalsModel.js";import{addDuration as y,addPadding as T,applyTimeRangeUpdate as v,clampTimeRange as f,mergeTimeRanges as E,timeRangesOverlap as x,timeRangesUnion as L}from"../data/TimeSliderRange.js";import{TypedEventEmitter as b}from"../event/TypedEventEmitter.js";import{TimeSliderHistogramLayer as R}from"../layer/TimeSliderHistogramLayer.js";import{TimeSliderIntervalsLayer as w}from"../layer/TimeSliderIntervalsLayer.js";import{CENTURY as S,DECADE as k,MILLENIUM as C,ONE_DAY as V,ONE_HOUR as B,ONE_MINUTE as M,ONE_MONTH as D,ONE_SECOND as z,ONE_WEEK as O,ONE_YEAR as _,TODAY as A}from"../ticks/TimeSliderConstants.js";import{TimeTicksBar as H}from"../ticks/TimeTicksBar.js";import{YAxisTicks as I}from"../ticks/YAxisTicks.js";import{resolveFont as $,toCssFont as F}from"../common/Font.js";const U=z,P=10*C;export class TimeSlider extends b{getLayers(){return[...this.layers]}getVisibleLayers(){return this.getLayers().filter(e=>e.visible)}constructor(i){super(),this.valueRanges=new Map,this.layers=[],this.onDestroy=[],this.ticksBar=new H,this.loaders=new Set,this.layerUnloaders=new Map,this.layerListenerStoppers=new Map,this.layerLoaders=new Map,this.pressedKeys=new Set,this.container=null,this.d=new t,this.id=e(),this.playing=!1,this.live=!1,this._showCurrent=!1,this.current=Date.now(),this.range={time:A,value:{minValue:0,maxValue:100}},this.size={width:100,height:100},this.sliderElement=document.createElement("div"),this.yAxisTicks=new I,this.hoverLine=document.createElement("div"),this.toolTip=document.createElement("div"),this.selectedLabel=document.createElement("div"),this.selectingRangeElement=document.createElement("div"),this.selectionOverlayContainer=document.createElement("div"),this._selectionRanges=[],this.selectionRangeElements=[],this.shadingElements=[],this.columnBandOverlayContainer=document.createElement("div"),this.columnBandElements=[],this.selectingRange=!1,this.selectingRangeVisible=!1,this.tickTooltip=!0,this.tooltipStyle={},this.tickToolTip=document.createElement("div"),this._gridOrder="front",this.selectingRangeStyle={},this.updateValueRangesQueue=new Map,this.showingStats=!1,this._engineReady=!1,this.mouse=null,this.updatingLabel=!1,this.warnedDirection=new Set,this.hoverCleared=!0,this.dragging=!1,this.pinching=!1,this.hoverOptions=i?.hover||{},this.selectionOptions={highlight:"boolean"!=typeof i?.selection?.highlight||i.selection.highlight,label:"boolean"!=typeof i?.selection?.label||i.selection.label,shading:"boolean"!=typeof i?.selection?.shading||i.selection.shading,invertShading:"boolean"==typeof i?.selection?.invertShading&&i.selection.invertShading,pick:i?.selection?.pick||"element",columnBand:i?.selection?.columnBand},this.showCurrent=i?.showCurrent||!1,this.showTicks=i?.showTicks||!1,this.selectRangeMode=i?.selectRangeMode||"select",this.playSpeed=i?.playSpeed||"auto",this.liveRange=i?.liveRange||10*z,this.theme=i?.theme||"dark",this._locale=i?.locale||r(),c(this._locale),this.ticksBar.setLocale(this._locale),this.ticksBar.setWeekLabel(i?.weekLabel||"default",i?.weekLabelPrefix),this.ticksBar.setTickLabelStyler(i?.tickLabelStyler),this.setLimits(i?.limits),this.tickTooltip=i?.tickTooltip??!0,this.tooltipStyle=i?.tooltipStyle??{},this.ticksBar.onHoverTick=e=>this.onTickHover(e),this._gridOrder=i?.gridOrder??"front",this.setSelectingRangeStyle(i?.selectingRangeStyle??{}),this.setBackground(i?.background),this.setFont(i?.font),this.syncMaxValues(),this.on("time",()=>this.renderSelectionOverlay()),this.on("size",()=>this.renderSelectionOverlay())}get locale(){return this._locale}setLocale(e){this._locale=e,c(e),this.ticksBar.setLocale(e),this.emit("locale",e)}setWeekLabel(e,t){this.ticksBar.setWeekLabel(e,t)}setTickLabelStyler(e){this.ticksBar.setTickLabelStyler(e)}get font(){return this._font?{...this._font}:void 0}setFont(e){this._font=e?{...e}:void 0;const t=$(e);this.ticksBar.setFont(F(t),t.size),this.yAxisTicks.setFont(e),this.applyTooltipStyles(),this.renderYAxis(),e&&"undefined"!=typeof document&&document.fonts&&document.fonts.load(F(t)).then(()=>this.refreshFonts(),()=>{})}refreshFonts(){this.ticksBar.refreshFont(),this.renderYAxis()}watchFontLoading(){if(this.stopWatchingFonts||"undefined"==typeof document||!document.fonts)return;const e=document.fonts,t=()=>this.refreshFonts();e.addEventListener("loadingdone",t),e.ready.then(t,()=>{}),this.stopWatchingFonts=()=>e.removeEventListener("loadingdone",t),this.onDestroy.push(()=>this.stopWatchingFonts?.())}watchPixelRatio(){if("undefined"==typeof window||!window.matchMedia)return;let e=()=>{};const t=()=>{const i=window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),s=()=>{e(),this.ticksBar.draw(),this.renderYAxis(),t()};i.addEventListener("change",s),e=()=>i.removeEventListener("change",s)};t(),this.onDestroy.push(()=>e())}get background(){return this._background}setBackground(e){this._background=e,this.engine?.setBackground(e),this.ticksBar.setBackground(e),this.updateBehindLayers()}setSelectingRangeStyle(e){this.selectingRangeStyle={...e},this.selectingRangeElement.style.boxSizing="border-box",this.selectingRangeElement.style.background=e.background??"#df04",this.selectingRangeElement.style.border=e.border??"3px solid #df0",this.selectingRangeElement.style.zIndex="3"}get gridOrder(){return this._gridOrder}setGridOrder(e){this._gridOrder=e,this.updateBehindLayers(),this.renderYAxis()}updateBehindLayers(){const e="behind"===this._gridOrder||this.getVisibleLayers().some(e=>e.baseline);this.engine?.setTransparent(e),this.sliderElement.style.background=e?this._background??("dark"===this.theme?"#111":"#eee"):""}attachBehindCanvas(){const e=this.yAxisTicks.behindCanvas;e.style.height=this.sliderElement.style.height,e.style.zIndex="0",[...this.sliderElement.children].forEach(t=>{t!==e&&t!==this.selectedLabel&&t instanceof HTMLCanvasElement&&(t.style.zIndex="1")}),e.parentElement!==this.sliderElement&&this.sliderElement.insertBefore(e,this.sliderElement.firstChild)}setTickTooltip(e){this.tickTooltip=e,!1===e&&(this.tickToolTip.style.display="none")}setTooltipStyle(e){this.tooltipStyle={...e},this.applyTooltipStyles()}applyTooltipStyles(){this.applyTooltipStyle(this.toolTip),this.applyTooltipStyle(this.tickToolTip),this.applyTooltipStyle(this.selectedLabel,"200px")}applyTooltipStyle(e,t=""){const i=this.tooltipStyle;e.style.background=i.background??"rgba(0, 0, 0, 0.75)",e.style.color=i.color??"white",e.style.border=i.border??"none",e.style.borderRadius=i.borderRadius??"4px",e.style.padding=i.padding??"4px 8px",e.style.maxWidth=i.maxWidth??t,e.style.font=F($(i.font??this._font))}onTickHover(e){if(!e)return this.tickToolTip.style.display="none",void this.emit("tickhover",null);const t=this.ticksBar.getCanvasRect(),i=new DOMRect(t.left+e.x,t.top,e.width,t.height),s={startTime:e.startTime,endTime:e.endTime,unit:d(e.startTime,e.endTime),label:e.label,fullLabel:this.ticksBar.getFullLabel(e)};this.emit("tickhover",{...s,rect:i});const n=!1===this.tickTooltip?void 0:"function"==typeof this.tickTooltip?this.tickTooltip(s):s.fullLabel;if(!n)return void(this.tickToolTip.style.display="none");this.tickToolTip.textContent=n,this.tickToolTip.style.display="block";const l=this.tickToolTip.offsetWidth,o=this.tickToolTip.offsetHeight,a=Math.min(Math.max(4,i.left+.5*i.width-.5*l),window.innerWidth-l-4),r=i.top-o-6;this.tickToolTip.style.left=`${a}px`,this.tickToolTip.style.top=`${r>=4?r:i.bottom+6}px`}get limits(){return this._limits?{...this._limits}:void 0}setLimits(e){!e||e.endTime>e.startTime||(console.warn("Ignoring time slider limits whose endTime is not after startTime",e),e=void 0),this._limits=e?{startTime:e.startTime,endTime:e.endTime}:void 0,this._limits&&this.setTimeRange(this.getTimeRange())}setSelection(e){this._selectionRanges=e.map(e=>({...e})),this.renderSelectionOverlay(!0),this.emit("selectionchange",{ranges:this.getSelection(),phase:"end"})}getSelection(){return this._selectionRanges.map(e=>({...e}))}clearSelection(){this.setSelection([])}setPickMode(e){this.selectionOptions.pick=e,this.updateHover()}selectionTimeToX(e,t,i,s){return e===-1/0?0:e===1/0?s:Math.min(s,Math.max(0,(e-t)/(i-t)*s))}renderSelectionOverlay(e=!1){if(!this.container)return;const t=this.getSliderBounds();if(t.width<=0)return;const{startTime:i,endTime:s}=this.getTimeRange(),n=e=>this.selectionTimeToX(e,i,s,t.width);if((e||this.selectionRangeElements.length!==this._selectionRanges.length||this.selectionRangeElements.some((e,t)=>e.range!==this._selectionRanges[t]))&&(this.selectionRangeElements.forEach(({body:e,startHandle:t,endHandle:i})=>{e.remove(),t?.remove(),i?.remove()}),this.selectionRangeElements=this._selectionRanges.map(e=>this.createSelectionRangeElements(e))),this.selectionRangeElements.forEach(({range:e,body:t,startHandle:i,endHandle:s})=>{const l=n(e.startTime),o=n(e.endTime);t.style.left=l+"px",t.style.width=Math.max(0,o-l)+"px",i&&(i.style.left=l-4+"px"),s&&(s.style.left=o-4+"px")}),this.shadingElements.forEach(e=>e.remove()),this.shadingElements=[],this.selectionOptions.shading&&this._selectionRanges.length>0){const e=E(this._selectionRanges).map(e=>[n(e.startTime),n(e.endTime)]);(this.selectionOptions.invertShading?e:function(e,t){const i=[];let s=0;for(const[t,n]of e)t>s&&i.push([s,t]),s=Math.max(s,n);s<t&&i.push([s,t]);return i}(e,t.width)).forEach(([e,t])=>{if(t<=e)return;const i=document.createElement("div");i.style.position="absolute",i.style.top="0px",i.style.height="100%",i.style.left=e+"px",i.style.width=t-e+"px",i.style.background="rgba(0, 0, 0, 0.5)",i.style.pointerEvents="none",this.selectionOverlayContainer.appendChild(i),this.shadingElements.push(i)})}}renderColumnHoverBand(e){if(this.columnBandElements.forEach(e=>e.remove()),this.columnBandElements=[],"column"!==this.selectionOptions.pick||0===e.length||!this.container)return;const t=this.getSliderBounds();if(t.width<=0)return;const{startTime:i,endTime:s}=this.getTimeRange(),n=e=>Math.min(t.width,Math.max(0,(e-i)/(s-i)*t.width)),l=this.selectionOptions.columnBand?.color??"#fff",o=this.selectionOptions.columnBand?.opacity??.15;e.forEach(({layer:e,elements:t})=>{const i=t.map(u),s=Math.min(...i.map(e=>e[0])),a=Math.max(...i.map(e=>e[1])),r=document.createElement("div");r.style.position="absolute",r.style.left=n(s)+"px",r.style.width=Math.max(1,n(a)-n(s))+"px",r.style.top=100*(1-e.max)+"%",r.style.height=100*(e.max-e.min)+"%",r.style.background=l,r.style.opacity=String(o),r.style.pointerEvents="none",this.columnBandOverlayContainer.appendChild(r),this.columnBandElements.push(r)})}createSelectionRangeElements(e){const t=document.createElement("div");t.style.position="absolute",t.style.top="0px",t.style.height="100%",t.style.background="rgba(100, 180, 255, 0.15)",t.style.borderTop="2px solid rgba(100, 180, 255, 0.8)",t.style.borderBottom="2px solid rgba(100, 180, 255, 0.8)",t.style.boxSizing="border-box",t.style.cursor="grab",t.style.pointerEvents="auto",t.style.touchAction="none",this.selectionOverlayContainer.appendChild(t);const i=()=>{const e=document.createElement("div");return e.style.position="absolute",e.style.top="0px",e.style.height="100%",e.style.width="8px",e.style.cursor="ew-resize",e.style.pointerEvents="auto",e.style.touchAction="none",e.style.background="rgba(100, 180, 255, 0.9)",this.selectionOverlayContainer.appendChild(e),e},s=e.startTime===-1/0?null:i(),n=e.endTime===1/0?null:i();return this.wireSelectionDrag(e,t,s,n),{range:e,body:t,startHandle:s,endHandle:n}}wireSelectionDrag(e,t,i,s){const n=(e,t)=>{e.addEventListener("pointerdown",i=>{i.stopPropagation(),i.preventDefault(),e.setPointerCapture(i.pointerId);const s=t(i),n=e=>{s(e),this.renderSelectionOverlay(),this.emit("selectionchange",{ranges:this.getSelection(),phase:"drag"})};let l=!1;const o=t=>{l||(l=!0,e.hasPointerCapture(t.pointerId)&&e.releasePointerCapture(t.pointerId),e.removeEventListener("pointermove",n),e.removeEventListener("pointerup",o),e.removeEventListener("pointercancel",o),e.removeEventListener("lostpointercapture",o),this.emit("selectionchange",{ranges:this.getSelection(),phase:"end"}))};this.emit("selectionchange",{ranges:this.getSelection(),phase:"start"}),e.addEventListener("pointermove",n),e.addEventListener("pointerup",o),e.addEventListener("pointercancel",o),e.addEventListener("lostpointercapture",o)})};i&&n(i,()=>t=>{const{t:i}=this.mouseInSlider(t);e.startTime=e.endTime===1/0?i:Math.min(i,e.endTime)}),s&&n(s,()=>t=>{const{t:i}=this.mouseInSlider(t);e.endTime=e.startTime===-1/0?i:Math.max(i,e.startTime)}),n(t,t=>{const i=this.mouseInSlider(t).t,s=e.startTime,n=e.endTime;return t=>{const l=this.mouseInSlider(t).t-i;s===-1/0&&n!==1/0?e.endTime=n+l:n===1/0&&s!==-1/0?e.startTime=s+l:s!==-1/0&&n!==1/0&&(e.startTime=s+l,e.endTime=n+l)}})}startSelectingRange(e){this.selectingRange=!0,this.whenDoneSelectingRange=e}stopSelectingRange(){this.selectingRange=!1,this.whenDoneSelectingRange?.(),this.whenDoneSelectingRange=void 0,this.selectingRangeVisible&&(this.container.removeChild(this.selectingRangeElement),this.selectingRangeVisible=!1)}syncMaxValues(){return this.updateAllValueRanges(),this.on("time",()=>this.updateAllValueRanges())}syncMaxValuesForLayer(e){return this.updateValueRanges(e.yAxisGroup),e.model.on(()=>this.updateValueRanges(e.yAxisGroup))}updateAllValueRanges(){this.layers.filter(e=>e.visible).forEach(e=>{this.updateValueRanges(e.yAxisGroup,!0)}),this.renderYAxis()}updateValueRanges(e,t){this.updateValueRangesQueue.has(e)||this.updateValueRangesQueue.set(e,{lastUpdate:0,pending:void 0});const i=this.updateValueRangesQueue.get(e);if(Date.now()-i.lastUpdate<100)return i.pending&&clearTimeout(i.pending),void(i.pending=setTimeout(()=>{i.pending=void 0,this.updateValueRanges(e)},200));i.lastUpdate=Date.now();const s=new Map,n=new Map;this.layers.filter(e=>e.visible).forEach(e=>{const t=e.yAxis.group||e.id;s.has(t)||(s.set(t,-Number.MAX_VALUE),n.set(t,Number.MAX_VALUE));const i=e.model.getValueRange(this.getTimeRange());i.minValue<n.get(t)&&n.set(t,i.minValue),i.maxValue>s.get(t)&&s.set(t,i.maxValue)}),this.valueRanges.clear(),s.forEach((e,t)=>{this.valueRanges.set(t,{max:e,min:n.get(t)})}),t||this.renderYAxis(),this.emit("valueRanges",e)}renderYAxis(){const e=new Map;this.layers.filter(e=>e.visible).forEach(t=>{const i=t.yAxis.group||t.id;e.has(i)||e.set(i,{min:t.min,max:t.max,group:i}),e.set(i,{...e.get(i),...t.yAxis,min:t.min,max:t.max,direction:this.isHangingDown(t)?"down":"up"})});const t=[];e.forEach(e=>{if(e.visible){const i=this.valueRanges.get(e.group);i&&t.push({...e,minValue:i.min,maxValue:i.max})}});const i=this.getVisibleLayers().filter(e=>e.baseline).map(e=>({y:this.isHangingDown(e)?e.max:e.min,color:e.baseline.color,width:e.baseline.width??1}));this.yAxisTicks.render(t,{gridBehind:"behind"===this._gridOrder,baselines:i})}setTheme(e){this.theme=e,this.updateBehindLayers(),this.ticksBar.setDarkMode("dark"===e),this.engine?.setTheme(e)}addLayerLoader(e){this.loaders.add(e)}showStats(e){this.showingStats=e,this.engine?.showStats(e)}get engineReady(){return this._engineReady}whenReady(){return this._engineReady?Promise.resolve():new Promise(e=>{const t=this.on("ready",()=>{t(),e()})})}async setEngine(e){this._engineReady=!1,this.engine&&(this.layerUnloaders.forEach(e=>e()),this.layerUnloaders.clear(),this.engine.dispose()),this.initSliderContainer(),this.engine=e,this.engine.setTheme(this.theme),this.engine.setBackground(this._background),await this.engine.init(this.sliderElement),this.engine.setTheme(this.theme),this._engineReady=!0,this.emit("ready"),this.getVisibleLayers().forEach(e=>this.loadLayer(e)),this.engine.showStats(this.showingStats),this.engine.setTimeRange(this.getTimeRange()),this.engine.setValueRange(this.getValueRange()),this.engine.setSize(this.size.width,this.size.height),this.attachBehindCanvas(),this.updateBehindLayers(),this.renderYAxis()}initSliderContainer(){this.stopControls&&this.stopControls(),this.container?.removeChild(this.sliderElement);let e=0;this.showTicks&&(e+=24),this.showCurrent&&(e+=4),this.sliderElement=document.createElement("div"),this.sliderElement.oncontextmenu=()=>!1,this.sliderElement.tabIndex=0,this.sliderElement.style.top="0px",this.sliderElement.style.width="100%",this.sliderElement.style.outline="none",this.sliderElement.style.touchAction="none",this.sliderElement.style.height=`calc(100% - ${0+e}px)`,this.container?.appendChild(this.sliderElement),this.initSelectLabel(),this.stopControls=this.initControls(),this.onDestroy.push(()=>{this.container?.removeChild(this.sliderElement)})}get showCurrent(){return this._showCurrent}set showCurrent(e){if(e!==this._showCurrent){this._showCurrent=e,this.ticksBar.showLine=!this.showCurrent;let t=0,i=0;this.showTicks&&(i+=24),this.showCurrent&&(i+=4),this.sliderElement.style.height=`calc(100% - ${t+i}px)`,this.yAxisTicks.behindCanvas.style.height=this.sliderElement.style.height}}async init(e,t){const i="string"==typeof e?document.getElementById(e):e;if(this.container=i,i){i.oncontextmenu=()=>!1;let e=0,s=0;if(this.showTicks){s+=24;const e=document.createElement("div");e.style.width="100%",e.style.height="24px",e.style.position="absolute",e.style.bottom="0px",e.style.touchAction="none",i.appendChild(e),this.ticksBar.init(e,e=>{const t=d(e.startTime,e.endTime);this.emit("tickclick",{startTime:e.startTime,endTime:e.endTime,unit:t}),this.fit({range:e,animate:1e3})}),this.ticksBar.showLine=!this.showCurrent}this.showCurrent&&(s+=4),this.sliderElement.oncontextmenu=()=>!1,this.sliderElement.tabIndex=0,this.sliderElement.style.top=`${e}px`,this.sliderElement.style.width="100%",this.sliderElement.style.outline="none",this.sliderElement.style.touchAction="none",this.sliderElement.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.sliderElement),i.style.isolation="isolate",this.yAxisTicks.canvas.style.zIndex="2",this.selectionOverlayContainer.style.zIndex="3",this.columnBandOverlayContainer.style.zIndex="3",this.yAxisTicks.canvas.style.top=`${e}px`,this.yAxisTicks.canvas.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.yAxisTicks.canvas),this.selectionOverlayContainer.style.position="absolute",this.selectionOverlayContainer.style.width="100%",this.selectionOverlayContainer.style.overflow="hidden",this.selectionOverlayContainer.style.pointerEvents="none",this.selectionOverlayContainer.style.top=`${e}px`,this.selectionOverlayContainer.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.selectionOverlayContainer),this.onDestroy.push(()=>i.removeChild(this.selectionOverlayContainer)),this.columnBandOverlayContainer.style.position="absolute",this.columnBandOverlayContainer.style.width="100%",this.columnBandOverlayContainer.style.overflow="hidden",this.columnBandOverlayContainer.style.pointerEvents="none",this.columnBandOverlayContainer.style.top=`${e}px`,this.columnBandOverlayContainer.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.columnBandOverlayContainer),this.onDestroy.push(()=>i.removeChild(this.columnBandOverlayContainer)),this.initHoverTooltip(),this.initTickTooltip(),this.watchFontLoading(),this.watchPixelRatio(),this.initSelectLabel(),this.setSize(this.sliderElement.clientWidth,this.sliderElement.clientHeight),this.syncSize(),this.setTimeRange(Y(t)),this.setValueRange(Y(t))}else console.warn(`Element ${e} not found`)}initSelectLabel(){this.selectedLabel.style.position="absolute",this.applyTooltipStyle(this.selectedLabel,"200px"),this.selectedLabel.style.pointerEvents="none",this.selectedLabel.style.display="none",this.selectedLabel.style.zIndex="10",this.sliderElement.appendChild(this.selectedLabel)}getLabel(e,t,i,s){if(t.labeler){const n=t.labeler(e,i,s);return null===n?null:"string"==typeof n?`<div>${n}</div>`:n?n.outerHTML:`<div>${e.name||e.id}</div>`}return`<div>${e.name||e.id}</div>`}getLayerById(e){return this.layers.find(t=>t.id===e)}select(e,t){this.stopSelectingRange(),this.stopUpdatingLabel?.();const i=()=>{this.updatingLabel=!1,this.stopUpdatingLabel?.(),this.stopUpdatingLabel=void 0,this.selectedLabel.style.display="none",this.layers.forEach(e=>e.select([])),this.selectedLayerId=void 0,this.emit("select",[])},s=e=>{this.layers.filter(t=>!e.some(e=>t.id===e.layer.id)).forEach(e=>e.select([])),e.forEach(e=>{e.layer.select(e.elements)}),this.emit("select",e)};if(t){s(this.getVisibleLayers().map(e=>{const i=e.model.dataInTimeRange(t);return{layer:e,elements:i}}).filter(e=>e.elements.length>0))}else if(e){const t=this.findElements(e,24);if(s(t.map(e=>({layer:e.layer,elements:e.elements})).flat()),1===t.length&&t[0].elements.length>0&&this.selectionOptions.label){const e=t[0].elements[0],s=t[0].layer;this.selectedLabel.innerHTML=this.getLabel(e,s,t[0].t,t[0].v)||"",this.selectedLabel.style.display="block";const n=this.selectedLabel.offsetWidth,l=this.selectedLabel.offsetHeight;this.selectedLayerId=s.id;const o=Array.isArray(e.t);this.updatingLabel=!0;const a=()=>{if(!this.updatingLabel)return;const{startTime:i,duration:s,endTime:a}=this.getTimeRange(),r=t[0].layer.model.get(e.id);if(r){const e=x(this.getTimeRange(),r.t);if(e){const a=this.getSliderBounds();let h=(.5*(e.startTime+e.endTime)-i)/s*a.width;const d="number"==typeof r.v?r.v:.5*(r.v[1]+r.v[0]);let m=this.modelValueToPixels(d,t[0].layer);o?m-=.5*l:m+=8;const c=.5*n,g=.5*l,u=a.width-.5*n,p=a.height-.5*l,y=Math.min(u,Math.max(c,h)),T=Math.min(p,Math.max(g,m));this.selectedLabel.style.display="block",this.selectedLabel.style.left=y-.5*n+"px",this.selectedLabel.style.top=`${T}px`}else this.selectedLabel.style.display="none"}else this.selectedLabel.style.display="none"};a();const r=s instanceof R&&s.histogram instanceof g;this.stopUpdatingLabel=this.on("time",r?i:a)}}else i()}listenToClicks(){let e=null;const t=t=>{e={x:t.clientX,y:t.clientY}},i=t=>{if(!e)return;const i=t.clientX-e.x,s=t.clientY-e.y;i*i+s*s<=25&&(this.stopSelectingRange(),this.select(e)),e=null},s=()=>{e=null};return this.sliderElement.addEventListener("pointerdown",t),this.sliderElement.addEventListener("pointerup",i),this.sliderElement.addEventListener("pointercancel",s),()=>{this.sliderElement.removeEventListener("pointerdown",t),this.sliderElement.removeEventListener("pointerup",i),this.sliderElement.removeEventListener("pointercancel",s)}}getSliderBounds(){return this.sliderElement.getBoundingClientRect()}mouseInSlider(e){const t=this.getSliderBounds(),i="x"in e?e:{x:e.clientX,y:e.clientY},s={x:i.x-t.left,y:i.y-t.top},n={x:s.x/t.width,y:-s.y/t.height+1},{startTime:l,duration:o}=this.getTimeRange(),a=l+n.x*o,{minValue:r,maxValue:h}=this.getValueRange();return{absolute:s,normalized:n,t:a,v:r+n.x*(h-r)}}pixelsToLayerValue(e,t){if(!e)return{yInLayer:0,toLayerHeight:1};const i="normalized"in e?e.normalized:this.mouseInSlider(e).normalized;let s=t.min,n=t.max;const l=n-s;return{yInLayer:this.isHangingDown(t)?(n-i.y)/l:(i.y-s)/l,toLayerHeight:l/this.getSliderBounds().height}}isHangingDown(e){return"down"===e.direction&&(e instanceof w||(this.warnedDirection.has(e.id)||(this.warnedDirection.add(e.id),console.warn("Layer direction 'down' is only supported for bar (intervals / histogram) layers, ignoring it for",e.name)),!1))}pixelsToModelValue(e,t){const{yInLayer:i,toLayerHeight:s}=this.pixelsToLayerValue(e,t);let n=0,l=100;if(t.model instanceof p){const e=this.valueRanges.get(t.yAxisGroup)||{min:0,max:1e3};n=e.min,l=e.max-n}return{yInModel:n+i*l,toModelHeight:s*l}}layerValueToPixels(e,t){let i=t.min,s=t.max;const n=s-i,l=this.getSliderBounds().height;return(1-(this.isHangingDown(t)?s-n*e:i+n*e))*l}modelValueToPixels(e,t){let i=0,s=100;if(t.model instanceof p){const e=t.model.getValueRange(this.getTimeRange());i=e.minValue,s=e.maxValue-i}const n=(e-i)/s;return this.layerValueToPixels(n,t)}findElements(e,t){if("column"===this.selectionOptions.pick)return this.findColumnElements(e);const{width:i,height:s}=this.getSliderBounds(),{normalized:n}=this.mouseInSlider(e),{startTime:l,endTime:o,duration:a}=this.getTimeRange(),r=l+n.x*a,h=t||12,d=h/i*a,m={startTime:r-1,endTime:r+1},c={startTime:r-.5*d,endTime:r+.5*d};return this.getVisibleLayers().map(e=>{const{yInModel:t,toModelHeight:i}=this.pixelsToModelValue({normalized:n},e),s=e instanceof w?0:h*i,l=e instanceof w?m:c,o={minValue:t-.5*s,maxValue:t+.5*s},a=e.model.dataInRange({...l,...o});return{layer:e,elements:a,t:r,v:t}}).filter(e=>e.elements.length>0)}findColumnElements(e,t){const{width:i}=this.getSliderBounds(),{normalized:s}=this.mouseInSlider(e),{startTime:n,duration:l}=this.getTimeRange(),o=n+s.x*l,a=(t||12)/i*l,r={startTime:o-1,endTime:o+1},h={startTime:o-.5*a,endTime:o+.5*a};return this.getVisibleLayers().map(e=>{const{yInModel:t}=this.pixelsToModelValue({normalized:s},e),i=e instanceof w?r:h,n=e.model.dataInTimeRange(i);return{layer:e,elements:n,t:o,v:t}}).filter(e=>e.elements.length>0)}clearHoverEvent(){this.hoverCleared||(this.hoverCleared=!0,this.renderColumnHoverBand([]),this.emit("hover",null))}updateHover(e){if(this.dragging)return this.hoverLine.style.display="none",this.toolTip.style.display="none",void this.clearHoverEvent();if(void 0!==e&&(this.mouse=e),this.mouse){const e=this.getSliderBounds(),{normalized:t}=this.mouseInSlider(this.mouse),{startTime:i,endTime:s,duration:l}=this.getTimeRange(),o=i+t.x*l,a=this.findElements(this.mouse);this.renderColumnHoverBand(a),this.hoverCleared=!1,this.emit("hover",{elements:a.map(e=>({layer:e.layer,elements:e.elements})),t:o,clientX:this.mouse.x,clientY:this.mouse.y});const r=a.map(e=>e.elements.map(t=>({e:t,l:e.layer,t:e.t,v:e.v}))).flat();let h;if(r.length>0)if(r.length>3){h=r.slice(0,2).map(e=>this.getLabel(e.e,e.l,e.t,e.v)).flat().filter(e=>null!==e).join(""),h+=`<div>And ${r.length-2} more...</div>`}else{h=a.map(e=>e.elements.map(t=>this.getLabel(t,e.layer,e.t,e.v))).flat().filter(e=>null!==e).join("")}if(!1===this.hoverOptions.tooltip)this.toolTip.style.display="none";else{const t=new Date(o),i=t.getHours(),s=t.getMinutes(),l=t.getSeconds(),a=n(o,!0,this._locale),r=`${(i<10?"0":"")+i}:${(s<10?"0":"")+s}:${(l<10?"0":"")+l}`;let d="";const m=this.ticksBar.cache.high.spacing;(void 0===this.hoverOptions.date?m>=B:this.hoverOptions.date)&&(d+=`<div>${a}</div>`),(void 0===this.hoverOptions.time?m<=V:this.hoverOptions.time)&&(d+=`<div>${r}</div>`),h&&(d+=h),this.toolTip.innerHTML=d,this.toolTip.style.display=d.length>0?"block":"none";const c=88,g=36;let u=this.mouse.x+10,p=this.mouse.y+10;const y=e.left+e.width-c-5,T=e.top+e.height-g-5;u>y&&(u=y),p>T&&(p=T),this.toolTip.style.left=`${u}px`,this.toolTip.style.top=`${p}px`}}else this.hoverLine.style.display="none",this.toolTip.style.display="none",this.clearHoverEvent()}initHoverTooltip(){this.toolTip.style.position="fixed",this.applyTooltipStyle(this.toolTip),this.toolTip.style.pointerEvents="none",this.toolTip.style.display="none",this.toolTip.style.zIndex="10",this.toolTip.style.overflow="hidden",document.body.appendChild(this.toolTip),this.onDestroy.push(()=>this.toolTip.remove())}initTickTooltip(){this.tickToolTip.style.position="fixed",this.applyTooltipStyle(this.tickToolTip),this.tickToolTip.style.pointerEvents="none",this.tickToolTip.style.display="none",this.tickToolTip.style.zIndex="10",this.tickToolTip.style.whiteSpace="pre-line",document.body.appendChild(this.tickToolTip),this.onDestroy.push(()=>this.tickToolTip.remove())}initHoverListener(){const e=()=>{this.updateHover(null)},t=e=>{this.updateHover({x:e.clientX,y:e.clientY})};this.sliderElement.addEventListener("mouseleave",e),this.sliderElement.addEventListener("mousemove",t);const i=this.listenToClicks();return()=>{this.sliderElement.removeEventListener("mouseleave",e),this.sliderElement.removeEventListener("mousemove",t),i()}}syncSize(){const e=()=>{const{offsetWidth:e,offsetHeight:t}=this.sliderElement;this.setSize(e,t)},t=new ResizeObserver(()=>{e()});this.container&&(t.observe(this.container),e()),this.onDestroy.push(()=>{t.disconnect()})}getTimeRange(){return y(this.range.time)}getValueRange(){return this.range.value}setTimeRange(e,t){const i=this.getTimeRange(),s=v(i,e),n=this._limits?f(s,this._limits):s;n.startTime===i.startTime&&n.endTime===i.endTime||(this.range.time=n,this.engine?.setTimeRange(n),this.showTicks&&this.ticksBar.setTimeRange(n),this.emit("time",n),this.updateHover())}setValueRange(e){const t={...this.getValueRange(),...e};this.range.value=t,this.engine?.setValueRange(t),this.emit("value",this.getValueRange()),this.updateHover()}setSize(e,t){this.size={width:e,height:t},this.showTicks&&this.ticksBar.setWidth(e);const i=this.getTimeRange(),s=this.getValueRange();this.engine?.setSize(e,t),this.setTimeRange(i),this.setValueRange(s),this.renderYAxis(),this.updateHover(),this.emit("size",{width:e,height:t})}up(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange();let n={startTime:0,endTime:Date.now()};const l=.5*(t+i);if(s>=.9*C){const e=X(10*s);n=h(l,e)}else{const e=[{threshold:S,unit:"millennium"},{threshold:k,unit:"century"},{threshold:_,unit:"decade"},{threshold:.9*D,unit:"year"},{threshold:O,unit:"month"},{threshold:V,unit:"week"},{threshold:B,unit:"day"},{threshold:M,unit:"hour"},{threshold:z,unit:"minute"},{threshold:-1,unit:"second"}];let t=0;for(;s<.9*e[t].threshold;)t++;const i=e[t].unit;n=m(l,i)}this.fit({...e,range:n})}down(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange();let n={startTime:0,endTime:Date.now()};const l=t+("number"==typeof e?.xRatio?e.xRatio:.5)*s;if(s>=.9*C){const e=X(s/10);n=h(l,e)}else{let e=0;const t=[{threshold:C,unit:"century"},{threshold:S,unit:"decade"},{threshold:k,unit:"year"},{threshold:_,unit:"month"},{threshold:1.1*D,unit:"week"},{threshold:O,unit:"day"},{threshold:V,unit:"hour"},{threshold:B,unit:"minute"},{threshold:M,unit:"second"}].reverse();for(;s>1.1*t[e].threshold;)e++;const i=t[e].unit;n=m(l,i)}this.fit({...e,range:n})}next(e){this.skip(1,e)}previous(e){this.skip(-1,e)}skip(e,t){this.fit({...t,range:this.getSkipRange(e)})}getSkipRange(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange(),n=.5*(t+i);if(s>=9*C){const e=X(s);return h(n,e)}const l=d(t,i);return l?m(n,l,Math.round(e)):{startTime:t+e*s,endTime:i+e*s}}clampToLimits(e){return this._limits?f(e,this._limits):e}describeStep(e){const t=this.getTimeRange(),i=this.getSkipRange(e),n=this.clampToLimits(i),l=Math.abs(n.startTime-t.startTime)>j||Math.abs(n.endTime-t.endTime)>j,o=l?n:i,a=e>0?s(t.startTime,o.startTime,this._locale):s(o.startTime,t.startTime,this._locale);return{range:n,canStep:l,span:a,label:K(e,a,this._locale)}}canStep(e){return this.describeStep(e).canStep}describeSpan(e){const{startTime:t,endTime:i}=e??this.getTimeRange(),n=s(t,i,this._locale);return{text:n.text,exact:n.exact,dates:a(t,i,this._locale)}}isFitted(e){const t=this.clampToLimits(e??this.getLayersTimeRange()),i=this.getTimeRange(),s=Math.max(j,.001*(t.endTime-t.startTime));return Math.abs(i.startTime-t.startTime)<=s&&Math.abs(i.endTime-t.endTime)<=s}getTimeRangeLabel(){const{startTime:e,endTime:t}=this.getTimeRange(),i=new Date(e);return 0===i.getHours()&&0===i.getMinutes()&&0===i.getSeconds()&&0===i.getMilliseconds()?l([e,t],this._locale):void 0}cancelFit(){this.stopFit?.(),this.stopFit=void 0}fit(e){this.cancelFit();const t=e?.range||this.getLayersTimeRange(),s=e?.padding?T(t,e.padding):t;if(e?.animate){const t=this.getTimeRange();this.stopFit=i(t.startTime,t.endTime,s.startTime,s.endTime,e.animate,(e,t)=>this.setTimeRange({startTime:e,endTime:t}))}else this.setTimeRange(s)}getLayersTimeRange(){if(0===this.getVisibleLayers().length)return A;{let e=this.getVisibleLayers()[0].model.getTimeRange();return this.getVisibleLayers().slice(1).forEach(t=>e=L(e,t.model.getTimeRange())),e}}loadLayer(e){if(e.timeSlider&&e.timeSlider.id!==this.id)console.warn("Layer already has been loaded by another time slider, create a new layer with the same model and style if you want to add it to another time slider");else if(this.engine&&this._engineReady&&!this.layerUnloaders.has(e.id)){const t=[...this.loaders].filter(e=>this.engine instanceof e.engineClass).find(t=>t.canLoad(e));if(t){const i=Date.now(),s=t.load(e,this.engine.scene,this.engine,this);e.timeSlider=this,e.loaded=!0;const n=e.name||e.constructor.name+"#"+e.id.slice(e.id.length-4).toUpperCase();console.log(`Loaded ${n} in ${o(Date.now()-i)}`);const l=this.syncMaxValuesForLayer(e);this.layerLoaders.set(e.id,t),this.layerUnloaders.set(e.id,()=>{l(),s(),this.layerLoaders.delete(e.id),e.loaded=!1})}else console.warn("No loader found for",{layer:e})}}unloadLayer(e){this.selectedLayerId===e.id&&this.select(null),this.layerUnloaders.has(e.id)&&(this.layerUnloaders.get(e.id)(),this.layerUnloaders.delete(e.id))}addLayer(e){if(this.layers.push(e),e.visible){this.loadLayer(e);const t=e.model.getTimeRange();if(1===this.getVisibleLayers().length)this.setTimeRange(t);else{const e=L(this.getTimeRange(),t);this.setTimeRange(e)}}const t=[e.on("visible",()=>{e.visible?this.loadLayer(e):this.unloadLayer(e),this.updateAllValueRanges(),this.updateBehindLayers()}),e.on("min",()=>this.onLayerBandChange(e)),e.on("max",()=>this.onLayerBandChange(e)),e.on("direction",()=>this.onLayerBandChange(e)),e.on("baseline",()=>{this.updateBehindLayers(),this.renderYAxis()})];this.layerListenerStoppers.set(e.id,()=>t.forEach(e=>e())),this.updateBehindLayers(),this.renderYAxis()}onLayerBandChange(e){const t=this.layerLoaders.get(e.id);t&&!t.followsLayerBand&&(this.layerUnloaders.get(e.id)?.(),this.layerUnloaders.delete(e.id),this.loadLayer(e)),this.updateAllValueRanges()}removeLayer(e){const t="string"==typeof e?e:e.id,i=this.layers.find(e=>e.id===t);i&&(this.unloadLayer(i),this.layerUnloaders.delete(t),this.layerListenerStoppers.get(t)?.(),this.layerListenerStoppers.delete(t),this.layers=this.layers.filter(e=>e.id!==t),this.updateBehindLayers(),this.renderYAxis())}destroy(){this.layers.map(e=>e.id).forEach(e=>this.removeLayer(e)),this.onDestroy.forEach(e=>e())}addHorizontalPinchZoom(){let e=null,t=null;const i=()=>{this.pinching=!1,e=null,t=null},s=i=>{if(2===i.touches.length){i.preventDefault(),this.dragging=!1,this.pinching=!0;const s=this.mouseInSlider(i.touches[0]).t,n=this.mouseInSlider(i.touches[1]).t;e=Math.min(s,n),t=Math.max(s,n)}},n=s=>{if(2===s.touches.length){if(null===e||null===t)return;s.preventDefault(),this.dragging=!1;const i=this.mouseInSlider(s.touches[0]).normalized.x,n=this.mouseInSlider(s.touches[1]).normalized.x,l=Math.min(i,n),o=Math.max(i,n),a=(t-e)/(o-l);let r=e-l*a,h=t+(1-o)*a;if(a>P){const e=.5*(r+h);r=e-.5*P,h=e+.5*P}if(a<U){const e=.5*(r+h);r=e-.5*U,h=e+.5*U}this.setTimeRange({startTime:r,endTime:h})}else i()},l=()=>{i()};this.sliderElement.addEventListener("touchstart",s,{passive:!1}),this.sliderElement.addEventListener("touchmove",n,{passive:!1}),this.sliderElement.addEventListener("touchend",l),this.sliderElement.addEventListener("touchcancel",l),this.onDestroy.push(()=>{this.sliderElement.removeEventListener("touchstart",s),this.sliderElement.removeEventListener("touchmove",n),this.sliderElement.removeEventListener("touchend",l),this.sliderElement.removeEventListener("touchcancel",l)})}initControls(){const e=new t;this.dragging=!1;let i,s=0,n=0,l=0;e.add(this.initHoverListener());const o=e=>{this.sliderElement.focus(),e.preventDefault();const t=this.mouseInSlider(e);this.zoom(.001*e.deltaY,{x:t.normalized.x})};let a=0,r=-1;const h=e=>{const t=Date.now(),i=t-a;r>=0&&i<300&&i>0&&(this.select(null),e.preventDefault(),this.zoom(-.75,{animate:1e3,x:r})),a=t},d=e=>{e.preventDefault(),this.select(null);const t=this.mouseInSlider(e);this.zoom(-.75,{animate:1e3,x:t.normalized.x})};this.selectingRangeElement.style.pointerEvents="none",this.selectingRangeElement.style.position="absolute",this.selectingRangeElement.style.top="0px";const m=e=>{if(this.sliderElement.focus(),2===e.button||0===e.button){e.preventDefault();const t=this.mouseInSlider(e),i=t.normalized.x,{startTime:o,duration:a}=this.getTimeRange();s=o+i*a,n=Date.now(),l=t.absolute.x,(e.ctrlKey||2===e.button)&&(this.selectingRange=!0),this.selectingRange?(this.selectingRangeElement.style.left=t.absolute.x+"px",this.selectingRangeElement.style.width="0px",this.selectingRangeElement.style.top=this.sliderElement.style.top||"0px",this.selectingRangeElement.style.height=this.sliderElement.style.height||"100%",this.container.appendChild(this.selectingRangeElement),this.selectingRangeVisible=!0):this.dragging=!0}},c=e=>{const t=this.mouseInSlider(e);return i=t.normalized.x,t},g=e=>{const t=c(e);if(this.selectingRange){const e=Math.abs(l-t.absolute.x),i=Math.min(l,t.absolute.x);this.selectingRangeElement.style.left=i+"px",this.selectingRangeElement.style.width=e+"px"}if(!this.dragging||Date.now()-n<100&&Math.abs(l-t.absolute.x)<10)return;e.preventDefault();const i=t.normalized.x,{startTime:o,endTime:a}=this.getTimeRange(),r=o+i*(a-o)-s;this.setTimeRange({startTime:o-r,endTime:a-r})},u=e=>{const t=this.getSliderBounds(),n=t.height-(e.clientY-t.top);if(!this.dragging&&!this.pinching&&n<8)this.ticksBar.click(e);else if(i=void 0,this.dragging=!1,this.selectingRange){const t=this.mouseInSlider(e).normalized.x,{startTime:i,endTime:n}=this.getTimeRange(),l=i+t*(n-i);"zoom"===this.selectRangeMode&&this.fit({range:{startTime:Math.min(s,l),endTime:Math.max(s,l)},animate:1e3}),"select"===this.selectRangeMode&&this.select(null,{startTime:Math.min(s,l),endTime:Math.max(s,l)}),"createSelection"===this.selectRangeMode&&this.setSelection([...this.getSelection(),{startTime:Math.min(s,l),endTime:Math.max(s,l)}])}this.stopSelectingRange()},p=e=>{this.pressedKeys.add(e.code)},y=e=>{this.pressedKeys.delete(e.code),"Space"===e.code&&(e.preventDefault(),this.togglePlaying()),"KeyF"===e.code&&(e.preventDefault(),this.fit({animate:3e3}));const t=void 0;"ArrowRight"===e.code&&(e.preventDefault(),this.skip(1,{animate:t})),"ArrowLeft"===e.code&&(e.preventDefault(),this.skip(-1,{animate:t})),"ArrowUp"===e.code&&(e.preventDefault(),this.up({animate:t})),"ArrowDown"===e.code&&(e.preventDefault(),this.down({xRatio:i,animate:t}))};let T=!0;const v=()=>{if(T){const e=this.pressedKeys.has("ShiftLeft")?.05:.01,t=2*e,s=this.pressedKeys.has("KeyD"),n=this.pressedKeys.has("KeyA");s&&this.shift(-e),n&&this.shift(e),this.pressedKeys.has("KeyW")&&this.zoom(-t,{x:s||n?void 0:i}),this.pressedKeys.has("KeyS")&&this.zoom(t,{x:s||n?void 0:i}),requestAnimationFrame(v)}};v(),e.add(()=>T=!1);const f=e=>e.preventDefault();this.sliderElement.addEventListener("contextmenu",f),this.sliderElement.addEventListener("wheel",o),this.sliderElement.addEventListener("pointerdown",m),this.sliderElement.addEventListener("pointermove",g),this.sliderElement.addEventListener("pointerup",u),this.sliderElement.addEventListener("dblclick",d),this.sliderElement.addEventListener("touchend",h),this.sliderElement.addEventListener("touchstart",e=>{if(1===e.touches.length){const t=this.mouseInSlider(e.touches[0]);r=t.normalized.x}else r=-1}),this.sliderElement.addEventListener("keydown",p),this.sliderElement.addEventListener("keyup",y),this.addHorizontalPinchZoom();const E=()=>{this.sliderElement.removeEventListener("contextmenu",f),this.sliderElement.removeEventListener("wheel",o),this.sliderElement.removeEventListener("pointerdown",m),this.sliderElement.removeEventListener("pointermove",g),this.sliderElement.removeEventListener("pointerup",u),this.sliderElement.removeEventListener("dblclick",d),this.sliderElement.removeEventListener("touchend",h),this.sliderElement.removeEventListener("keydown",p),this.sliderElement.removeEventListener("keyup",y)};return this.onDestroy.push(E),e.add(E),e.disposeLater()}shift(e,t){const{startTime:i,endTime:s,duration:n}=this.getTimeRange(),l=t?.absolute?e:e*n;this.fit({...t,range:{startTime:i-l,endTime:s-l}})}zoom(e,t){const i="number"==typeof t?.x?t.x:.5,{startTime:s,endTime:n,duration:l}=this.getTimeRange(),o={startTime:s-e*l*i,endTime:n+e*l*(1-i)},a=o.endTime-o.startTime,r=o.startTime+.5*a;a>P&&(o.startTime=r-.5*P,o.endTime=r+.5*P),a<U&&(o.startTime=r-.5*U,o.endTime=r+.5*U),this.fit({range:o,animate:t?.animate})}togglePlaying(){this.playing?this.pause():this.play()}isPlaying(){return this.playing}play(){if(this.playing)return;this.playing=!0,this.emit("playing",!0);let e=Date.now();const t=()=>{if(this.playing){if(this.live){const{duration:e}=this.getTimeRange(),t=Date.now(),i=10/this.size.width;this.setTimeRange({startTime:t-(1-i)*e,endTime:t+i*e}),this.setCurrent(t)}else if("auto"!==this.playSpeed||this.showCurrent){const t=Date.now(),i=t-e,s=this.current-this.getTimeRange().startTime,n="auto"===this.playSpeed?1:this.playSpeed;this.shift(-n*i,{absolute:!0}),this.setCurrent(this.getTimeRange().startTime+s),e=t}else{const t=Date.now();let i=5e-5*(t-e);this.pressedKeys.has("ShiftLeft")&&(i*=5);const s=this.current-this.getTimeRange().startTime;this.shift(-i),this.setCurrent(this.getTimeRange().startTime+s),e=t}requestAnimationFrame(t)}};t()}setCurrent(e){this.current!==e&&(Math.abs(e-Date.now())>100&&this.live&&(this.pause(),this.setLive(!1)),this.current=e,this.emit("current",e))}pause(){this.playing&&(this.playing=!1,this.emit("playing",!1),this.setLive(!1))}setLive(e){if(this.live!==e){if(this.live=e,e){const e=this.getTimeRange();this.fit({range:{startTime:e.endTime-this.liveRange,endTime:e.endTime},animate:z}),this.play()}this.emit("live",e)}}}function Y(e){return{startTime:"number"==typeof e?.startTime?e.startTime:"number"==typeof e?.endTime?e.duration?e.endTime-e.duration:e.endTime-V:e?.duration?Date.now()-.5*e.duration:Date.now()-.5*V,endTime:"number"==typeof e?.endTime?e.endTime:"number"==typeof e?.startTime?e.duration?e.startTime+e.duration:e.startTime+V:e?.duration?Date.now()+.5*e.duration:Date.now()+.5*V,duration:e?.duration?e.duration:"number"==typeof e?.startTime&&"number"==typeof e?.endTime?e.endTime+e.startTime:V,minValue:"number"==typeof e?.minValue?e.minValue:"number"==typeof e?.maxValue?e.maxValue>0?0:e.maxValue-100:0,maxValue:"number"==typeof e?.maxValue?e.maxValue:"number"==typeof e?.minValue?e.minValue<0?0:e.minValue+100:100}}const j=z,W={en:{next:"Next {span}",previous:"Previous {span}",nextUnit:"Next {unit}",previousUnit:"Previous {unit}"},de:{next:"Weiter: {span}",previous:"Zurück: {span}"},fr:{next:"Suivant : {span}",previous:"Précédent : {span}"},nl:{next:"Volgende: {span}",previous:"Vorige: {span}"}};function K(e,t,i){const s=W[i.split("-")[0].toLowerCase()];if(!s)return(e>0?"→ ":"← ")+t.text;const n=e>0?s.nextUnit:s.previousUnit;return n&&t.unitName?n.replace("{unit}",t.unitName):(e>0?s.next:s.previous).replace("{span}",t.text)}function X(e){const t=e/315576e5,i=Math.log10(t),s=Math.ceil(i);return Math.pow(10,s)}
1
+ import{v4 as e}from"uuid";import{Disposables as t}from"../common/Disposables.js";import{animateRangeTransition as i}from"../common/Easing.js";import{describeTimeSpan as s,formatDate as n,formatDateRange as l,formatDuration as o,formatTimeSpanDates as a,getDefaultLocale as r,getLargeTimeUnitRange as h,getMatchingTimeUnit as d,getTimeUnitRange as c,setDefaultLocale as m}from"../common/TimeTools.js";import{TimeSliderDynamicHistogram as g}from"../data/histogram/TimeSliderDynamicHistogram.js";import{getTimeArray as u}from"../data/TimeSliderElement.js";import{TimeSliderIntervalsModel as p}from"../data/TimeSliderIntervalsModel.js";import{addDuration as y,addPadding as T,applyTimeRangeUpdate as v,clampTimeRange as f,mergeTimeRanges as x,timeRangesOverlap as E,timeRangesUnion as b}from"../data/TimeSliderRange.js";import{TypedEventEmitter as w}from"../event/TypedEventEmitter.js";import{TimeSliderHistogramLayer as L}from"../layer/TimeSliderHistogramLayer.js";import{TimeSliderIntervalsLayer as R}from"../layer/TimeSliderIntervalsLayer.js";import{CENTURY as S,DECADE as k,MILLENIUM as C,ONE_DAY as M,ONE_HOUR as B,ONE_MINUTE as V,ONE_MONTH as O,ONE_SECOND as _,ONE_WEEK as D,ONE_YEAR as I,TODAY as z}from"../ticks/TimeSliderConstants.js";import{TimeTicksBar as A}from"../ticks/TimeTicksBar.js";import{YAxisTicks as H}from"../ticks/YAxisTicks.js";import{resolveFont as $,toCssFont as F}from"../common/Font.js";import{getDevicePixelRatio as U}from"../common/Pixels.js";const P={idle:{fill:"rgba(100, 180, 255, 0.15)",border:{color:"rgba(100, 180, 255, 0.8)",width:1,style:"solid"},handle:{color:"rgba(100, 180, 255, 0.9)",width:0,look:"bar"}},editing:{fill:"rgba(100, 180, 255, 0.15)",border:{color:"rgba(100, 180, 255, 0.8)",width:2,style:"solid"},handle:{color:"rgba(100, 180, 255, 0.9)",width:4,look:"bar"}},drawing:{fill:"#df04",border:{color:"#df0",width:3,style:"solid"},handle:{color:"#df0",width:0,look:"bar"}}};function Y(e){if(!e||e.size<=0||e.intensity<=0)return"";const t=Math.round(100*Math.min(1,e.intensity)),i=`color-mix(in srgb, ${e.color} ${t}%, transparent)`;return`drop-shadow(0 0 ${.4*e.size}px ${i}) drop-shadow(0 0 ${e.size}px ${i})`}const j=_,W=10*C;export class TimeSlider extends w{getLayers(){return[...this.layers]}getVisibleLayers(){return this.getLayers().filter(e=>e.visible)}constructor(i){super(),this.valueRanges=new Map,this.layers=[],this.onDestroy=[],this.ticksBar=new A,this.loaders=new Set,this.layerUnloaders=new Map,this.layerListenerStoppers=new Map,this.layerLoaders=new Map,this.pressedKeys=new Set,this.container=null,this.d=new t,this.id=e(),this.playing=!1,this.live=!1,this._showCurrent=!1,this.current=Date.now(),this.range={time:z,value:{minValue:0,maxValue:100}},this.size={width:100,height:100},this.sliderElement=document.createElement("div"),this.yAxisTicks=new H,this.hoverLine=document.createElement("div"),this.toolTip=document.createElement("div"),this.selectedLabel=document.createElement("div"),this.selectingRangeElement=document.createElement("div"),this.selectionOverlayContainer=document.createElement("div"),this._selectionRanges=[],this.selectionRangeElements=[],this.selectionBehindContainer=document.createElement("div"),this._selectionEditMode="always",this.editingIndex=null,this.selectionStyle={},this._selectionOrder="front",this.shadingElements=[],this.columnBandOverlayContainer=document.createElement("div"),this.columnBandElements=[],this.selectingRange=!1,this.selectingRangeVisible=!1,this.tickTooltip=!0,this.tooltipStyle={},this.tickToolTip=document.createElement("div"),this._gridOrder="front",this.selectingRangeStyle={},this.updateValueRangesQueue=new Map,this.showingStats=!1,this._engineReady=!1,this.mouse=null,this.updatingLabel=!1,this.warnedDirection=new Set,this.hoverCleared=!0,this.dragging=!1,this.pinching=!1,this.hoverOptions=i?.hover||{},this.selectionOptions={highlight:"boolean"!=typeof i?.selection?.highlight||i.selection.highlight,label:"boolean"!=typeof i?.selection?.label||i.selection.label,shading:"boolean"!=typeof i?.selection?.shading||i.selection.shading,invertShading:"boolean"==typeof i?.selection?.invertShading&&i.selection.invertShading,pick:i?.selection?.pick||"element",columnBand:i?.selection?.columnBand},this.showCurrent=i?.showCurrent||!1,this.showTicks=i?.showTicks||!1,this.selectRangeMode=i?.selectRangeMode||"select",this.playSpeed=i?.playSpeed||"auto",this.liveRange=i?.liveRange||10*_,this.theme=i?.theme||"dark",this._locale=i?.locale||r(),m(this._locale),this.ticksBar.setLocale(this._locale),this.ticksBar.setWeekLabel(i?.weekLabel||"default",i?.weekLabelPrefix),this.ticksBar.setTickLabelStyler(i?.tickLabelStyler),this.setLimits(i?.limits),this.tickTooltip=i?.tickTooltip??!0,this.tooltipStyle=i?.tooltipStyle??{},this.ticksBar.onHoverTick=e=>this.onTickHover(e),this._gridOrder=i?.gridOrder??"front",this.setSelectingRangeStyle(i?.selectingRangeStyle??{}),this._selectionEditMode=i?.selectionEditMode??"always",this.selectionStyle=i?.selectionStyle??{},this.applyDrawingStyle(),this._selectionOrder=i?.selectionOrder??"front",this.selectionBehindContainer.style.position="absolute",this.selectionBehindContainer.style.width="100%",this.selectionBehindContainer.style.overflow="hidden",this.selectionBehindContainer.style.pointerEvents="none",this.selectionBehindContainer.style.zIndex="0",this.setBackground(i?.background),this.setFont(i?.font),this.syncMaxValues(),this.on("time",()=>this.renderSelectionOverlay()),this.on("size",()=>this.renderSelectionOverlay())}get locale(){return this._locale}setLocale(e){this._locale=e,m(e),this.ticksBar.setLocale(e),this.emit("locale",e)}setWeekLabel(e,t){this.ticksBar.setWeekLabel(e,t)}setTickLabelStyler(e){this.ticksBar.setTickLabelStyler(e)}get font(){return this._font?{...this._font}:void 0}setFont(e){this._font=e?{...e}:void 0;const t=$(e);this.ticksBar.setFont(F(t),t.size),this.yAxisTicks.setFont(e),this.applyTooltipStyles(),this.renderYAxis(),e&&"undefined"!=typeof document&&document.fonts&&document.fonts.load(F(t)).then(()=>this.refreshFonts(),()=>{})}refreshFonts(){this.ticksBar.refreshFont(),this.renderYAxis()}watchFontLoading(){if(this.stopWatchingFonts||"undefined"==typeof document||!document.fonts)return;const e=document.fonts,t=()=>this.refreshFonts();e.addEventListener("loadingdone",t),e.ready.then(t,()=>{}),this.stopWatchingFonts=()=>e.removeEventListener("loadingdone",t),this.onDestroy.push(()=>this.stopWatchingFonts?.())}watchPixelRatio(){if("undefined"==typeof window||!window.matchMedia)return;let e=()=>{};const t=()=>{const i=window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),s=()=>{e(),this.ticksBar.draw(),this.renderYAxis(),t()};i.addEventListener("change",s),e=()=>i.removeEventListener("change",s)};t(),this.onDestroy.push(()=>e())}get background(){return this._background}setBackground(e){this._background=e,this.engine?.setBackground(e),this.ticksBar.setBackground(e),this.updateBehindLayers()}setSelectingRangeStyle(e){this.selectingRangeStyle={...e},this.applyDrawingStyle()}applyDrawingStyle(){const e=this.selectingRangeElement,t=this.selectionStyle.drawing??{},i=this.resolveSelectionStyle("drawing");e.style.boxSizing="border-box",e.style.zIndex="3",e.style.background=t.fill??this.selectingRangeStyle.background??i.fill,e.style.border=t.border||!this.selectingRangeStyle.border?`${function(e){if(e<=0)return 0;const t=U();return Math.max(1,Math.round(e*t))/t}(i.border.width)}px ${i.border.style} ${i.border.color}`:this.selectingRangeStyle.border,e.style.filter=Y(i.glow)}get selectionEditMode(){return this._selectionEditMode}setSelectionEditMode(e){this._selectionEditMode=e,this.editingIndex=null,this.renderSelectionOverlay(!0)}get editingSelection(){return this.editingIndex}editSelection(e){const t=null!==e&&e>=0&&e<this._selectionRanges.length?e:null;t!==this.editingIndex&&(this.editingIndex=t,this.renderSelectionOverlay(!0),this.emit("selectionedit",null===t?null:{index:t,range:{...this._selectionRanges[t]}}))}setSelectionStyle(e){this.selectionStyle={idle:e.idle&&{...e.idle},editing:e.editing&&{...e.editing},drawing:e.drawing&&{...e.drawing}},this.applyDrawingStyle(),this.selectionRangeElements.forEach((e,t)=>this.styleSelectionRange(e,this.isRangeEditable(t))),this.renderSelectionOverlay()}get selectionOrder(){return this._selectionOrder}setSelectionOrder(e){this._selectionOrder=e,this.updateBehindLayers(),this.renderSelectionOverlay(!0)}isRangeEditable(e){return"always"===this._selectionEditMode||this.editingIndex===e}resolveSelectionStyle(e){const t=P[e],i=this.selectionStyle[e]??{},s=i.border?.color??t.border.color;return{fill:i.fill??t.fill,border:{color:s,width:i.border?.width??t.border.width,style:i.border?.style??t.border.style},handle:{color:i.handle?.color??t.handle.color,width:i.handle?.width??t.handle.width,look:i.handle?.look??t.handle.look},glow:i.glow?{color:i.glow.color??s,size:i.glow.size??8,intensity:i.glow.intensity??1}:void 0}}styleSelectionRange(e,t){const i=this.resolveSelectionStyle(t?"editing":"idle");e.fill.style.background=i.fill,e.frame.style.borderStyle=i.border.style,e.frame.style.borderColor=i.border.color,e.frame.style.filter=Y(i.glow),[e.startHandle,e.endHandle].forEach(e=>{const t=e?.firstElementChild;if(!t)return;t.style.background=i.handle.color;const s="grip"===i.handle.look;t.style.top=s?"50%":"0px",t.style.height=s?"min(32px, 40%)":"100%",t.style.transform=s?"translateY(-50%)":"",t.style.borderRadius=s?"999px":""})}layoutOverlays(){const e=this.sliderElement.style.top||"0px",t=this.sliderElement.style.height||"100%";[this.selectionOverlayContainer,this.columnBandOverlayContainer].forEach(i=>{i.style.top=e,i.style.height=t}),this.selectionBehindContainer.style.height=t,this.yAxisTicks.behindCanvas.style.height=t}get gridOrder(){return this._gridOrder}setGridOrder(e){this._gridOrder=e,this.updateBehindLayers(),this.renderYAxis()}updateBehindLayers(){const e="behind"===this._gridOrder||this.getVisibleLayers().some(e=>e.baseline)||"behind"===this._selectionOrder&&this._selectionRanges.length>0;this.engine?.setTransparent(e),this.sliderElement.style.background=e?this._background??("dark"===this.theme?"#111":"#eee"):""}attachBehindCanvas(){const e=this.yAxisTicks.behindCanvas;e.style.height=this.sliderElement.style.height,e.style.zIndex="0",[...this.sliderElement.children].forEach(t=>{t!==e&&t!==this.selectedLabel&&t!==this.selectionBehindContainer&&t instanceof HTMLCanvasElement&&(t.style.zIndex="1")}),e.parentElement!==this.sliderElement&&this.sliderElement.insertBefore(e,this.sliderElement.firstChild),this.selectionBehindContainer.parentElement!==this.sliderElement&&this.sliderElement.insertBefore(this.selectionBehindContainer,e.nextSibling),this.layoutOverlays()}setTickTooltip(e){this.tickTooltip=e,!1===e&&(this.tickToolTip.style.display="none")}setTooltipStyle(e){this.tooltipStyle={...e},this.applyTooltipStyles()}applyTooltipStyles(){this.applyTooltipStyle(this.toolTip),this.applyTooltipStyle(this.tickToolTip),this.applyTooltipStyle(this.selectedLabel,"200px")}applyTooltipStyle(e,t=""){const i=this.tooltipStyle;e.style.background=i.background??"rgba(0, 0, 0, 0.75)",e.style.color=i.color??"white",e.style.border=i.border??"none",e.style.borderRadius=i.borderRadius??"4px",e.style.padding=i.padding??"4px 8px",e.style.maxWidth=i.maxWidth??t,e.style.font=F($(i.font??this._font))}onTickHover(e){if(!e)return this.tickToolTip.style.display="none",void this.emit("tickhover",null);const t=this.ticksBar.getCanvasRect(),i=new DOMRect(t.left+e.x,t.top,e.width,t.height),s={startTime:e.startTime,endTime:e.endTime,unit:d(e.startTime,e.endTime),label:e.label,fullLabel:this.ticksBar.getFullLabel(e)};this.emit("tickhover",{...s,rect:i});const n=!1===this.tickTooltip?void 0:"function"==typeof this.tickTooltip?this.tickTooltip(s):s.fullLabel;if(!n)return void(this.tickToolTip.style.display="none");this.tickToolTip.textContent=n,this.tickToolTip.style.display="block";const l=this.tickToolTip.offsetWidth,o=this.tickToolTip.offsetHeight,a=Math.min(Math.max(4,i.left+.5*i.width-.5*l),window.innerWidth-l-4),r=i.top-o-6;this.tickToolTip.style.left=`${a}px`,this.tickToolTip.style.top=`${r>=4?r:i.bottom+6}px`}get limits(){return this._limits?{...this._limits}:void 0}setLimits(e){!e||e.endTime>e.startTime||(console.warn("Ignoring time slider limits whose endTime is not after startTime",e),e=void 0),this._limits=e?{startTime:e.startTime,endTime:e.endTime}:void 0,this._limits&&this.setTimeRange(this.getTimeRange())}setSelection(e){this._selectionRanges=e.map(e=>({...e})),null!==this.editingIndex&&this.editingIndex>=this._selectionRanges.length&&(this.editingIndex=null,this.emit("selectionedit",null)),this.renderSelectionOverlay(!0),this.emit("selectionchange",{ranges:this.getSelection(),phase:"end"})}getSelection(){return this._selectionRanges.map(e=>({...e}))}clearSelection(){this.setSelection([])}setPickMode(e){this.selectionOptions.pick=e,this.updateHover()}selectionTimeToX(e,t,i,s){return e===-1/0?0:e===1/0?s:Math.min(s,Math.max(0,(e-t)/(i-t)*s))}renderSelectionOverlay(e=!1){if(!this.container)return;const t=this.getSliderBounds();if(t.width<=0)return;const{startTime:i,endTime:s}=this.getTimeRange(),n=e=>this.selectionTimeToX(e,i,s,t.width),l=U(),o=e=>Math.round(e*l),a=e=>e>0?Math.max(1,Math.round(e*l)):0;if((e||this.selectionRangeElements.length!==this._selectionRanges.length||this.selectionRangeElements.some((e,t)=>e.range!==this._selectionRanges[t]))&&(this.selectionRangeElements.forEach(({fill:e,frame:t,startHandle:i,endHandle:s})=>{e.remove(),t.remove(),i?.remove(),s?.remove()}),this.selectionRangeElements=this._selectionRanges.map((e,t)=>this.createSelectionRangeElements(e,t)),this.updateBehindLayers()),this.selectionRangeElements.forEach(({range:e,fill:t,frame:i,startHandle:s,endHandle:r},h)=>{const d=this.resolveSelectionStyle(this.isRangeEditable(h)?"editing":"idle"),c=e.startTime===-1/0,m=e.endTime===1/0,g=o(n(e.startTime)),u=o(n(e.endTime));t.style.left=g/l+"px",t.style.width=Math.max(0,u-g)/l+"px";const p=a(d.border.width),y=Math.floor(p/2),T=c?g:g-y,v=m?u:u-y+p,f=p/l;i.style.left=T/l+"px",i.style.width=Math.max(0,v-T)/l+"px",i.style.borderWidth=`${f}px ${m?0:f}px ${f}px ${c?0:f}px`;const x=(e,t)=>{const i=e?.firstElementChild;if(!e||!i)return;const s=a(d.handle.width),n=(t-Math.floor(s/2))/l,o=s/l,r=Math.max(8,o),h=n+.5*o-.5*r;e.style.left=h+"px",e.style.width=r+"px",i.style.left=n-h+"px",i.style.width=o+"px"};x(s,g),x(r,u)}),this.shadingElements.forEach(e=>e.remove()),this.shadingElements=[],this.selectionOptions.shading&&this._selectionRanges.length>0){const e=x(this._selectionRanges).map(e=>[n(e.startTime),n(e.endTime)]);(this.selectionOptions.invertShading?e:function(e,t){const i=[];let s=0;for(const[t,n]of e)t>s&&i.push([s,t]),s=Math.max(s,n);s<t&&i.push([s,t]);return i}(e,t.width)).forEach(([e,t])=>{if(t<=e)return;const i=document.createElement("div");i.style.position="absolute",i.style.top="0px",i.style.height="100%",i.style.left=e+"px",i.style.width=t-e+"px",i.style.background="rgba(0, 0, 0, 0.5)",i.style.pointerEvents="none",this.selectionOverlayContainer.appendChild(i),this.shadingElements.push(i)})}}renderColumnHoverBand(e){if(this.columnBandElements.forEach(e=>e.remove()),this.columnBandElements=[],"column"!==this.selectionOptions.pick||0===e.length||!this.container)return;const t=this.getSliderBounds();if(t.width<=0)return;const{startTime:i,endTime:s}=this.getTimeRange(),n=e=>Math.min(t.width,Math.max(0,(e-i)/(s-i)*t.width)),l=this.selectionOptions.columnBand?.color??"#fff",o=this.selectionOptions.columnBand?.opacity??.15;e.forEach(({layer:e,elements:t})=>{const i=t.map(u),s=Math.min(...i.map(e=>e[0])),a=Math.max(...i.map(e=>e[1])),r=document.createElement("div");r.style.position="absolute",r.style.left=n(s)+"px",r.style.width=Math.max(1,n(a)-n(s))+"px",r.style.top=100*(1-e.max)+"%",r.style.height=100*(e.max-e.min)+"%",r.style.background=l,r.style.opacity=String(o),r.style.pointerEvents="none",this.columnBandOverlayContainer.appendChild(r),this.columnBandElements.push(r)})}createSelectionRangeElements(e,t){const i=this.isRangeEditable(t),s=document.createElement("div");s.style.position="absolute",s.style.top="0px",s.style.height="100%",s.style.pointerEvents="none",("behind"===this._selectionOrder?this.selectionBehindContainer:this.selectionOverlayContainer).appendChild(s);const n=document.createElement("div");n.style.position="absolute",n.style.top="0px",n.style.height="100%",n.style.boxSizing="border-box",n.style.background="transparent",n.style.pointerEvents=i?"auto":"none",n.style.cursor=i?"grab":"",n.style.touchAction=i?"none":"",this.selectionOverlayContainer.appendChild(n);const l=()=>{const e=document.createElement("div");e.style.position="absolute",e.style.top="0px",e.style.height="100%",e.style.cursor="ew-resize",e.style.pointerEvents="auto",e.style.touchAction="none";const t=document.createElement("div");return t.style.position="absolute",t.style.pointerEvents="none",e.appendChild(t),this.selectionOverlayContainer.appendChild(e),e},o=i&&e.startTime!==-1/0?l():null,a=i&&e.endTime!==1/0?l():null,r={range:e,fill:s,frame:n,startHandle:o,endHandle:a};return this.styleSelectionRange(r,i),i&&this.wireSelectionDrag(e,n,o,a),r}wireSelectionDrag(e,t,i,s){const n=(e,t)=>{e.addEventListener("pointerdown",i=>{i.stopPropagation(),i.preventDefault(),e.setPointerCapture(i.pointerId);const s=t(i),n=e=>{s(e),this.renderSelectionOverlay(),this.emit("selectionchange",{ranges:this.getSelection(),phase:"drag"})};let l=!1;const o=t=>{l||(l=!0,e.hasPointerCapture(t.pointerId)&&e.releasePointerCapture(t.pointerId),e.removeEventListener("pointermove",n),e.removeEventListener("pointerup",o),e.removeEventListener("pointercancel",o),e.removeEventListener("lostpointercapture",o),this.emit("selectionchange",{ranges:this.getSelection(),phase:"end"}))};this.emit("selectionchange",{ranges:this.getSelection(),phase:"start"}),e.addEventListener("pointermove",n),e.addEventListener("pointerup",o),e.addEventListener("pointercancel",o),e.addEventListener("lostpointercapture",o)})};i&&n(i,()=>t=>{const{t:i}=this.mouseInSlider(t);e.startTime=e.endTime===1/0?i:Math.min(i,e.endTime)}),s&&n(s,()=>t=>{const{t:i}=this.mouseInSlider(t);e.endTime=e.startTime===-1/0?i:Math.max(i,e.startTime)}),n(t,t=>{const i=this.mouseInSlider(t).t,s=e.startTime,n=e.endTime;return t=>{const l=this.mouseInSlider(t).t-i;s===-1/0&&n!==1/0?e.endTime=n+l:n===1/0&&s!==-1/0?e.startTime=s+l:s!==-1/0&&n!==1/0&&(e.startTime=s+l,e.endTime=n+l)}})}startSelectingRange(e){this.editSelection(null),this.selectingRange=!0,this.whenDoneSelectingRange=e}stopSelectingRange(){this.selectingRange=!1,this.whenDoneSelectingRange?.(),this.whenDoneSelectingRange=void 0,this.selectingRangeVisible&&(this.container.removeChild(this.selectingRangeElement),this.selectingRangeVisible=!1)}syncMaxValues(){return this.updateAllValueRanges(),this.on("time",()=>this.updateAllValueRanges())}syncMaxValuesForLayer(e){return this.updateValueRanges(e.yAxisGroup),e.model.on(()=>this.updateValueRanges(e.yAxisGroup))}updateAllValueRanges(){this.layers.filter(e=>e.visible).forEach(e=>{this.updateValueRanges(e.yAxisGroup,!0)}),this.renderYAxis()}updateValueRanges(e,t){this.updateValueRangesQueue.has(e)||this.updateValueRangesQueue.set(e,{lastUpdate:0,pending:void 0});const i=this.updateValueRangesQueue.get(e);if(Date.now()-i.lastUpdate<100)return i.pending&&clearTimeout(i.pending),void(i.pending=setTimeout(()=>{i.pending=void 0,this.updateValueRanges(e)},200));i.lastUpdate=Date.now();const s=new Map,n=new Map;this.layers.filter(e=>e.visible).forEach(e=>{const t=e.yAxis.group||e.id;s.has(t)||(s.set(t,-Number.MAX_VALUE),n.set(t,Number.MAX_VALUE));const i=e.model.getValueRange(this.getTimeRange());i.minValue<n.get(t)&&n.set(t,i.minValue),i.maxValue>s.get(t)&&s.set(t,i.maxValue)}),this.valueRanges.clear(),s.forEach((e,t)=>{this.valueRanges.set(t,{max:e,min:n.get(t)})}),t||this.renderYAxis(),this.emit("valueRanges",e)}renderYAxis(){const e=new Map;this.layers.filter(e=>e.visible).forEach(t=>{const i=t.yAxis.group||t.id;e.has(i)||e.set(i,{min:t.min,max:t.max,group:i}),e.set(i,{...e.get(i),...t.yAxis,min:t.min,max:t.max,direction:this.isHangingDown(t)?"down":"up"})});const t=[];e.forEach(e=>{if(e.visible){const i=this.valueRanges.get(e.group);i&&t.push({...e,minValue:i.min,maxValue:i.max})}});const i=this.getVisibleLayers().filter(e=>e.baseline).map(e=>({y:this.isHangingDown(e)?e.max:e.min,color:e.baseline.color,width:e.baseline.width??1}));this.yAxisTicks.render(t,{gridBehind:"behind"===this._gridOrder,baselines:i})}setTheme(e){this.theme=e,this.updateBehindLayers(),this.ticksBar.setDarkMode("dark"===e),this.engine?.setTheme(e)}addLayerLoader(e){this.loaders.add(e)}showStats(e){this.showingStats=e,this.engine?.showStats(e)}get engineReady(){return this._engineReady}whenReady(){return this._engineReady?Promise.resolve():new Promise(e=>{const t=this.on("ready",()=>{t(),e()})})}async setEngine(e){this._engineReady=!1,this.engine&&(this.layerUnloaders.forEach(e=>e()),this.layerUnloaders.clear(),this.engine.dispose()),this.initSliderContainer(),this.engine=e,this.engine.setTheme(this.theme),this.engine.setBackground(this._background),await this.engine.init(this.sliderElement),this.engine.setTheme(this.theme),this._engineReady=!0,this.emit("ready"),this.getVisibleLayers().forEach(e=>this.loadLayer(e)),this.engine.showStats(this.showingStats),this.engine.setTimeRange(this.getTimeRange()),this.engine.setValueRange(this.getValueRange()),this.engine.setSize(this.size.width,this.size.height),this.attachBehindCanvas(),this.updateBehindLayers(),this.renderYAxis()}initSliderContainer(){this.stopControls&&this.stopControls(),this.container?.removeChild(this.sliderElement);let e=0;this.showTicks&&(e+=24),this.showCurrent&&(e+=4),this.sliderElement=document.createElement("div"),this.sliderElement.oncontextmenu=()=>!1,this.sliderElement.tabIndex=0,this.sliderElement.style.top="0px",this.sliderElement.style.width="100%",this.sliderElement.style.outline="none",this.sliderElement.style.touchAction="none",this.sliderElement.style.height=`calc(100% - ${0+e}px)`,this.container?.appendChild(this.sliderElement),this.initSelectLabel(),this.stopControls=this.initControls(),this.onDestroy.push(()=>{this.container?.removeChild(this.sliderElement)})}get showCurrent(){return this._showCurrent}set showCurrent(e){if(e!==this._showCurrent){this._showCurrent=e,this.ticksBar.showLine=!this.showCurrent;let t=0,i=0;this.showTicks&&(i+=24),this.showCurrent&&(i+=4),this.sliderElement.style.height=`calc(100% - ${t+i}px)`,this.yAxisTicks.behindCanvas.style.height=this.sliderElement.style.height,this.layoutOverlays()}}async init(e,t){const i="string"==typeof e?document.getElementById(e):e;if(this.container=i,i){i.oncontextmenu=()=>!1;let e=0,s=0;if(this.showTicks){s+=24;const e=document.createElement("div");e.style.width="100%",e.style.height="24px",e.style.position="absolute",e.style.bottom="0px",e.style.touchAction="none",i.appendChild(e),this.ticksBar.init(e,e=>{const t=d(e.startTime,e.endTime);this.emit("tickclick",{startTime:e.startTime,endTime:e.endTime,unit:t}),this.fit({range:e,animate:1e3})}),this.ticksBar.showLine=!this.showCurrent}this.showCurrent&&(s+=4),this.sliderElement.oncontextmenu=()=>!1,this.sliderElement.tabIndex=0,this.sliderElement.style.top=`${e}px`,this.sliderElement.style.width="100%",this.sliderElement.style.outline="none",this.sliderElement.style.touchAction="none",this.sliderElement.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.sliderElement),i.style.isolation="isolate",this.yAxisTicks.canvas.style.zIndex="2",this.selectionOverlayContainer.style.zIndex="3",this.columnBandOverlayContainer.style.zIndex="3",this.yAxisTicks.canvas.style.top=`${e}px`,this.yAxisTicks.canvas.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.yAxisTicks.canvas),this.selectionOverlayContainer.style.position="absolute",this.selectionOverlayContainer.style.width="100%",this.selectionOverlayContainer.style.overflow="hidden",this.selectionOverlayContainer.style.pointerEvents="none",this.selectionOverlayContainer.style.top=`${e}px`,this.selectionOverlayContainer.style.height=`calc(100% - ${e+s}px)`,this.selectionBehindContainer.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.selectionOverlayContainer),this.onDestroy.push(()=>i.removeChild(this.selectionOverlayContainer)),this.columnBandOverlayContainer.style.position="absolute",this.columnBandOverlayContainer.style.width="100%",this.columnBandOverlayContainer.style.overflow="hidden",this.columnBandOverlayContainer.style.pointerEvents="none",this.columnBandOverlayContainer.style.top=`${e}px`,this.columnBandOverlayContainer.style.height=`calc(100% - ${e+s}px)`,i.appendChild(this.columnBandOverlayContainer),this.onDestroy.push(()=>i.removeChild(this.columnBandOverlayContainer)),this.initHoverTooltip(),this.initTickTooltip(),this.watchFontLoading();const n=e=>{"Escape"===e.key&&null!==this.editingIndex&&this.editSelection(null)};document.addEventListener("keydown",n),this.onDestroy.push(()=>document.removeEventListener("keydown",n)),this.watchPixelRatio(),this.initSelectLabel(),this.setSize(this.sliderElement.clientWidth,this.sliderElement.clientHeight),this.syncSize(),this.setTimeRange(K(t)),this.setValueRange(K(t))}else console.warn(`Element ${e} not found`)}initSelectLabel(){this.selectedLabel.style.position="absolute",this.applyTooltipStyle(this.selectedLabel,"200px"),this.selectedLabel.style.pointerEvents="none",this.selectedLabel.style.display="none",this.selectedLabel.style.zIndex="10",this.sliderElement.appendChild(this.selectedLabel)}getLabel(e,t,i,s){if(t.labeler){const n=t.labeler(e,i,s);return null===n?null:"string"==typeof n?`<div>${n}</div>`:n?n.outerHTML:`<div>${e.name||e.id}</div>`}return`<div>${e.name||e.id}</div>`}getLayerById(e){return this.layers.find(t=>t.id===e)}select(e,t){this.stopSelectingRange(),this.stopUpdatingLabel?.();const i=()=>{this.updatingLabel=!1,this.stopUpdatingLabel?.(),this.stopUpdatingLabel=void 0,this.selectedLabel.style.display="none",this.layers.forEach(e=>e.select([])),this.selectedLayerId=void 0,this.emit("select",[])},s=e=>{this.layers.filter(t=>!e.some(e=>t.id===e.layer.id)).forEach(e=>e.select([])),e.forEach(e=>{e.layer.select(e.elements)}),this.emit("select",e)};if(t){s(this.getVisibleLayers().map(e=>{const i=e.model.dataInTimeRange(t);return{layer:e,elements:i}}).filter(e=>e.elements.length>0))}else if(e){const t=this.findElements(e,24);if(s(t.map(e=>({layer:e.layer,elements:e.elements})).flat()),1===t.length&&t[0].elements.length>0&&this.selectionOptions.label){const e=t[0].elements[0],s=t[0].layer;this.selectedLabel.innerHTML=this.getLabel(e,s,t[0].t,t[0].v)||"",this.selectedLabel.style.display="block";const n=this.selectedLabel.offsetWidth,l=this.selectedLabel.offsetHeight;this.selectedLayerId=s.id;const o=Array.isArray(e.t);this.updatingLabel=!0;const a=()=>{if(!this.updatingLabel)return;const{startTime:i,duration:s,endTime:a}=this.getTimeRange(),r=t[0].layer.model.get(e.id);if(r){const e=E(this.getTimeRange(),r.t);if(e){const a=this.getSliderBounds();let h=(.5*(e.startTime+e.endTime)-i)/s*a.width;const d="number"==typeof r.v?r.v:.5*(r.v[1]+r.v[0]);let c=this.modelValueToPixels(d,t[0].layer);o?c-=.5*l:c+=8;const m=.5*n,g=.5*l,u=a.width-.5*n,p=a.height-.5*l,y=Math.min(u,Math.max(m,h)),T=Math.min(p,Math.max(g,c));this.selectedLabel.style.display="block",this.selectedLabel.style.left=y-.5*n+"px",this.selectedLabel.style.top=`${T}px`}else this.selectedLabel.style.display="none"}else this.selectedLabel.style.display="none"};a();const r=s instanceof L&&s.histogram instanceof g;this.stopUpdatingLabel=this.on("time",r?i:a)}}else i()}onSelectionRangeClick(e){if("always"===this._selectionEditMode||0===this._selectionRanges.length)return;if("never"===this._selectionEditMode)return void this.editSelection(null);const{t:t}=this.mouseInSlider(e),i=this.findElements(e,24).some(e=>e.elements.length>0),s=this._selectionRanges.findIndex(e=>e.startTime<=t&&t<=e.endTime);this.editSelection(!i&&s>=0?s:null)}listenToClicks(){let e=null;const t=t=>{e={x:t.clientX,y:t.clientY}},i=t=>{if(!e)return;const i=t.clientX-e.x,s=t.clientY-e.y;i*i+s*s<=25&&(this.stopSelectingRange(),this.onSelectionRangeClick(e),this.select(e)),e=null},s=()=>{e=null};return this.sliderElement.addEventListener("pointerdown",t),this.sliderElement.addEventListener("pointerup",i),this.sliderElement.addEventListener("pointercancel",s),()=>{this.sliderElement.removeEventListener("pointerdown",t),this.sliderElement.removeEventListener("pointerup",i),this.sliderElement.removeEventListener("pointercancel",s)}}getSliderBounds(){return this.sliderElement.getBoundingClientRect()}mouseInSlider(e){const t=this.getSliderBounds(),i="x"in e?e:{x:e.clientX,y:e.clientY},s={x:i.x-t.left,y:i.y-t.top},n={x:s.x/t.width,y:-s.y/t.height+1},{startTime:l,duration:o}=this.getTimeRange(),a=l+n.x*o,{minValue:r,maxValue:h}=this.getValueRange();return{absolute:s,normalized:n,t:a,v:r+n.x*(h-r)}}pixelsToLayerValue(e,t){if(!e)return{yInLayer:0,toLayerHeight:1};const i="normalized"in e?e.normalized:this.mouseInSlider(e).normalized;let s=t.min,n=t.max;const l=n-s;return{yInLayer:this.isHangingDown(t)?(n-i.y)/l:(i.y-s)/l,toLayerHeight:l/this.getSliderBounds().height}}isHangingDown(e){return"down"===e.direction&&(e instanceof R||(this.warnedDirection.has(e.id)||(this.warnedDirection.add(e.id),console.warn("Layer direction 'down' is only supported for bar (intervals / histogram) layers, ignoring it for",e.name)),!1))}pixelsToModelValue(e,t){const{yInLayer:i,toLayerHeight:s}=this.pixelsToLayerValue(e,t);let n=0,l=100;if(t.model instanceof p){const e=this.valueRanges.get(t.yAxisGroup)||{min:0,max:1e3};n=e.min,l=e.max-n}return{yInModel:n+i*l,toModelHeight:s*l}}layerValueToPixels(e,t){let i=t.min,s=t.max;const n=s-i,l=this.getSliderBounds().height;return(1-(this.isHangingDown(t)?s-n*e:i+n*e))*l}modelValueToPixels(e,t){let i=0,s=100;if(t.model instanceof p){const e=t.model.getValueRange(this.getTimeRange());i=e.minValue,s=e.maxValue-i}const n=(e-i)/s;return this.layerValueToPixels(n,t)}findElements(e,t){if("column"===this.selectionOptions.pick)return this.findColumnElements(e);const{width:i,height:s}=this.getSliderBounds(),{normalized:n}=this.mouseInSlider(e),{startTime:l,endTime:o,duration:a}=this.getTimeRange(),r=l+n.x*a,h=t||12,d=h/i*a,c={startTime:r-1,endTime:r+1},m={startTime:r-.5*d,endTime:r+.5*d};return this.getVisibleLayers().map(e=>{const{yInModel:t,toModelHeight:i}=this.pixelsToModelValue({normalized:n},e),s=e instanceof R?0:h*i,l=e instanceof R?c:m,o={minValue:t-.5*s,maxValue:t+.5*s},a=e.model.dataInRange({...l,...o});return{layer:e,elements:a,t:r,v:t}}).filter(e=>e.elements.length>0)}findColumnElements(e,t){const{width:i}=this.getSliderBounds(),{normalized:s}=this.mouseInSlider(e),{startTime:n,duration:l}=this.getTimeRange(),o=n+s.x*l,a=(t||12)/i*l,r={startTime:o-1,endTime:o+1},h={startTime:o-.5*a,endTime:o+.5*a};return this.getVisibleLayers().map(e=>{const{yInModel:t}=this.pixelsToModelValue({normalized:s},e),i=e instanceof R?r:h,n=e.model.dataInTimeRange(i);return{layer:e,elements:n,t:o,v:t}}).filter(e=>e.elements.length>0)}clearHoverEvent(){this.hoverCleared||(this.hoverCleared=!0,this.renderColumnHoverBand([]),this.emit("hover",null))}updateHover(e){if(this.dragging)return this.hoverLine.style.display="none",this.toolTip.style.display="none",void this.clearHoverEvent();if(void 0!==e&&(this.mouse=e),this.mouse){const e=this.getSliderBounds(),{normalized:t}=this.mouseInSlider(this.mouse),{startTime:i,endTime:s,duration:l}=this.getTimeRange(),o=i+t.x*l,a=this.findElements(this.mouse);this.renderColumnHoverBand(a),this.hoverCleared=!1,this.emit("hover",{elements:a.map(e=>({layer:e.layer,elements:e.elements})),t:o,clientX:this.mouse.x,clientY:this.mouse.y});const r=a.map(e=>e.elements.map(t=>({e:t,l:e.layer,t:e.t,v:e.v}))).flat();let h;if(r.length>0)if(r.length>3){h=r.slice(0,2).map(e=>this.getLabel(e.e,e.l,e.t,e.v)).flat().filter(e=>null!==e).join(""),h+=`<div>And ${r.length-2} more...</div>`}else{h=a.map(e=>e.elements.map(t=>this.getLabel(t,e.layer,e.t,e.v))).flat().filter(e=>null!==e).join("")}if(!1===this.hoverOptions.tooltip)this.toolTip.style.display="none";else{const t=new Date(o),i=t.getHours(),s=t.getMinutes(),l=t.getSeconds(),a=n(o,!0,this._locale),r=`${(i<10?"0":"")+i}:${(s<10?"0":"")+s}:${(l<10?"0":"")+l}`;let d="";const c=this.ticksBar.cache.high.spacing;(void 0===this.hoverOptions.date?c>=B:this.hoverOptions.date)&&(d+=`<div>${a}</div>`),(void 0===this.hoverOptions.time?c<=M:this.hoverOptions.time)&&(d+=`<div>${r}</div>`),h&&(d+=h),this.toolTip.innerHTML=d,this.toolTip.style.display=d.length>0?"block":"none";const m=88,g=36;let u=this.mouse.x+10,p=this.mouse.y+10;const y=e.left+e.width-m-5,T=e.top+e.height-g-5;u>y&&(u=y),p>T&&(p=T),this.toolTip.style.left=`${u}px`,this.toolTip.style.top=`${p}px`}}else this.hoverLine.style.display="none",this.toolTip.style.display="none",this.clearHoverEvent()}initHoverTooltip(){this.toolTip.style.position="fixed",this.applyTooltipStyle(this.toolTip),this.toolTip.style.pointerEvents="none",this.toolTip.style.display="none",this.toolTip.style.zIndex="10",this.toolTip.style.overflow="hidden",document.body.appendChild(this.toolTip),this.onDestroy.push(()=>this.toolTip.remove())}initTickTooltip(){this.tickToolTip.style.position="fixed",this.applyTooltipStyle(this.tickToolTip),this.tickToolTip.style.pointerEvents="none",this.tickToolTip.style.display="none",this.tickToolTip.style.zIndex="10",this.tickToolTip.style.whiteSpace="pre-line",document.body.appendChild(this.tickToolTip),this.onDestroy.push(()=>this.tickToolTip.remove())}initHoverListener(){const e=()=>{this.updateHover(null)},t=e=>{this.updateHover({x:e.clientX,y:e.clientY})};this.sliderElement.addEventListener("mouseleave",e),this.sliderElement.addEventListener("mousemove",t);const i=this.listenToClicks();return()=>{this.sliderElement.removeEventListener("mouseleave",e),this.sliderElement.removeEventListener("mousemove",t),i()}}syncSize(){const e=()=>{const{offsetWidth:e,offsetHeight:t}=this.sliderElement;this.setSize(e,t)},t=new ResizeObserver(()=>{e()});this.container&&(t.observe(this.container),e()),this.onDestroy.push(()=>{t.disconnect()})}getTimeRange(){return y(this.range.time)}getValueRange(){return this.range.value}setTimeRange(e,t){const i=this.getTimeRange(),s=v(i,e),n=this._limits?f(s,this._limits):s;n.startTime===i.startTime&&n.endTime===i.endTime||(this.range.time=n,this.engine?.setTimeRange(n),this.showTicks&&this.ticksBar.setTimeRange(n),this.emit("time",n),this.updateHover())}setValueRange(e){const t={...this.getValueRange(),...e};this.range.value=t,this.engine?.setValueRange(t),this.emit("value",this.getValueRange()),this.updateHover()}setSize(e,t){this.size={width:e,height:t},this.showTicks&&this.ticksBar.setWidth(e);const i=this.getTimeRange(),s=this.getValueRange();this.engine?.setSize(e,t),this.setTimeRange(i),this.setValueRange(s),this.renderYAxis(),this.updateHover(),this.emit("size",{width:e,height:t})}up(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange();let n={startTime:0,endTime:Date.now()};const l=.5*(t+i);if(s>=.9*C){const e=Q(10*s);n=h(l,e)}else{const e=[{threshold:S,unit:"millennium"},{threshold:k,unit:"century"},{threshold:I,unit:"decade"},{threshold:.9*O,unit:"year"},{threshold:D,unit:"month"},{threshold:M,unit:"week"},{threshold:B,unit:"day"},{threshold:V,unit:"hour"},{threshold:_,unit:"minute"},{threshold:-1,unit:"second"}];let t=0;for(;s<.9*e[t].threshold;)t++;const i=e[t].unit;n=c(l,i)}this.fit({...e,range:n})}down(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange();let n={startTime:0,endTime:Date.now()};const l=t+("number"==typeof e?.xRatio?e.xRatio:.5)*s;if(s>=.9*C){const e=Q(s/10);n=h(l,e)}else{let e=0;const t=[{threshold:C,unit:"century"},{threshold:S,unit:"decade"},{threshold:k,unit:"year"},{threshold:I,unit:"month"},{threshold:1.1*O,unit:"week"},{threshold:D,unit:"day"},{threshold:M,unit:"hour"},{threshold:B,unit:"minute"},{threshold:V,unit:"second"}].reverse();for(;s>1.1*t[e].threshold;)e++;const i=t[e].unit;n=c(l,i)}this.fit({...e,range:n})}next(e){this.skip(1,e)}previous(e){this.skip(-1,e)}skip(e,t){this.fit({...t,range:this.getSkipRange(e)})}getSkipRange(e){const{startTime:t,endTime:i,duration:s}=this.getTimeRange(),n=.5*(t+i);if(s>=9*C){const e=Q(s);return h(n,e)}const l=d(t,i);return l?c(n,l,Math.round(e)):{startTime:t+e*s,endTime:i+e*s}}clampToLimits(e){return this._limits?f(e,this._limits):e}describeStep(e){const t=this.getTimeRange(),i=this.getSkipRange(e),n=this.clampToLimits(i),l=Math.abs(n.startTime-t.startTime)>X||Math.abs(n.endTime-t.endTime)>X,o=l?n:i,a=e>0?s(t.startTime,o.startTime,this._locale):s(o.startTime,t.startTime,this._locale);return{range:n,canStep:l,span:a,label:G(e,a,this._locale)}}canStep(e){return this.describeStep(e).canStep}describeSpan(e){const{startTime:t,endTime:i}=e??this.getTimeRange(),n=s(t,i,this._locale);return{text:n.text,exact:n.exact,dates:a(t,i,this._locale)}}isFitted(e){const t=this.clampToLimits(e??this.getLayersTimeRange()),i=this.getTimeRange(),s=Math.max(X,.001*(t.endTime-t.startTime));return Math.abs(i.startTime-t.startTime)<=s&&Math.abs(i.endTime-t.endTime)<=s}getTimeRangeLabel(){const{startTime:e,endTime:t}=this.getTimeRange(),i=new Date(e);return 0===i.getHours()&&0===i.getMinutes()&&0===i.getSeconds()&&0===i.getMilliseconds()?l([e,t],this._locale):void 0}cancelFit(){this.stopFit?.(),this.stopFit=void 0}fit(e){this.cancelFit();const t=e?.range||this.getLayersTimeRange(),s=e?.padding?T(t,e.padding):t;if(e?.animate){const t=this.getTimeRange();this.stopFit=i(t.startTime,t.endTime,s.startTime,s.endTime,e.animate,(e,t)=>this.setTimeRange({startTime:e,endTime:t}))}else this.setTimeRange(s)}getLayersTimeRange(){if(0===this.getVisibleLayers().length)return z;{let e=this.getVisibleLayers()[0].model.getTimeRange();return this.getVisibleLayers().slice(1).forEach(t=>e=b(e,t.model.getTimeRange())),e}}loadLayer(e){if(e.timeSlider&&e.timeSlider.id!==this.id)console.warn("Layer already has been loaded by another time slider, create a new layer with the same model and style if you want to add it to another time slider");else if(this.engine&&this._engineReady&&!this.layerUnloaders.has(e.id)){const t=[...this.loaders].filter(e=>this.engine instanceof e.engineClass).find(t=>t.canLoad(e));if(t){const i=Date.now(),s=t.load(e,this.engine.scene,this.engine,this);e.timeSlider=this,e.loaded=!0;const n=e.name||e.constructor.name+"#"+e.id.slice(e.id.length-4).toUpperCase();console.log(`Loaded ${n} in ${o(Date.now()-i)}`);const l=this.syncMaxValuesForLayer(e);this.layerLoaders.set(e.id,t),this.layerUnloaders.set(e.id,()=>{l(),s(),this.layerLoaders.delete(e.id),e.loaded=!1})}else console.warn("No loader found for",{layer:e})}}unloadLayer(e){this.selectedLayerId===e.id&&this.select(null),this.layerUnloaders.has(e.id)&&(this.layerUnloaders.get(e.id)(),this.layerUnloaders.delete(e.id))}addLayer(e){if(this.layers.push(e),e.visible){this.loadLayer(e);const t=e.model.getTimeRange();if(1===this.getVisibleLayers().length)this.setTimeRange(t);else{const e=b(this.getTimeRange(),t);this.setTimeRange(e)}}const t=[e.on("visible",()=>{e.visible?this.loadLayer(e):this.unloadLayer(e),this.updateAllValueRanges(),this.updateBehindLayers()}),e.on("min",()=>this.onLayerBandChange(e)),e.on("max",()=>this.onLayerBandChange(e)),e.on("direction",()=>this.onLayerBandChange(e)),e.on("baseline",()=>{this.updateBehindLayers(),this.renderYAxis()})];this.layerListenerStoppers.set(e.id,()=>t.forEach(e=>e())),this.updateBehindLayers(),this.renderYAxis()}onLayerBandChange(e){const t=this.layerLoaders.get(e.id);t&&!t.followsLayerBand&&(this.layerUnloaders.get(e.id)?.(),this.layerUnloaders.delete(e.id),this.loadLayer(e)),this.updateAllValueRanges()}removeLayer(e){const t="string"==typeof e?e:e.id,i=this.layers.find(e=>e.id===t);i&&(this.unloadLayer(i),this.layerUnloaders.delete(t),this.layerListenerStoppers.get(t)?.(),this.layerListenerStoppers.delete(t),this.layers=this.layers.filter(e=>e.id!==t),this.updateBehindLayers(),this.renderYAxis())}destroy(){this.layers.map(e=>e.id).forEach(e=>this.removeLayer(e)),this.onDestroy.forEach(e=>e())}addHorizontalPinchZoom(){let e=null,t=null;const i=()=>{this.pinching=!1,e=null,t=null},s=i=>{if(2===i.touches.length){i.preventDefault(),this.dragging=!1,this.pinching=!0;const s=this.mouseInSlider(i.touches[0]).t,n=this.mouseInSlider(i.touches[1]).t;e=Math.min(s,n),t=Math.max(s,n)}},n=s=>{if(2===s.touches.length){if(null===e||null===t)return;s.preventDefault(),this.dragging=!1;const i=this.mouseInSlider(s.touches[0]).normalized.x,n=this.mouseInSlider(s.touches[1]).normalized.x,l=Math.min(i,n),o=Math.max(i,n),a=(t-e)/(o-l);let r=e-l*a,h=t+(1-o)*a;if(a>W){const e=.5*(r+h);r=e-.5*W,h=e+.5*W}if(a<j){const e=.5*(r+h);r=e-.5*j,h=e+.5*j}this.setTimeRange({startTime:r,endTime:h})}else i()},l=()=>{i()};this.sliderElement.addEventListener("touchstart",s,{passive:!1}),this.sliderElement.addEventListener("touchmove",n,{passive:!1}),this.sliderElement.addEventListener("touchend",l),this.sliderElement.addEventListener("touchcancel",l),this.onDestroy.push(()=>{this.sliderElement.removeEventListener("touchstart",s),this.sliderElement.removeEventListener("touchmove",n),this.sliderElement.removeEventListener("touchend",l),this.sliderElement.removeEventListener("touchcancel",l)})}initControls(){const e=new t;this.dragging=!1;let i,s=0,n=0,l=0;e.add(this.initHoverListener());const o=e=>{this.sliderElement.focus(),e.preventDefault();const t=this.mouseInSlider(e);this.zoom(.001*e.deltaY,{x:t.normalized.x})};let a=0,r=-1;const h=e=>{const t=Date.now(),i=t-a;r>=0&&i<300&&i>0&&(this.select(null),e.preventDefault(),this.zoom(-.75,{animate:1e3,x:r})),a=t},d=e=>{e.preventDefault(),this.select(null);const t=this.mouseInSlider(e);this.zoom(-.75,{animate:1e3,x:t.normalized.x})};this.selectingRangeElement.style.pointerEvents="none",this.selectingRangeElement.style.position="absolute",this.selectingRangeElement.style.top="0px";const c=e=>{if(this.sliderElement.focus(),2===e.button||0===e.button){e.preventDefault();const t=this.mouseInSlider(e),i=t.normalized.x,{startTime:o,duration:a}=this.getTimeRange();s=o+i*a,n=Date.now(),l=t.absolute.x,(e.ctrlKey||2===e.button)&&(this.selectingRange=!0),this.selectingRange?(this.selectingRangeElement.style.left=t.absolute.x+"px",this.selectingRangeElement.style.width="0px",this.selectingRangeElement.style.top=this.sliderElement.style.top||"0px",this.selectingRangeElement.style.height=this.sliderElement.style.height||"100%",this.container.appendChild(this.selectingRangeElement),this.selectingRangeVisible=!0):this.dragging=!0}},m=e=>{const t=this.mouseInSlider(e);return i=t.normalized.x,t},g=e=>{const t=m(e);if(this.selectingRange){const e=Math.abs(l-t.absolute.x),i=Math.min(l,t.absolute.x);this.selectingRangeElement.style.left=i+"px",this.selectingRangeElement.style.width=e+"px"}if(!this.dragging||Date.now()-n<100&&Math.abs(l-t.absolute.x)<10)return;e.preventDefault();const i=t.normalized.x,{startTime:o,endTime:a}=this.getTimeRange(),r=o+i*(a-o)-s;this.setTimeRange({startTime:o-r,endTime:a-r})},u=e=>{const t=this.getSliderBounds(),n=t.height-(e.clientY-t.top);if(!this.dragging&&!this.pinching&&n<8)this.ticksBar.click(e);else if(i=void 0,this.dragging=!1,this.selectingRange){const t=this.mouseInSlider(e).normalized.x,{startTime:i,endTime:n}=this.getTimeRange(),l=i+t*(n-i);"zoom"===this.selectRangeMode&&this.fit({range:{startTime:Math.min(s,l),endTime:Math.max(s,l)},animate:1e3}),"select"===this.selectRangeMode&&this.select(null,{startTime:Math.min(s,l),endTime:Math.max(s,l)}),"createSelection"===this.selectRangeMode&&this.setSelection([...this.getSelection(),{startTime:Math.min(s,l),endTime:Math.max(s,l)}])}this.stopSelectingRange()},p=e=>{this.pressedKeys.add(e.code)},y=e=>{this.pressedKeys.delete(e.code),"Space"===e.code&&(e.preventDefault(),this.togglePlaying()),"KeyF"===e.code&&(e.preventDefault(),this.fit({animate:3e3}));const t=void 0;"ArrowRight"===e.code&&(e.preventDefault(),this.skip(1,{animate:t})),"ArrowLeft"===e.code&&(e.preventDefault(),this.skip(-1,{animate:t})),"ArrowUp"===e.code&&(e.preventDefault(),this.up({animate:t})),"ArrowDown"===e.code&&(e.preventDefault(),this.down({xRatio:i,animate:t}))};let T=!0;const v=()=>{if(T){const e=this.pressedKeys.has("ShiftLeft")?.05:.01,t=2*e,s=this.pressedKeys.has("KeyD"),n=this.pressedKeys.has("KeyA");s&&this.shift(-e),n&&this.shift(e),this.pressedKeys.has("KeyW")&&this.zoom(-t,{x:s||n?void 0:i}),this.pressedKeys.has("KeyS")&&this.zoom(t,{x:s||n?void 0:i}),requestAnimationFrame(v)}};v(),e.add(()=>T=!1);const f=e=>e.preventDefault();this.sliderElement.addEventListener("contextmenu",f),this.sliderElement.addEventListener("wheel",o),this.sliderElement.addEventListener("pointerdown",c),this.sliderElement.addEventListener("pointermove",g),this.sliderElement.addEventListener("pointerup",u),this.sliderElement.addEventListener("dblclick",d),this.sliderElement.addEventListener("touchend",h),this.sliderElement.addEventListener("touchstart",e=>{if(1===e.touches.length){const t=this.mouseInSlider(e.touches[0]);r=t.normalized.x}else r=-1}),this.sliderElement.addEventListener("keydown",p),this.sliderElement.addEventListener("keyup",y),this.addHorizontalPinchZoom();const x=()=>{this.sliderElement.removeEventListener("contextmenu",f),this.sliderElement.removeEventListener("wheel",o),this.sliderElement.removeEventListener("pointerdown",c),this.sliderElement.removeEventListener("pointermove",g),this.sliderElement.removeEventListener("pointerup",u),this.sliderElement.removeEventListener("dblclick",d),this.sliderElement.removeEventListener("touchend",h),this.sliderElement.removeEventListener("keydown",p),this.sliderElement.removeEventListener("keyup",y)};return this.onDestroy.push(x),e.add(x),e.disposeLater()}shift(e,t){const{startTime:i,endTime:s,duration:n}=this.getTimeRange(),l=t?.absolute?e:e*n;this.fit({...t,range:{startTime:i-l,endTime:s-l}})}zoom(e,t){const i="number"==typeof t?.x?t.x:.5,{startTime:s,endTime:n,duration:l}=this.getTimeRange(),o={startTime:s-e*l*i,endTime:n+e*l*(1-i)},a=o.endTime-o.startTime,r=o.startTime+.5*a;a>W&&(o.startTime=r-.5*W,o.endTime=r+.5*W),a<j&&(o.startTime=r-.5*j,o.endTime=r+.5*j),this.fit({range:o,animate:t?.animate})}togglePlaying(){this.playing?this.pause():this.play()}isPlaying(){return this.playing}play(){if(this.playing)return;this.playing=!0,this.emit("playing",!0);let e=Date.now();const t=()=>{if(this.playing){if(this.live){const{duration:e}=this.getTimeRange(),t=Date.now(),i=10/this.size.width;this.setTimeRange({startTime:t-(1-i)*e,endTime:t+i*e}),this.setCurrent(t)}else if("auto"!==this.playSpeed||this.showCurrent){const t=Date.now(),i=t-e,s=this.current-this.getTimeRange().startTime,n="auto"===this.playSpeed?1:this.playSpeed;this.shift(-n*i,{absolute:!0}),this.setCurrent(this.getTimeRange().startTime+s),e=t}else{const t=Date.now();let i=5e-5*(t-e);this.pressedKeys.has("ShiftLeft")&&(i*=5);const s=this.current-this.getTimeRange().startTime;this.shift(-i),this.setCurrent(this.getTimeRange().startTime+s),e=t}requestAnimationFrame(t)}};t()}setCurrent(e){this.current!==e&&(Math.abs(e-Date.now())>100&&this.live&&(this.pause(),this.setLive(!1)),this.current=e,this.emit("current",e))}pause(){this.playing&&(this.playing=!1,this.emit("playing",!1),this.setLive(!1))}setLive(e){if(this.live!==e){if(this.live=e,e){const e=this.getTimeRange();this.fit({range:{startTime:e.endTime-this.liveRange,endTime:e.endTime},animate:_}),this.play()}this.emit("live",e)}}}function K(e){return{startTime:"number"==typeof e?.startTime?e.startTime:"number"==typeof e?.endTime?e.duration?e.endTime-e.duration:e.endTime-M:e?.duration?Date.now()-.5*e.duration:Date.now()-.5*M,endTime:"number"==typeof e?.endTime?e.endTime:"number"==typeof e?.startTime?e.duration?e.startTime+e.duration:e.startTime+M:e?.duration?Date.now()+.5*e.duration:Date.now()+.5*M,duration:e?.duration?e.duration:"number"==typeof e?.startTime&&"number"==typeof e?.endTime?e.endTime+e.startTime:M,minValue:"number"==typeof e?.minValue?e.minValue:"number"==typeof e?.maxValue?e.maxValue>0?0:e.maxValue-100:0,maxValue:"number"==typeof e?.maxValue?e.maxValue:"number"==typeof e?.minValue?e.minValue<0?0:e.minValue+100:100}}const X=_,N={en:{next:"Next {span}",previous:"Previous {span}",nextUnit:"Next {unit}",previousUnit:"Previous {unit}"},de:{next:"Weiter: {span}",previous:"Zurück: {span}"},fr:{next:"Suivant : {span}",previous:"Précédent : {span}"},nl:{next:"Volgende: {span}",previous:"Vorige: {span}"}};function G(e,t,i){const s=N[i.split("-")[0].toLowerCase()];if(!s)return(e>0?"→ ":"← ")+t.text;const n=e>0?s.nextUnit:s.previousUnit;return n&&t.unitName?n.replace("{unit}",t.unitName):(e>0?s.next:s.previous).replace("{span}",t.text)}function Q(e){const t=e/315576e5,i=Math.log10(t),s=Math.ceil(i);return Math.pow(10,s)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@protomaze/time",
3
- "version": "1.8.3",
3
+ "version": "1.9.0",
4
4
  "description": "Protomaze Time sliders",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1 +1 @@
1
- import e,{forwardRef as t,useCallback as n,useEffect as r,useImperativeHandle as i,useLayoutEffect as a,useMemo as o,useRef as l,useState as s}from"react";import{Disposables as c}from"../common/Disposables.js";import{formatDuration as m}from"../common/TimeTools.js";import{TimeSlider as d}from"../engine/TimeSlider.js";import{ONE_YEAR as p}from"../ticks/TimeSliderConstants.js";import{ColoredSlider as u}from"./ColoredSlider.js";import{DateLabelWithPicker as g}from"./DateLabelWithPicker.js";import{DateRangeLabelWithPicker as h}from"./DateRangeLabelWithPicker.js";import{MaterialIconButton as f}from"./MaterialIconButton.js";import{MaterialTextButton as y}from"./MaterialTextButton.js";import{TimeLabelWithPicker as w}from"./TimeLabelWithPicker.js";const x={padding:"4px 8px",background:"#0008",borderRadius:"4px",color:"#fff",fontFamily:"monospace",fontSize:"12px"},b=[Date.now()-p,Date.now()];function k(e,t){return e[0]===t[0]&&e[1]===t[1]}function v(e){return JSON.stringify(e)}export const ReactTimeSlider=t(({timeRange:t,onTimeRange:n,selectRangeButton:a,noPlayButton:p,noTimeLabels:E,noRangeLabel:C,noDateLabels:L,theme:S,canHideLabels:R,verticalGap:N,engine:I,layers:_,loaders:z,showStats:D,currentSlider:j,...M},O)=>{const P=o(()=>new d(M),[]);r(()=>{M?.showCurrent&&(P.showCurrent=M?.showCurrent)},[M.showCurrent]),r(()=>{M?.showTicks&&(P.showTicks=M?.showTicks)},[M.showTicks]),r(()=>{M?.playSpeed&&(P.playSpeed=M?.playSpeed)},[M.playSpeed]),r(()=>{M?.liveRange&&(P.liveRange=M?.liveRange)},[M.liveRange]),r(()=>{M?.locale&&P.setLocale(M.locale)},[M.locale]),r(()=>{M?.weekLabel&&P.setWeekLabel(M.weekLabel,M.weekLabelPrefix)},[M.weekLabel,M.weekLabelPrefix]),r(()=>{P.setTickLabelStyler(M?.tickLabelStyler)},[M.tickLabelStyler]),r(()=>{P.setLimits(M?.limits)},[M.limits?.startTime,M.limits?.endTime]),r(()=>{P.setFont(M?.font)},[M.font?.family,M.font?.weight,M.font?.size]),r(()=>{P.setBackground(M?.background)},[M.background]),r(()=>{P.setTickTooltip(M?.tickTooltip??!0)},[M.tickTooltip]),r(()=>{P.setTooltipStyle(M?.tooltipStyle??{})},[JSON.stringify(M.tooltipStyle??{})]),r(()=>{P.setGridOrder(M?.gridOrder??"front")},[M.gridOrder]),r(()=>{P.setSelectingRangeStyle(M?.selectingRangeStyle??{})},[M.selectingRangeStyle?.background,M.selectingRangeStyle?.border]);const[,B]=s(0);r(()=>P.on("locale",()=>B(e=>e+1)),[P]);const W=N||4,F=22+W+8+"px",G=22+W+22+W+8+"px",H=l(null),X=l(null),A=l(null),[J,U]=s(!1),[V,Y]=s(!1),[$,q]=s(!1),[K,Q]=s(!1),[Z,ee]=s(!1),[te,ne]=s(Date.now()),re=l(null);useMaterialIcons();const[ie,ae]=s(t||b),oe=l(t||b),le=void 0!==t,se=l(new Set),[ce,me]=s(!1);r(()=>{if(le){const e=v(t);if(J&&!k(t,oe.current)&&!se.current.has(e)){oe.current=t;const[e,n]=t;P.setTimeRange({startTime:e,endTime:n})}se.current.delete(e)}},[J,t,le]),r(()=>{const e=new c;return e.add(P.on("time",e=>{const{startTime:t,endTime:r}=e,i=[t,r];k(i,oe.current)||(oe.current=i,se.current.add(v(i)),ae(i),n?.(i))})),e.disposeLater()},[P]),r(()=>{U(!1);const e=new c;return P.init(X.current).then(()=>U(!0)),e.add(P.on("time",e=>{if(e.startTime!==oe.current[0]||e.endTime!==oe.current[1]){const{startTime:t,endTime:r}=e,i=[t,r];oe.current=i,ae(i),n?.(i)}})),e.add(P.on("playing",Y)),e.add(P.on("live",q)),e.add(P.on("current",ne)),e.disposeLater()},[P]),r(()=>{z?.forEach(e=>P.addLayerLoader(e))},[z]),r(()=>{"boolean"==typeof M.showCurrent&&(P.showCurrent=M.showCurrent)},[M.showCurrent]),i(O,()=>({get timeSlider(){return P}})),r(()=>{if(M.showCurrent){const e=setInterval(()=>{A.current&&(A.current.available=Date.now())},10);return()=>clearInterval(e)}},[M.showCurrent]),r(()=>{J&&P.showStats(!0===D)},[J,D]),r(()=>{},[J]),r(()=>{J&&P.setEngine(I)},[J,I]),r(()=>{if(J){const e=new Set,t=new Set;P.getLayers().forEach(e=>t.add(e.id)),_.forEach(n=>{t.delete(n.id),e.add(n.id)}),P.getLayers().forEach(t=>e.delete(t.id));const n=_.filter(t=>e.has(t.id)),r=P.getLayers().filter(e=>t.has(e.id));r.length===P.getLayers().length&&n.length>0&&P.setTimeRange(n[0].model.getTimeRange()),r.forEach(e=>P.removeLayer(e)),n.forEach(e=>P.addLayer(e))}},[J,_]);r(()=>{const e=e=>{re.current&&e.target&&e.target.parentElement?.getAttribute("layerpanelbutton")!==P.id&&!re.current.contains(e.target)&&ee(!1)};if(Z)return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[Z]);const de=e=>{const t=P.current,{duration:n,startTime:r}=P.getTimeRange(),i=(t-r)/n;i>1||i<0?P.setTimeRange({startTime:e-.5*n,endTime:e+.5*n}):P.setTimeRange({startTime:e-i*n,endTime:e+(1-i)*n}),P.setCurrent(e)};r(()=>{const e=()=>{if(H.current){let e=560;M.showCurrent&&(e+=160),p&&(e-=30),C&&(e-=160),E&&(e-=140),L&&(e-=185);const t=H.current.getBoundingClientRect().width;Q(t<e)}};e();const t=new ResizeObserver(e);return H.current&&t.observe(H.current),window.addEventListener("resize",e),()=>{t.disconnect(),window.removeEventListener("resize",e)}},[M.showCurrent,p,C,E,L]);let pe=42;M.showCurrent&&(pe+=4),K&&!R&&(pe+=26);const ue="dark"===S;return r(()=>{S&&P.setTheme(S)},[S]),e.createElement("div",{ref:H,style:{display:"block",position:"relative",borderRadius:"inherit",background:ue?"#222":"#ddd",width:"100%",height:"100%",padding:"8px",boxSizing:"border-box"}},Z&&e.createElement("div",{ref:re,style:{position:"absolute",top:F,left:"8px",maxWidth:"200px",display:"flex",gap:"8px",alignItems:"center",paddingRight:"8px",paddingBottom:"8px",paddingTop:"8px",flexDirection:"column",zIndex:1e3,background:ue?"#222":"#ddd"}},P.getLayers().map(t=>e.createElement(T,{key:t.id,layer:t,timeSlider:P,isDarkMode:ue}))),e.createElement("div",{style:{position:"absolute",top:"8px",left:"8px",display:"flex",gap:"8px",alignItems:"center"}},e.createElement(f,{layerpanelbutton:P.id,iconName:"layers",onClick:e=>ee(e=>!e)}),e.createElement(f,{iconName:"skip_previous",onClick:()=>P.up({animate:1e3}),rotate:90}),!K&&!C&&e.createElement("span",{style:{...x}},m(ie)),e.createElement(f,{iconName:"arrow_range",onClick:()=>P.fit({animate:3e3})}),a&&e.createElement(f,{iconName:"ink_selection",active:ce,onClick:()=>{me(!0),P.startSelectingRange(()=>me(!1))}})),K&&!R&&M.showCurrent&&!C&&e.createElement("div",{style:{position:"absolute",top:F,left:"8px",display:"flex",gap:"8px",height:"22px"}},e.createElement("span",{style:{...x}},m(ie))),K&&!R&&!M.showCurrent&&!C&&e.createElement("div",{style:{position:"absolute",top:"8px",left:"50%",transform:"translateX(-50%)",display:"flex",gap:"8px",height:"22px"}},e.createElement("span",{style:{...x}},m(ie))),(!K||!R)&&e.createElement("div",{style:{position:"absolute",top:K?F:"8px",right:K?"8px":"50%",transform:K?void 0:"translateX(50%)",padding:0,display:"flex",gap:"8px",height:"22px",width:!K||M.showCurrent?void 0:"calc(100% - 16px)"}},!M.showCurrent&&(!E||!E)&&e.createElement(e.Fragment,null,!E&&e.createElement(w,{theme:S,time:ie[0],setTime:e=>P.setTimeRange({startTime:e})}),K&&!E&&!L&&!M.showCurrent&&e.createElement("div",{style:{flexGrow:1}}),!L&&e.createElement(h,{theme:S,range:[ie[0],ie[1]],setRange:e=>P.setTimeRange({startTime:e[0],endTime:e[1]})}),K&&!E&&!L&&!M.showCurrent&&e.createElement("div",{style:{flexGrow:1}}),!E&&e.createElement(w,{theme:S,time:ie[1]-1,setTime:e=>P.setTimeRange({endTime:e+1})})),M.showCurrent&&e.createElement(e.Fragment,null,!L&&e.createElement(g,{theme:S,time:te,setTime:de}),!E&&e.createElement(w,{theme:S,time:te,setTime:de}))),e.createElement("div",{style:{position:"absolute",top:"8px",right:"8px",display:"flex",gap:"8px",alignItems:"center"}},M.showCurrent&&e.createElement(e.Fragment,null,e.createElement(y,{text:"Live",onClick:()=>{P.live?P.pause():P.setLive(!0)},color:$?"#fff":ue?"#888":"#bbb"},e.createElement("span",{className:"material-symbols-outlined",style:{fontSize:"18px",zIndex:1,lineHeight:1}},"radio_button_unchecked"),$&&e.createElement("span",{className:"material-symbols-outlined",style:{fontSize:"18px",lineHeight:1,marginLeft:"-24px",color:"red"}},"radio_button_checked"))),e.createElement(f,{iconName:"skip_previous",onClick:()=>P.previous({animate:1e3})}),!p&&!V&&e.createElement(f,{iconName:"play_arrow",onClick:()=>P.play()}),!p&&V&&e.createElement(f,{iconName:"pause",onClick:()=>P.pause()}),e.createElement(f,{iconName:"skip_next",onClick:()=>P.next({animate:1e3})})),M.showCurrent&&e.createElement(u,{ref:A,value:te,min:ie[0],max:ie[1],onValue:e=>{P.pause(),P.setCurrent(e)},onPointerMove:e=>P.updateHover({x:e.clientX,y:e.clientY}),onPointerLeave:()=>P.updateHover(null),matchWidth:!0,style:{width:"calc(100% - 16px)",left:"8px",position:"absolute",bottom:"26px",zIndex:1},...j}),e.createElement("div",{ref:X,style:{position:"absolute",top:K&&!R?G:F,left:"8px",borderRadius:"inherit",width:"calc(100% - 16px)",height:`calc(100% - ${pe}px)`,background:M.background??(ue?"#111":"#eee"),overflow:"hidden"}}))});function T({layer:t,timeSlider:n,isDarkMode:i}){const[a,o]=s(t.visible);return r(()=>{t.on("visible",e=>o(e))},[]),e.createElement("div",{style:{display:"flex",gap:"8px",alignItems:"center",background:i?"#222":"#ddd",borderRadius:"4px",width:"100%"}},a&&e.createElement(f,{iconName:"visibility",onClick:()=>t.visible=!1}),!a&&e.createElement(f,{iconName:"visibility_off",color:"#888",onClick:()=>t.visible=!0}),e.createElement("span",{style:{...x,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flexGrow:1,minWidth:0}},t.name||t.constructor.name+"#"+t.id.slice(t.id.length-4).toUpperCase()),e.createElement(f,{iconName:"center_focus_weak",onClick:()=>n.fit({animate:3e3,range:t.model.getTimeRange()})}))}export function useMaterialIcons(e="outlined"){r(()=>{const e=document.createElement("link");return e.rel="stylesheet",e.href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200",document.head.appendChild(e),()=>{document.head.removeChild(e)}},[e])}
1
+ import e,{forwardRef as t,useCallback as n,useEffect as r,useImperativeHandle as i,useLayoutEffect as o,useMemo as a,useRef as l,useState as s}from"react";import{Disposables as c}from"../common/Disposables.js";import{formatDuration as d}from"../common/TimeTools.js";import{TimeSlider as m}from"../engine/TimeSlider.js";import{ONE_YEAR as p}from"../ticks/TimeSliderConstants.js";import{ColoredSlider as u}from"./ColoredSlider.js";import{DateLabelWithPicker as g}from"./DateLabelWithPicker.js";import{DateRangeLabelWithPicker as h}from"./DateRangeLabelWithPicker.js";import{MaterialIconButton as f}from"./MaterialIconButton.js";import{MaterialTextButton as y}from"./MaterialTextButton.js";import{TimeLabelWithPicker as w}from"./TimeLabelWithPicker.js";const x={padding:"4px 8px",background:"#0008",borderRadius:"4px",color:"#fff",fontFamily:"monospace",fontSize:"12px"},b=[Date.now()-p,Date.now()];function k(e,t){return e[0]===t[0]&&e[1]===t[1]}function v(e){return JSON.stringify(e)}export const ReactTimeSlider=t(({timeRange:t,onTimeRange:n,selectRangeButton:o,noPlayButton:p,noTimeLabels:T,noRangeLabel:S,noDateLabels:C,theme:L,canHideLabels:R,verticalGap:N,engine:I,layers:_,loaders:z,showStats:D,currentSlider:O,...M},j)=>{const P=a(()=>new m(M),[]);r(()=>{M?.showCurrent&&(P.showCurrent=M?.showCurrent)},[M.showCurrent]),r(()=>{M?.showTicks&&(P.showTicks=M?.showTicks)},[M.showTicks]),r(()=>{M?.playSpeed&&(P.playSpeed=M?.playSpeed)},[M.playSpeed]),r(()=>{M?.liveRange&&(P.liveRange=M?.liveRange)},[M.liveRange]),r(()=>{M?.locale&&P.setLocale(M.locale)},[M.locale]),r(()=>{M?.weekLabel&&P.setWeekLabel(M.weekLabel,M.weekLabelPrefix)},[M.weekLabel,M.weekLabelPrefix]),r(()=>{P.setTickLabelStyler(M?.tickLabelStyler)},[M.tickLabelStyler]),r(()=>{P.setLimits(M?.limits)},[M.limits?.startTime,M.limits?.endTime]),r(()=>{P.setFont(M?.font)},[M.font?.family,M.font?.weight,M.font?.size]),r(()=>{P.setBackground(M?.background)},[M.background]),r(()=>{P.setTickTooltip(M?.tickTooltip??!0)},[M.tickTooltip]),r(()=>{P.setTooltipStyle(M?.tooltipStyle??{})},[JSON.stringify(M.tooltipStyle??{})]),r(()=>{P.setGridOrder(M?.gridOrder??"front")},[M.gridOrder]),r(()=>{P.setSelectingRangeStyle(M?.selectingRangeStyle??{})},[M.selectingRangeStyle?.background,M.selectingRangeStyle?.border]),r(()=>{P.setSelectionEditMode(M?.selectionEditMode??"always")},[M.selectionEditMode]),r(()=>{P.setSelectionStyle(M?.selectionStyle??{})},[JSON.stringify(M.selectionStyle??{})]),r(()=>{P.setSelectionOrder(M?.selectionOrder??"front")},[M.selectionOrder]);const[,B]=s(0);r(()=>P.on("locale",()=>B(e=>e+1)),[P]);const W=N||4,F=22+W+8+"px",G=22+W+22+W+8+"px",H=l(null),J=l(null),X=l(null),[A,U]=s(!1),[V,Y]=s(!1),[$,q]=s(!1),[K,Q]=s(!1),[Z,ee]=s(!1),[te,ne]=s(Date.now()),re=l(null);useMaterialIcons();const[ie,oe]=s(t||b),ae=l(t||b),le=void 0!==t,se=l(new Set),[ce,de]=s(!1);r(()=>{if(le){const e=v(t);if(A&&!k(t,ae.current)&&!se.current.has(e)){ae.current=t;const[e,n]=t;P.setTimeRange({startTime:e,endTime:n})}se.current.delete(e)}},[A,t,le]),r(()=>{const e=new c;return e.add(P.on("time",e=>{const{startTime:t,endTime:r}=e,i=[t,r];k(i,ae.current)||(ae.current=i,se.current.add(v(i)),oe(i),n?.(i))})),e.disposeLater()},[P]),r(()=>{U(!1);const e=new c;return P.init(J.current).then(()=>U(!0)),e.add(P.on("time",e=>{if(e.startTime!==ae.current[0]||e.endTime!==ae.current[1]){const{startTime:t,endTime:r}=e,i=[t,r];ae.current=i,oe(i),n?.(i)}})),e.add(P.on("playing",Y)),e.add(P.on("live",q)),e.add(P.on("current",ne)),e.disposeLater()},[P]),r(()=>{z?.forEach(e=>P.addLayerLoader(e))},[z]),r(()=>{"boolean"==typeof M.showCurrent&&(P.showCurrent=M.showCurrent)},[M.showCurrent]),i(j,()=>({get timeSlider(){return P}})),r(()=>{if(M.showCurrent){const e=setInterval(()=>{X.current&&(X.current.available=Date.now())},10);return()=>clearInterval(e)}},[M.showCurrent]),r(()=>{A&&P.showStats(!0===D)},[A,D]),r(()=>{},[A]),r(()=>{A&&P.setEngine(I)},[A,I]),r(()=>{if(A){const e=new Set,t=new Set;P.getLayers().forEach(e=>t.add(e.id)),_.forEach(n=>{t.delete(n.id),e.add(n.id)}),P.getLayers().forEach(t=>e.delete(t.id));const n=_.filter(t=>e.has(t.id)),r=P.getLayers().filter(e=>t.has(e.id));r.length===P.getLayers().length&&n.length>0&&P.setTimeRange(n[0].model.getTimeRange()),r.forEach(e=>P.removeLayer(e)),n.forEach(e=>P.addLayer(e))}},[A,_]);r(()=>{const e=e=>{re.current&&e.target&&e.target.parentElement?.getAttribute("layerpanelbutton")!==P.id&&!re.current.contains(e.target)&&ee(!1)};if(Z)return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[Z]);const me=e=>{const t=P.current,{duration:n,startTime:r}=P.getTimeRange(),i=(t-r)/n;i>1||i<0?P.setTimeRange({startTime:e-.5*n,endTime:e+.5*n}):P.setTimeRange({startTime:e-i*n,endTime:e+(1-i)*n}),P.setCurrent(e)};r(()=>{const e=()=>{if(H.current){let e=560;M.showCurrent&&(e+=160),p&&(e-=30),S&&(e-=160),T&&(e-=140),C&&(e-=185);const t=H.current.getBoundingClientRect().width;Q(t<e)}};e();const t=new ResizeObserver(e);return H.current&&t.observe(H.current),window.addEventListener("resize",e),()=>{t.disconnect(),window.removeEventListener("resize",e)}},[M.showCurrent,p,S,T,C]);let pe=42;M.showCurrent&&(pe+=4),K&&!R&&(pe+=26);const ue="dark"===L;return r(()=>{L&&P.setTheme(L)},[L]),e.createElement("div",{ref:H,style:{display:"block",position:"relative",borderRadius:"inherit",background:ue?"#222":"#ddd",width:"100%",height:"100%",padding:"8px",boxSizing:"border-box"}},Z&&e.createElement("div",{ref:re,style:{position:"absolute",top:F,left:"8px",maxWidth:"200px",display:"flex",gap:"8px",alignItems:"center",paddingRight:"8px",paddingBottom:"8px",paddingTop:"8px",flexDirection:"column",zIndex:1e3,background:ue?"#222":"#ddd"}},P.getLayers().map(t=>e.createElement(E,{key:t.id,layer:t,timeSlider:P,isDarkMode:ue}))),e.createElement("div",{style:{position:"absolute",top:"8px",left:"8px",display:"flex",gap:"8px",alignItems:"center"}},e.createElement(f,{layerpanelbutton:P.id,iconName:"layers",onClick:e=>ee(e=>!e)}),e.createElement(f,{iconName:"skip_previous",onClick:()=>P.up({animate:1e3}),rotate:90}),!K&&!S&&e.createElement("span",{style:{...x}},d(ie)),e.createElement(f,{iconName:"arrow_range",onClick:()=>P.fit({animate:3e3})}),o&&e.createElement(f,{iconName:"ink_selection",active:ce,onClick:()=>{de(!0),P.startSelectingRange(()=>de(!1))}})),K&&!R&&M.showCurrent&&!S&&e.createElement("div",{style:{position:"absolute",top:F,left:"8px",display:"flex",gap:"8px",height:"22px"}},e.createElement("span",{style:{...x}},d(ie))),K&&!R&&!M.showCurrent&&!S&&e.createElement("div",{style:{position:"absolute",top:"8px",left:"50%",transform:"translateX(-50%)",display:"flex",gap:"8px",height:"22px"}},e.createElement("span",{style:{...x}},d(ie))),(!K||!R)&&e.createElement("div",{style:{position:"absolute",top:K?F:"8px",right:K?"8px":"50%",transform:K?void 0:"translateX(50%)",padding:0,display:"flex",gap:"8px",height:"22px",width:!K||M.showCurrent?void 0:"calc(100% - 16px)"}},!M.showCurrent&&(!T||!T)&&e.createElement(e.Fragment,null,!T&&e.createElement(w,{theme:L,time:ie[0],setTime:e=>P.setTimeRange({startTime:e})}),K&&!T&&!C&&!M.showCurrent&&e.createElement("div",{style:{flexGrow:1}}),!C&&e.createElement(h,{theme:L,range:[ie[0],ie[1]],setRange:e=>P.setTimeRange({startTime:e[0],endTime:e[1]})}),K&&!T&&!C&&!M.showCurrent&&e.createElement("div",{style:{flexGrow:1}}),!T&&e.createElement(w,{theme:L,time:ie[1]-1,setTime:e=>P.setTimeRange({endTime:e+1})})),M.showCurrent&&e.createElement(e.Fragment,null,!C&&e.createElement(g,{theme:L,time:te,setTime:me}),!T&&e.createElement(w,{theme:L,time:te,setTime:me}))),e.createElement("div",{style:{position:"absolute",top:"8px",right:"8px",display:"flex",gap:"8px",alignItems:"center"}},M.showCurrent&&e.createElement(e.Fragment,null,e.createElement(y,{text:"Live",onClick:()=>{P.live?P.pause():P.setLive(!0)},color:$?"#fff":ue?"#888":"#bbb"},e.createElement("span",{className:"material-symbols-outlined",style:{fontSize:"18px",zIndex:1,lineHeight:1}},"radio_button_unchecked"),$&&e.createElement("span",{className:"material-symbols-outlined",style:{fontSize:"18px",lineHeight:1,marginLeft:"-24px",color:"red"}},"radio_button_checked"))),e.createElement(f,{iconName:"skip_previous",onClick:()=>P.previous({animate:1e3})}),!p&&!V&&e.createElement(f,{iconName:"play_arrow",onClick:()=>P.play()}),!p&&V&&e.createElement(f,{iconName:"pause",onClick:()=>P.pause()}),e.createElement(f,{iconName:"skip_next",onClick:()=>P.next({animate:1e3})})),M.showCurrent&&e.createElement(u,{ref:X,value:te,min:ie[0],max:ie[1],onValue:e=>{P.pause(),P.setCurrent(e)},onPointerMove:e=>P.updateHover({x:e.clientX,y:e.clientY}),onPointerLeave:()=>P.updateHover(null),matchWidth:!0,style:{width:"calc(100% - 16px)",left:"8px",position:"absolute",bottom:"26px",zIndex:1},...O}),e.createElement("div",{ref:J,style:{position:"absolute",top:K&&!R?G:F,left:"8px",borderRadius:"inherit",width:"calc(100% - 16px)",height:`calc(100% - ${pe}px)`,background:M.background??(ue?"#111":"#eee"),overflow:"hidden"}}))});function E({layer:t,timeSlider:n,isDarkMode:i}){const[o,a]=s(t.visible);return r(()=>{t.on("visible",e=>a(e))},[]),e.createElement("div",{style:{display:"flex",gap:"8px",alignItems:"center",background:i?"#222":"#ddd",borderRadius:"4px",width:"100%"}},o&&e.createElement(f,{iconName:"visibility",onClick:()=>t.visible=!1}),!o&&e.createElement(f,{iconName:"visibility_off",color:"#888",onClick:()=>t.visible=!0}),e.createElement("span",{style:{...x,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flexGrow:1,minWidth:0}},t.name||t.constructor.name+"#"+t.id.slice(t.id.length-4).toUpperCase()),e.createElement(f,{iconName:"center_focus_weak",onClick:()=>n.fit({animate:3e3,range:t.model.getTimeRange()})}))}export function useMaterialIcons(e="outlined"){r(()=>{const e=document.createElement("link");return e.rel="stylesheet",e.href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200",document.head.appendChild(e),()=>{document.head.removeChild(e)}},[e])}