@deephaven/embed-chart 0.38.1-beta.3 → 0.38.1-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/assets/App-2fd87eab.js +2 -0
- package/build/assets/App-2fd87eab.js.map +1 -0
- package/build/assets/{index-f4dac3e2.js → index-11136157.js} +7 -7
- package/build/assets/{index-f4dac3e2.js.map → index-11136157.js.map} +1 -1
- package/build/assets/{index-96fe7399.js → index-9192b18a.js} +2 -2
- package/build/assets/{index-96fe7399.js.map → index-9192b18a.js.map} +1 -1
- package/build/assets/useConnection-87b8bdaa.js +2 -0
- package/build/assets/useConnection-87b8bdaa.js.map +1 -0
- package/build/index.html +1 -1
- package/package.json +14 -14
- package/build/assets/App-e99c3dcf.js +0 -2
- package/build/assets/App-e99c3dcf.js.map +0 -1
- package/build/assets/useConnection-1368e513.js +0 -2
- package/build/assets/useConnection-1368e513.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var de=Object.defineProperty;var he=(f,t,e)=>t in f?de(f,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):f[t]=e;var h=(f,t,e)=>(he(f,typeof t!="symbol"?t+"":t,e),e);import{A as v,G as $,C as T,E as B,F as J}from"./vendor-c6328e9a.js";import{q as me,L as H,w as fe,x as pe,b as ge}from"./index-9192b18a.js";function X(f,t="No value available in context. Was code wrapped in a provider?"){const e=v.useContext(f);if(e==null)throw new Error(t);return e}class Te extends Error{constructor(){super(...arguments);h(this,"isCanceled",!0)}}const _=Te;class Me extends Error{constructor(){super(...arguments);h(this,"isTimeout",!0)}}const ne=Me;class z{static makeCancelable(t,e){let n=!1,r,s;const a=new Promise((l,i)=>{s=i,Promise.resolve(t).then(o=>{n?e&&e(o):(r=o,l(o))}).catch(o=>i(o))});return a.cancel=()=>{n=!0,s(new _),r!=null&&e&&e(r)},a}static isCanceled(t){return t instanceof _}static isTimedOut(t){return t instanceof ne}static withTimeout(t,e){return new Promise((n,r)=>{setTimeout(()=>{try{n(e())}catch(s){r(s)}},t)})}}function We(f){if(f==null)throw new Error("Value is null or undefined")}class Se{static join(t,e="and"){if(t==null||t.length===0)return"";if(t.length===1)return t[0];if(t.length===2)return`${t[0]} ${e} ${t[1]}`;const n=t.slice(0,t.length-1).join(", "),r=t[t.length-1];return`${n}, ${e} ${r}`}static toLower(t,e=!0){if(t==null){if(e)return"";throw new Error("Null string passed in to TextUtils.toLower")}return t.toLowerCase()}static sort(t,e,n=!0){return t<e?n?-1:1:t>e?n?1:-1:0}}const ye=Se;function Ue(f){return f.then!==void 0}const O=class{static disableAllActions(){O.actionsDisabled=!0}static enableAllActions(){O.actionsDisabled=!1}static isContextActionEvent(t){return Array.isArray(t.contextActions)}static compareActions(t,e){return t.group!==e.group?(t.group??0)>(e.group??0)?1:-1:t.order!==e.order?(t.order??0)>(e.order??0)?1:-1:t.title!==e.title?(t.title??"")>(e.title??"")?1:-1:t!==e?t>e?1:-1:0}static sortActions(t){if(t==null||!Array.isArray(t))return[];const e=t.slice();return e.sort(O.compareActions),e}static isMacPlatform(){const{platform:t}=window.navigator;return t.startsWith("Mac")}static getModifierKey(){return O.isMacPlatform()?"metaKey":"ctrlKey"}static isModifierKeyDown(t){const e=O.getModifierKey();return t[e]}static getMenuItems(t,e=!0){let n=[],r=t;Array.isArray(r)||(r=[r]);for(let s=0;s<r.length;s+=1){const a=r[s];let l;typeof a=="function"?l=a():l=a,l!=null&&(l instanceof Promise?e&&n.push(l):Array.isArray(l)?n=n.concat(l):n.push(l))}return n=n.filter(s=>s.title!==void 0||s.then!=null||s.menuElement),n}static getNextMenuItem(t,e,n){let r=t;r<0&&e<0&&(r=n.length);for(let s=1;s<n.length+1;s+=1){const a=(r+e*s+n.length)%n.length,l=n[a];if(!(l instanceof Promise)&&l.disabled!==!0)return a}return t}};let U=O;h(U,"actionsDisabled",!1);const A=U,Z=$.forwardRef((f,t)=>{var R;function e(g){const{menuItem:N,onMenuItemClick:S}=f;S(N,g)}function n(g){const{menuItem:N,onMenuItemMouseMove:S}=f;S(N,g)}function r(g){const{menuItem:N,onMenuItemContextMenu:S}=f;S(N,g)}function s(g,N,S){if(typeof g.type=="string")return g;const{closeMenu:L,menuItem:Q,isKeyboardSelected:oe,isMouseSelected:le,"data-testid":ue}=f,ce={menuItem:Q,closeMenu:L,isKeyboardSelected:oe,isMouseSelected:le,iconElement:N,displayShortcut:S,"data-testid":ue};return $.cloneElement(g,{forwardedProps:ce})}const{children:a,menuItem:l,isKeyboardSelected:i=!1,isMouseSelected:o=!1,"data-testid":u}=f,m=(R=l.shortcut)==null?void 0:R.getDisplayText();let p=null;if(l.icon){const g=l.icon;if($.isValidElement(g))p=g;else{let N;l.iconColor!=null&&(l.disabled===void 0||!l.disabled)&&(N={color:l.iconColor}),p=T.jsx(J,{icon:g,style:N})}}let M=null;const y=Boolean(a);l.actions&&(M=T.jsx(J,{icon:me}));let b=null;if(l.menuElement)b=T.jsx("div",{className:"custom-menu-item",onMouseMove:n,children:s(l.menuElement,p,m)});else{const g=l.disabled,N=l.iconOutline;b=T.jsx("button",{type:"button",className:B("btn-context-menu",{disabled:g},{active:(y||o)&&(g===void 0||!g)},{"keyboard-active":i&&(g===void 0||!g)}),onClick:e,onMouseMove:n,onContextMenu:r,title:l.description??"",children:T.jsxs("div",{className:"btn-context-menu-wrapper",children:[T.jsx("span",{className:B("icon",{outline:N}),children:p}),T.jsx("span",{className:"title",children:l.title}),m!==void 0&&T.jsx("span",{className:"shortcut",children:m}),M&&T.jsx("span",{className:B("submenu-indicator",{disabled:g}),children:M})]})})}return T.jsxs("div",{className:"context-menu-item",ref:t,"data-testid":u,children:[a,b]})});Z.displayName="ContextMenuItem";Z.defaultProps={children:null,isKeyboardSelected:!1,isMouseSelected:!1,"data-testid":void 0};const Ee=Z,ee=H.module("ContextMenu"),G=class extends v.PureComponent{constructor(e){super(e);h(this,"container");h(this,"oldFocus");h(this,"activeSubMenuRef");h(this,"subMenuTimer");h(this,"rAF");h(this,"initialPosition");this.handleBlur=this.handleBlur.bind(this),this.handleCloseSubMenu=this.handleCloseSubMenu.bind(this),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleMenuItemClick=this.handleMenuItemClick.bind(this),this.handleMenuItemContextMenu=this.handleMenuItemContextMenu.bind(this),this.handleMenuItemMouseMove=this.handleMenuItemMouseMove.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this),this.handleWindowResize=this.handleWindowResize.bind(this),this.container=$.createRef(),this.oldFocus=document.activeElement,this.activeSubMenuRef=$.createRef(),this.subMenuTimer=0,this.rAF=0,this.initialPosition={top:e.top,left:e.left},this.state={menuItems:[],pendingItems:[],activeSubMenu:null,hasOverflow:!1,subMenuTop:null,subMenuLeft:null,subMenuParentWidth:0,subMenuParentHeight:0,keyboardIndex:-1,mouseIndex:-1}}static handleContextMenu(e){e.metaKey||(e.stopPropagation(),e.preventDefault())}componentDidMount(){this.initMenu(),this.verifyPosition(),window.addEventListener("resize",this.handleWindowResize),this.rAF=window.requestAnimationFrame(()=>{var n;(n=this.container.current)==null||n.focus();const{onMenuOpened:e}=this.props;e(this)})}componentDidUpdate(e,n){var a,l;const{actions:r}=this.props,{activeSubMenu:s}=this.state;s!==n.activeSubMenu&&(s==null?(a=this.container.current)==null||a.focus():this.setActiveSubMenuPosition()),e.actions!==r&&(this.initMenu(),(this.container.current==null||!this.container.current.contains(document.activeElement))&&((l=this.container.current)==null||l.focus())),this.verifyPosition()}componentWillUnmount(){this.cancelPromises(),window.removeEventListener("resize",this.handleWindowResize),cancelAnimationFrame(this.rAF)}getKeyboardIndex(){const{options:e}=this.props;if(e.separateKeyboardMouse!==void 0&&e.separateKeyboardMouse){const{keyboardIndex:n}=this.state;return n}return this.getMouseIndex()}setKeyboardIndex(e){const{options:n}=this.props;n.separateKeyboardMouse!==void 0&&n.separateKeyboardMouse?this.setState({keyboardIndex:e}):this.setMouseIndex(e)}getMouseIndex(){const{mouseIndex:e}=this.state;return e}setMouseIndex(e){this.setState({mouseIndex:e})}initMenu(){this.cancelPromises(),cancelAnimationFrame(this.rAF);const{options:e}=this.props;let n=e.initialKeyboardIndex;n===void 0&&(n=-1);const{actions:r}=this.props,s=A.getMenuItems(r),a=[];for(let l=s.length-1;l>=0;l-=1){const i=s[l];i instanceof Promise?this.initMenuPromise(i):a.push(i)}this.setState({mouseIndex:-1,keyboardIndex:n,activeSubMenu:null,menuItems:A.sortActions(a)})}initMenuPromise(e){const n=z.makeCancelable(e);this.setState(r=>({pendingItems:r.pendingItems.concat(n)})),n.then(r=>{this.setState(s=>{const a=s.pendingItems.indexOf(n);if(a>=0){const l=s.pendingItems.slice();return l.splice(a,1),{menuItems:A.sortActions(s.menuItems.concat(r)),pendingItems:l}}return null})},r=>{z.isCanceled(r)||(this.setState(s=>{const a=s.pendingItems.indexOf(n);if(a>=0){const l=s.pendingItems.slice();return l.splice(a,1),{pendingItems:l}}return null}),ee.error(r))})}cancelPromises(){const{pendingItems:e}=this.state;e.map(n=>n.cancel())}setActiveSubMenuPosition(){if(this.activeSubMenuRef.current===null)return;const e=this.activeSubMenuRef.current.getBoundingClientRect();this.setState({subMenuTop:e.top,subMenuLeft:e.right,subMenuParentHeight:e.height,subMenuParentWidth:e.width})}verifyPosition(){var M,y;const{options:e,updatePosition:n,subMenuParentWidth:r,subMenuParentHeight:s,top:a,left:l}=this.props;if(!this.container.current||e.doNotVerifyPosition!=null&&e.doNotVerifyPosition)return;let{top:i,left:o}=this.initialPosition;const{width:u,height:m}=((M=this.container.current)==null?void 0:M.getBoundingClientRect())??{width:0,height:0},p=(((y=this.container.current)==null?void 0:y.scrollHeight)??0)>window.innerHeight;m===0||u===0||(i+m>window.innerHeight&&(i-m-s>0?i-=m-s:i=window.innerHeight-m),o+u>window.innerWidth&&(o=o-u-r),(l!==o||a!==i)&&(this.setState({hasOverflow:p}),n(i,o)))}handleWindowResize(){this.container.current&&this.closeMenu(!0)}handleBlur(e){if(!this.container.current){ee.warn("Container is null!");return}if(!this.container.current.contains(e.relatedTarget)){let n=e.relatedTarget,r=!1;for(;n&&!r;)r=n.hasAttribute("data-dh-context-menu"),n=n.parentElement;r||this.closeMenu(!0)}}isEscapeKey(e){const{left:n}=this.props;return e==="Escape"||n<0&&e==="ArrowRight"||e==="ArrowLeft"}handleKeyDown(e){const{menuItems:n}=this.state,r=this.getKeyboardIndex();let s=r,a=!1;if(e.key==="Enter"||e.key===" "){r>=0&&r<n.length&&this.handleMenuItemClick(n[r],e);return}if(e.key==="ArrowRight"?r>=0&&r<=n.length?a=!0:s=0:this.isEscapeKey(e.key)?s=null:e.key==="ArrowUp"||e.shiftKey&&e.key==="Tab"?s=A.getNextMenuItem(s,-1,n):(e.key==="ArrowDown"||e.key==="Tab")&&(s=A.getNextMenuItem(s,1,n)),a){this.openSubMenu(r),e.preventDefault(),e.stopPropagation();return}r!==s&&(s!==null?this.setKeyboardIndex(s):(this.closeMenu(),this.oldFocus instanceof HTMLElement&&this.oldFocus.focus()),e.preventDefault(),e.stopPropagation())}openSubMenu(e){const{menuItems:n,activeSubMenu:r}=this.state,s=n[e].actions?e:null;r!==s&&this.setState({activeSubMenu:s,subMenuTop:null,subMenuLeft:null})}closeMenu(e=!1){const{closeMenu:n,onMenuClosed:r}=this.props;cancelAnimationFrame(this.rAF),this.rAF=window.requestAnimationFrame(()=>{n(e),r(this)})}closeSubMenu(){this.setState({activeSubMenu:null})}handleCloseSubMenu(e){e?this.closeMenu(!0):this.closeSubMenu()}handleMenuItemClick(e,n){n.preventDefault(),n.stopPropagation();const{menuItems:r}=this.state;e!=null&&(e.disabled===void 0||!e.disabled)&&(e.actions!=null?this.openSubMenu(r.indexOf(e)):e.action!=null&&(e.action(),this.closeMenu(!0)))}handleMenuItemContextMenu(e,n){n.metaKey||this.handleMenuItemClick(e,n)}handleMenuItemMouseMove(e){const{menuItems:n}=this.state,r=n.indexOf(e);this.setMouseIndex(r),r>=0&&r<n.length&&(e.disabled===void 0||!e.disabled)&&this.openSubMenu(r)}handleMouseLeave(){this.setMouseIndex(-1)}render(){const e=[],{top:n,left:r}=this.props,{activeSubMenu:s,hasOverflow:a,keyboardIndex:l,menuItems:i,mouseIndex:o,pendingItems:u,subMenuTop:m,subMenuLeft:p,subMenuParentWidth:M,subMenuParentHeight:y}=this.state;for(let S=0;S<i.length;S+=1){const L=i[S];S>0&&L.group!==i[S-1].group&&e.push(T.jsx("hr",{},`${S}.separator`));const Q=T.jsx(Ee,{ref:s===S?this.activeSubMenuRef:null,isKeyboardSelected:l===S,isMouseSelected:o===S,menuItem:L,closeMenu:this.handleCloseSubMenu,onMenuItemClick:this.handleMenuItemClick,onMenuItemMouseMove:this.handleMenuItemMouseMove,onMenuItemContextMenu:this.handleMenuItemContextMenu},S);e.push(Q)}let b=null;u.length>0&&(b=T.jsx("div",{className:"loading",children:T.jsx(fe,{})}));const{menuStyle:R,"data-testid":g}=this.props,N=s!==null&&m!==null&&p!==null;return T.jsxs(T.Fragment,{children:[T.jsxs("div",{className:B({"has-overflow":a},"context-menu-container"),style:{top:n,left:r,...R},ref:this.container,"data-dh-context-menu":!0,onBlur:this.handleBlur,onKeyDown:this.handleKeyDown,onMouseLeave:this.handleMouseLeave,onContextMenu:G.handleContextMenu,role:"menuitem",tabIndex:0,"data-testid":g,children:[e,b]}),N&&s!==null&&m!==null&&p!==null&&T.jsx(G,{actions:i[s].actions||[],closeMenu:this.handleCloseSubMenu,top:m,left:p,updatePosition:(S,L)=>{this.setState({subMenuTop:S,subMenuLeft:L})},subMenuParentWidth:M,subMenuParentHeight:y},`sub-${s}`)]})}};let K=G;h(K,"defaultProps",{subMenuParentWidth:0,subMenuParentHeight:0,closeMenu(){},onMenuOpened(){},onMenuClosed(){},options:{},menuStyle:{},"data-testid":void 0});const Fe=K;class Ce extends v.Component{constructor(e){super(e);h(this,"container");h(this,"openMenu");this.handleMenuClose=this.handleMenuClose.bind(this),this.handleContextMenu=this.handleContextMenu.bind(this),this.container=$.createRef(),this.openMenu=$.createRef(),this.state={actions:null,left:0,top:0}}componentDidMount(){var e;(e=this.container.current)!=null&&e.parentElement&&this.container.current.parentElement.addEventListener("contextmenu",this.handleContextMenu)}componentWillUnmount(){var e;(e=this.container.current)!=null&&e.parentElement&&this.container.current.parentElement.removeEventListener("contextmenu",this.handleContextMenu)}handleContextMenu(e){if(!A.isContextActionEvent(e)||!this.container.current||e.metaKey||e.ctrlKey)return;const n=A.getMenuItems(e.contextActions),r=this.container.current.getBoundingClientRect(),s=e.clientY-r.top,a=e.clientX-r.left;if(n.length===0){if(e.target===this.container.current){e.preventDefault(),this.setState({actions:null},()=>{const l=document.elementFromPoint(a,s),i=new MouseEvent("contextmenu",{clientX:e.clientX,clientY:e.clientY,bubbles:!0,cancelable:!0});l==null||l.dispatchEvent(i)});return}return}e.preventDefault(),this.setState({actions:n,top:s,left:a})}handleMenuClose(e){e===this.openMenu.current&&this.setState({actions:null})}render(){let e=null;const{"data-testid":n}=this.props,{actions:r,top:s,left:a}=this.state;return r&&(e=T.jsx(Fe,{ref:this.openMenu,actions:r,onMenuClosed:this.handleMenuClose,top:s,left:a,updatePosition:(l,i)=>{this.setState({top:l,left:i})},"data-testid":n})),T.jsx("div",{className:B("context-menu-root",{active:r}),ref:this.container,children:e})}}const Ke=Ce;function re(){return X(pe,"No API available in useApi. Was code wrapped in ApiBootstrap or ApiContext.Provider?")}function Ne(f,t){const e=re(),n=v.useMemo(()=>new e.CoreClient(f,t),[e,f,t]);return v.useEffect(()=>()=>{n.disconnect()},[n]),n}const se=v.createContext(null);function Ye({serverUrl:f,options:t,children:e}){const n=Ne(f,t);return T.jsx(se.Provider,{value:n,children:e})}function be(){return X(se,"No Client available in useClient. Was code wrapped in ClientBootstrap or ClientContext.Provider?")}class Y{static isValid(t){return!0}static isSameFormat(t,e){throw new Error("isSameFormat not implemented")}static makeFormat(t,e,n){return{label:t,formatString:e,type:n}}format(t,e){return""}}h(Y,"TYPE_GLOBAL","type-global"),h(Y,"TYPE_CONTEXT_PRESET","type-context-preset"),h(Y,"TYPE_CONTEXT_CUSTOM","type-context-custom");const F=Y;class Ie extends F{format(t){switch(t){case 1:case!0:return"true";case 0:case!1:return"false";default:return""}}}const we=Ie;class ve extends F{format(t){return String.fromCharCode(t)}}const ke=ve,{dh:xe}=globalThis,D=xe,te=H.module("DateTimeColumnFormatter"),x=class extends F{constructor({timeZone:e="",showTimeZone:n=!0,showTSeparator:r=!1,defaultDateTimeFormatString:s=x.DEFAULT_DATETIME_FORMAT_STRING}={}){super();h(this,"dhTimeZone");h(this,"defaultDateTimeFormatString");h(this,"showTimeZone");h(this,"showTSeparator");h(this,"formatStringMap");const a=e||x.DEFAULT_TIME_ZONE_ID;try{this.dhTimeZone=D.i18n.TimeZone.getTimeZone(a)}catch{te.error("Unsupported time zone id",a),this.dhTimeZone=D.i18n.TimeZone.getTimeZone(x.DEFAULT_TIME_ZONE_ID)}this.defaultDateTimeFormatString=s,this.showTimeZone=n,this.showTSeparator=r,this.formatStringMap=x.makeFormatStringMap(n,r)}static isValid(e){try{return D.i18n.DateTimeFormat.format(e.formatString,new Date),!0}catch{return!1}}static makeFormat(e,n,r=F.TYPE_CONTEXT_PRESET){return{label:e,formatString:n,type:r}}static isSameFormat(e,n){return e===n||e!==null&&n!==null&&e.type===n.type&&e.formatString===n.formatString}static makeGlobalFormatStringMap(e,n){const r=n?"'T'":" ",s=e?" z":"";return new Map([["yyyy-MM-dd HH:mm:ss",`yyyy-MM-dd${r}HH:mm:ss${s}`],["yyyy-MM-dd HH:mm:ss.SSS",`yyyy-MM-dd${r}HH:mm:ss.SSS${s}`],["yyyy-MM-dd HH:mm:ss.SSSSSSSSS",`yyyy-MM-dd${r}HH:mm:ss.SSSSSSSSS${s}`]])}static getGlobalFormats(e,n){return[...x.makeGlobalFormatStringMap(e,n).keys()]}static makeFormatStringMap(e,n){const r=n!==void 0&&n?"'T'":" ",s=e!==void 0&&e?" z":"";return new Map([["yyyy-MM-dd",`yyyy-MM-dd${s}`],["MM-dd-yyyy",`MM-dd-yyyy${s}`],["HH:mm:ss",`HH:mm:ss${s}`],["HH:mm:ss.SSS",`HH:mm:ss.SSS${s}`],["HH:mm:ss.SSSSSSSSS",`HH:mm:ss.SSSSSSSSS${s}`],["yyyy-MM-dd HH:mm:ss",`yyyy-MM-dd${r}HH:mm:ss${s}`],["yyyy-MM-dd HH:mm:ss.SSS",`yyyy-MM-dd${r}HH:mm:ss.SSS${s}`],["yyyy-MM-dd HH:mm:ss.SSSSSSSSS",`yyyy-MM-dd${r}HH:mm:ss.SSSSSSSSS${s}`]])}static getFormats(e,n){return[...x.makeFormatStringMap(e,n).keys()]}getEffectiveFormatString(e){return this.formatStringMap.get(e)??e}format(e,n={}){const r=n.formatString!=null&&n.formatString!==""?n.formatString:this.defaultDateTimeFormatString,s=this.getEffectiveFormatString(r);try{return D.i18n.DateTimeFormat.format(s,e,this.dhTimeZone)}catch{te.error("Invalid format arguments")}return""}};let j=x;h(j,"DEFAULT_DATETIME_FORMAT_STRING","yyyy-MM-dd HH:mm:ss.SSS"),h(j,"DEFAULT_TIME_ZONE_ID","America/New_York");const De=H.module("DecimalColumnFormatter"),I=class extends F{constructor({defaultFormatString:e=I.DEFAULT_FORMAT_STRING}={}){super();h(this,"defaultFormatString");this.defaultFormatString=e}static isValid(e){try{return D.i18n.NumberFormat.format(e.formatString,0),!0}catch{return!1}}static makeFormat(e,n,r=F.TYPE_CONTEXT_PRESET,s){return{label:e,type:r,formatString:n,multiplier:s}}static makePresetFormat(e,n="",r){return I.makeFormat(e,n,F.TYPE_CONTEXT_PRESET,r)}static makeCustomFormat(e="",n){return I.makeFormat("Custom Format",e,F.TYPE_CONTEXT_CUSTOM,n)}static isSameFormat(e,n){return e===n||e!=null&&n!=null&&e.type===n.type&&e.formatString===n.formatString&&e.multiplier===n.multiplier}format(e,n={}){const r=n.formatString!=null&&n.formatString!==""?n.formatString:this.defaultFormatString,s=n.multiplier!=null&&n.multiplier!==0?e*n.multiplier:e;try{return D.i18n.NumberFormat.format(r,s)}catch{De.error("Invalid format arguments")}return""}};let w=I;h(w,"DEFAULT_FORMAT_STRING","###,##0.0000"),h(w,"FORMAT_PERCENT",I.makePresetFormat("Percent","##0.00%")),h(w,"FORMAT_BASIS_POINTS",I.makePresetFormat("Basis Points","###,##0 bp",1e4)),h(w,"FORMAT_MILLIONS",I.makePresetFormat("Millions","###,##0.000 mm",1e-6)),h(w,"FORMAT_SCIENTIFIC_NOTATION",I.makePresetFormat("Scientific Notation","0.0000E0")),h(w,"FORMAT_ROUND",I.makePresetFormat("Round","###,##0")),h(w,"FORMAT_ROUND_TWO_DECIMALS",I.makePresetFormat("0.00","###,##0.00")),h(w,"FORMAT_ROUND_FOUR_DECIMALS",I.makePresetFormat("0.0000","###,##0.0000"));class Ae extends F{format(t){return`${t}`}}const Oe=Ae,Pe=H.module("IntegerColumnFormatter"),P=class extends F{constructor({defaultFormatString:e=P.DEFAULT_FORMAT_STRING}={}){super();h(this,"defaultFormatString");this.defaultFormatString=e}static isValid(e){try{return D.i18n.NumberFormat.format(e.formatString,0),!0}catch{return!1}}static makeFormat(e,n,r=F.TYPE_CONTEXT_PRESET,s){return{label:e,type:r,formatString:n,multiplier:s}}static makePresetFormat(e,n="",r){return P.makeFormat(e,n,F.TYPE_CONTEXT_PRESET,r)}static makeCustomFormat(e="",n){return P.makeFormat("Custom Format",e,F.TYPE_CONTEXT_CUSTOM,n)}static isSameFormat(e,n){return e===n||e!=null&&n!=null&&e.type===n.type&&e.formatString===n.formatString&&e.multiplier===n.multiplier}format(e,n={}){const r=n.formatString!=null&&n.formatString!==""?n.formatString:this.defaultFormatString,s=n.multiplier!=null&&n.multiplier!==0?e*n.multiplier:e;try{return D.i18n.NumberFormat.format(r,s)}catch{Pe.error("Invalid format arguments")}return""}};let q=P;h(q,"DEFAULT_FORMAT_STRING","###,##0"),h(q,"FORMAT_MILLIONS",P.makePresetFormat("Millions","###,##0.000 mm",1e-6)),h(q,"FORMAT_SCIENTIFIC_NOTATION",P.makePresetFormat("Scientific Notation","0.0000E0"));class $e extends F{format(t){return t}}const C=class{static makeDateWrapper(t,e,n,r=0,s=1,a=0,l=0,i=0,o=0){if(!e)throw new Error("No timezone provided");const u=`${n}`.padStart(4,"0"),m=`${r+1}`.padStart(2,"0"),p=`${s}`.padStart(2,"0"),M=`${a}`.padStart(2,"0"),y=`${l}`.padStart(2,"0"),b=`${i}`.padStart(2,"0"),R=`${o}`.padStart(9,"0"),g=`${u}-${m}-${p} ${M}:${y}:${b}.${R}`;return t.i18n.DateTimeFormat.parse(C.FULL_DATE_FORMAT,g,t.i18n.TimeZone.getTimeZone(e))}static getNextNanos(t){const e=parseInt(t,10),n="0".repeat(9-t.length),r=`${e+1}${n}`;return parseInt(r,10)}static getNextDate(t,e,n,r){let{year:s,month:a,date:l,hours:i,minutes:o,seconds:u,nanos:m}=n;if(e.nanos!=null){if(e.nanos.length===9)return null;m=C.getNextNanos(e.nanos),m>999999999&&(u+=1,m=0)}else e.seconds!=null?u+=1:e.minutes!=null?o+=1:e.hours!=null?i+=1:e.date!=null?l+=1:e.month!=null?a+=1:s+=1;const p=new Date(s,a,l,i,o,u);return C.makeDateWrapper(t,r,p.getFullYear(),p.getMonth(),p.getDate(),p.getHours(),p.getMinutes(),p.getSeconds(),m)}static parseMonth(t){const e=parseInt(t,10);if(!Number.isNaN(e))return e>=1&&e<=12?e-1:NaN;const n=t.trim().toLowerCase();if(n.length>=3){for(let r=0;r<C.months.length;r+=1)if(C.months[r].startsWith(n))return r}return NaN}static parseDateValues(t,e,n,r,s,a,l){const i=parseInt(t,10),o=e!=null?this.parseMonth(e):0,u=n!=null?parseInt(n,10):1,m=r!=null?parseInt(r,10):0,p=s!=null?parseInt(s,10):0,M=a!=null?parseInt(a,10):0,y=l!=null?parseInt(l.padEnd(9,"0"),10):0;return Number.isNaN(i)||Number.isNaN(o)||Number.isNaN(u)||Number.isNaN(m)||Number.isNaN(p)||Number.isNaN(M)||Number.isNaN(y)?null:{year:i,month:o,date:u,hours:m,minutes:p,seconds:M,nanos:y}}static parseDateTimeString(t){const n=/\s*(\d{4})([-./]([\da-z]+))?([-./](\d{1,2}))?([tT\s](\d{2})([:](\d{2}))?([:](\d{2}))?([.](\d{1,9}))?)?(.*)/.exec(t);if(n==null)throw new Error(`Unexpected date string: ${t}`);const[,r,,s,,a,,l,,i,,o,,u,m]=n;if(m!=null&&m.length>0)throw new Error(`Unexpected characters after date string '${t}': ${m}`);return{year:r,month:s,date:a,hours:l,minutes:i,seconds:o,nanos:u}}static parseDateRange(t,e,n){const r=e.trim().toLowerCase();if(r.length===0)throw new Error("Cannot parse date range from empty string");if(r==="null")return[null,null];if(r==="today"){const o=new Date(Date.now()),u=C.makeDateWrapper(t,n,o.getFullYear(),o.getMonth(),o.getDate()),m=C.makeDateWrapper(t,n,o.getFullYear(),o.getMonth(),o.getDate()+1);return[u,m]}if(r==="yesterday"){const o=new Date(Date.now()),u=C.makeDateWrapper(t,n,o.getFullYear(),o.getMonth(),o.getDate()-1),m=C.makeDateWrapper(t,n,o.getFullYear(),o.getMonth(),o.getDate());return[u,m]}if(r==="now"){const o=new Date(Date.now());return[t.DateWrapper.ofJsDate(o),null]}const s=C.parseDateTimeString(r);if(s.year==null&&s.month==null&&s.date==null)throw new Error(`Unable to extract year, month, or day ${r}`);const a=C.parseDateValues(s.year,s.month,s.date,s.hours,s.minutes,s.seconds,s.nanos);if(a==null)throw new Error(`Unable to extract date values from ${s}`);const l=C.makeDateWrapper(t,n,a.year,a.month,a.date,a.hours,a.minutes,a.seconds,a.nanos),i=C.getNextDate(t,s,a,n);return[l,i]}static getJsDate(t){return typeof t=="number"?new Date(t):t.asDate()}};let V=C;h(V,"FULL_DATE_FORMAT","yyyy-MM-dd HH:mm:ss.SSSSSSSSS"),h(V,"months",["january","february","march","april","may","june","july","august","september","october","november","december"]);class W{}h(W,"not","not"),h(W,"and","and"),h(W,"or","or");class d{}h(d,"eq","eq"),h(d,"eqIgnoreCase","eqIgnoreCase"),h(d,"notEq","notEq"),h(d,"notEqIgnoreCase","notEqIgnoreCase"),h(d,"greaterThan","greaterThan"),h(d,"greaterThanOrEqualTo","greaterThanOrEqualTo"),h(d,"lessThan","lessThan"),h(d,"lessThanOrEqualTo","lessThanOrEqualTo"),h(d,"in","in"),h(d,"inIgnoreCase","inIgnoreCase"),h(d,"notIn","notIn"),h(d,"notInIgnoreCase","notInIgnoreCase"),h(d,"isTrue","isTrue"),h(d,"isFalse","isFalse"),h(d,"isNull","isNull"),h(d,"invoke","invoke"),h(d,"contains","contains"),h(d,"notContains","notContains"),h(d,"startsWith","startsWith"),h(d,"endsWith","endsWith"),h(d,"containsAny","containsAny");const k=H.module("TableUtils"),c=class{constructor(t){h(this,"dh");this.dh=t}static async applyCustomColumns(t,e,n=c.APPLY_TABLE_CHANGE_TIMEOUT_MS){return c.executeAndWaitForEvent(r=>r==null?void 0:r.applyCustomColumns(e),t,dh.Table.EVENT_CUSTOMCOLUMNSCHANGED,n)}static async applyFilter(t,e,n=c.APPLY_TABLE_CHANGE_TIMEOUT_MS){return c.executeAndWaitForEvent(r=>r==null?void 0:r.applyFilter(e),t,dh.Table.EVENT_FILTERCHANGED,n)}static async applyNeverFilter(t,e,n=c.APPLY_TABLE_CHANGE_TIMEOUT_MS){if(t==null)return null;const r=t.findColumn(e),s=[c.makeNeverFilter(r)];return await c.applyFilter(t,s,n),t}static async applySort(t,e,n=c.APPLY_TABLE_CHANGE_TIMEOUT_MS){return c.executeAndWaitForEvent(r=>r==null?void 0:r.applySort(e),t,dh.Table.EVENT_SORTCHANGED,n)}static getSortIndex(t,e){var n;for(let r=0;r<t.length;r+=1)if(((n=t[r].column)==null?void 0:n.name)===e)return r;return null}static getSortForColumn(t,e){const n=c.getSortIndex(t,e);return n!=null?t[n]:null}static getFilterText(t){return t?t.toString():null}static getFilterTypes(t){return c.isBooleanType(t)?[d.isTrue,d.isFalse,d.isNull]:c.isCharType(t)||c.isNumberType(t)||c.isDateType(t)?[d.eq,d.notEq,d.greaterThan,d.greaterThanOrEqualTo,d.lessThan,d.lessThanOrEqualTo]:c.isTextType(t)?[d.eq,d.eqIgnoreCase,d.notEq,d.notEqIgnoreCase,d.contains,d.notContains,d.startsWith,d.endsWith]:[]}static getNextSort(t,e,n){if(n<0||n>=t.length)return null;const r=c.getSortForColumn(e,t[n].name);return r===null?t[n].sort().asc():r.direction===c.sortDirection.ascending?r.desc():null}static makeColumnSort(t,e,n,r){if(e<0||e>=t.length||n===c.sortDirection.none)return null;let s=t[e].sort();switch(n){case c.sortDirection.ascending:s=s.asc();break;case c.sortDirection.descending:s=s.desc();break}return r&&(s=s.abs()),s}static toggleSortForColumn(t,e,n,r=!1){if(n<0||n>=e.length)return[];const s=c.getNextSort(e,t,n);return c.setSortForColumn(t,e[n].name,s,r)}static sortColumn(t,e,n,r,s,a){if(n<0||n>=e.length)return[];const l=c.makeColumnSort(e,n,r,s);return c.setSortForColumn(t,e[n].name,l,a)}static setSortForColumn(t,e,n,r=!1){const s=c.getSortIndex(t,e);let a=[];return r&&(a=a.concat(t.filter(({direction:l})=>l!==c.sortDirection.reverse)),s!==null&&a.splice(s,1)),n!==null&&a.push(n),a}static getNormalizedType(t){switch(t){case"boolean":case"java.lang.Boolean":case c.dataType.BOOLEAN:return c.dataType.BOOLEAN;case"char":case"java.lang.Character":case c.dataType.CHAR:return c.dataType.CHAR;case"java.lang.String":case c.dataType.STRING:return c.dataType.STRING;case"io.deephaven.db.tables.utils.DBDateTime":case"io.deephaven.time.DateTime":case"com.illumon.iris.db.tables.utils.DBDateTime":case"java.time.Instant":case"java.time.ZonedDateTime":case c.dataType.DATETIME:return c.dataType.DATETIME;case"double":case"java.lang.Double":case"float":case"java.lang.Float":case"java.math.BigDecimal":case c.dataType.DECIMAL:return c.dataType.DECIMAL;case"int":case"java.lang.Integer":case"long":case"java.lang.Long":case"short":case"java.lang.Short":case"byte":case"java.lang.Byte":case"java.math.BigInteger":case c.dataType.INT:return c.dataType.INT;default:return c.dataType.UNKNOWN}}static isLongType(t){switch(t){case"long":case"java.lang.Long":return!0;default:return!1}}static isDateType(t){switch(t){case"io.deephaven.db.tables.utils.DBDateTime":case"io.deephaven.time.DateTime":case"java.time.Instant":case"java.time.ZonedDateTime":case"com.illumon.iris.db.tables.utils.DBDateTime":return!0;default:return!1}}static isNumberType(t){return c.isIntegerType(t)||c.isDecimalType(t)}static isIntegerType(t){switch(t){case"int":case"java.lang.Integer":case"java.math.BigInteger":case"long":case"java.lang.Long":case"short":case"java.lang.Short":case"byte":case"java.lang.Byte":return!0;default:return!1}}static isDecimalType(t){switch(t){case"double":case"java.lang.Double":case"java.math.BigDecimal":case"float":case"java.lang.Float":return!0;default:return!1}}static isBigDecimalType(t){switch(t){case"java.math.BigDecimal":return!0;default:return!1}}static isBigIntegerType(t){switch(t){case"java.math.BigInteger":return!0;default:return!1}}static isBooleanType(t){switch(t){case"boolean":case"java.lang.Boolean":return!0;default:return!1}}static isCharType(t){switch(t){case"char":case"java.lang.Character":return!0;default:return!1}}static isStringType(t){switch(t){case"java.lang.String":return!0;default:return!1}}static isTextType(t){return this.isStringType(t)||this.isCharType(t)}static getBaseType(t){return t.split("[]")[0]}static isCompatibleType(t,e){return c.getNormalizedType(t)===c.getNormalizedType(e)}static quoteValue(t){return t.length>=2&&(t.charAt(0)==='"'&&t.charAt(t.length-1)==='"'||t.charAt(0)==="'"&&t.charAt(t.length-1)==="'")?t:`"${t}"`}static isRangeOperation(t){switch(t){case"<":case"<=":case"=<":case">":case">=":case"=>":return!0;default:return!1}}static makeRangeFilterWithOperation(t,e,n){switch(e){case"=":return t.eq(n);case"<":return t.lessThan(n);case"<=":case"=<":return t.lessThanOrEqualTo(n);case">":return t.greaterThan(n);case">=":case"=>":return t.greaterThanOrEqualTo(n);case"!=":case"!":return t.notEq(n);default:return null}}static makeCancelableTablePromise(t){return z.makeCancelable(t,e=>{e.close()})}static makeCancelableTableEventPromise(t,e,n=0,r=null){let s,a,l=!0;const i=new Promise((o,u)=>{a=setTimeout(()=>{s(),l=!1,u(new ne(`Event "${e}" timed out.`))},n),s=t.addEventListener(e,m=>{if(r!=null&&!r(m)){k.debug2("Event triggered, but matcher returned false.");return}k.debug2("Event triggered, resolving."),s(),clearTimeout(a),l=!1,o(m)})});return i.cancel=()=>{if(l){k.debug2("Pending promise cleanup."),s(),clearTimeout(a),l=!1;return}k.debug2("Ignoring non-pending promise cancel.")},i}static removeCommas(t){return t.replace(/[\s|,]/g,"")}static makeBooleanValue(t,e=!1){if(t===""&&e)return null;switch(t==null?void 0:t.toLowerCase()){case"null":return null;case"0":case"f":case"fa":case"fal":case"fals":case"false":case"n":case"no":return!1;case"1":case"t":case"tr":case"tru":case"true":case"y":case"ye":case"yes":return!0;default:throw new Error(`Invalid boolean '${t}'`)}}static makeNumberValue(t){if(t==="null"||t==="")return null;const e=t.toLowerCase().trim();if(e==="∞"||e==="infinity"||e==="inf")return Number.POSITIVE_INFINITY;if(e==="-∞"||e==="-infinity"||e==="-inf")return Number.NEGATIVE_INFINITY;const n=c.removeCommas(e);if(c.NUMBER_REGEX.test(n))return parseFloat(n);throw new Error(`Invalid number '${t}'`)}static getFilterOperatorString(t){switch(t){case d.eq:return"=";case d.notEq:return"!=";case d.greaterThan:return">";case d.greaterThanOrEqualTo:return">=";case d.lessThan:return"<";case d.lessThanOrEqualTo:return"<=";case d.contains:return"~";case d.notContains:return"!~";default:throw new Error(`Unexpected filter type ${t}`)}}static isTreeTable(t){return t!=null&&t.expand!==void 0&&t.collapse!==void 0}static sortColumns(t,e=!0){return[...t].sort((n,r)=>{const s=n.name.toUpperCase(),a=r.name.toUpperCase();return ye.sort(s,a,e)})}makeQuickFilter(t,e,n){const r=e.split("||");let s=null;for(let a=0;a<r.length;a+=1){const i=r[a].split("&&");let o=null;for(let u=0;u<i.length;u+=1){const m=i[u].trim();if(m.length>0){const p=this.makeQuickFilterFromComponent(t,m,n);if(p)o?o=o.and(p):o=p;else throw new Error(`Unable to parse quick filter from text ${e}`)}}s&&o?s=s.or(o):s=o}return s}makeQuickFilterFromComponent(t,e,n){const{type:r}=t;return c.isNumberType(r)?this.makeQuickNumberFilter(t,e):c.isBooleanType(r)?this.makeQuickBooleanFilter(t,e):n!=null&&c.isDateType(r)?this.makeQuickDateFilter(t,e,n):c.isCharType(r)?this.makeQuickCharFilter(t,e):this.makeQuickTextFilter(t,e)}makeQuickNumberFilter(t,e){const n=t.filter(),{dh:r}=this;let s=null;const l=/\s*(>=|<=|=>|=<|>|<|!=|=|!)?(\s*-\s*)?(\s*\d*(?:,\d{3})*(?:\.\d*)?\s*)?(null|nan|infinity|inf|\u221E)?(.*)/i.exec(e);let i=null,o=null,u=null,m=null,p=null;if(l!==null&&l.length>3&&([,i,o,u,m,p]=l),p!=null&&p.trim().length>0)return null;if(i==null&&(i="="),m!=null){if(!(i==="="||i==="!"||i==="!="))return null;switch(m=m.trim().toLowerCase(),m){case"null":s=n.isNull();break;case"nan":s=r.FilterCondition.invoke("isNaN",n);break;case"infinity":case"inf":case"∞":o!=null?s=r.FilterCondition.invoke("isInf",n).and(n.lessThan(r.FilterValue.ofNumber(0))):s=r.FilterCondition.invoke("isInf",n).and(n.greaterThan(r.FilterValue.ofNumber(0)));break}return s!==null&&(i==="!"||i==="!=")&&(s=s.not()),s}if(u==null)return null;if(u=c.removeCommas(u),c.isLongType(t.type))try{u=r.FilterValue.ofNumber(r.LongWrapper.ofString(`${o!=null?"-":""}${u}`))}catch(M){return k.warn("Unable to create long filter",M),null}else{if(u=parseFloat(u),u==null||Number.isNaN(u))return null;u=r.FilterValue.ofNumber(o!=null?0-u:u)}return s=t.filter(),c.makeRangeFilterWithOperation(s,i,u)}makeQuickTextFilter(t,e){const{dh:n}=this,r=`${e}`.trim(),a=/^(!~|!=|~|=|!)?(.*)/.exec(r);let l=null,i=null;if(a!==null&&a.length>2&&([,l,i]=a,i!=null&&(i=i.trim())),i==null||i.length===0)return null;l==null&&(l="=");const o=t.filter();if(i.toLowerCase()==="null")switch(l){case"=":return o.isNull();case"!=":case"!":return o.isNull().not()}let u=null,m=null;switch(i.startsWith("*")?(u="*",i=i.substring(1)):i.endsWith("*")&&!i.endsWith("\\*")&&(m="*",i=i.substring(0,i.length-1)),i=i.replace("\\",""),l){case"~":return o.isNull().not().and(o.invoke("matches",n.FilterValue.ofString(`(?s)(?i).*\\Q${i}\\E.*`)));case"!~":return o.isNull().or(o.invoke("matches",n.FilterValue.ofString(`(?s)(?i).*\\Q${i}\\E.*`)).not());case"!=":return u==="*"?o.isNull().or(o.invoke("matches",n.FilterValue.ofString(`(?s)(?i).*\\Q${i}\\E$`)).not()):m==="*"?o.isNull().or(o.invoke("matches",n.FilterValue.ofString(`(?s)(?i)^\\Q${i}\\E.*`)).not()):o.notEqIgnoreCase(n.FilterValue.ofString(i.toLowerCase()));case"=":return u==="*"?o.isNull().not().and(o.invoke("matches",n.FilterValue.ofString(`(?s)(?i).*\\Q${i}\\E$`))):m==="*"?o.isNull().not().and(o.invoke("matches",n.FilterValue.ofString(`(?s)(?i)^\\Q${i}\\E.*`))):o.eqIgnoreCase(n.FilterValue.ofString(i.toLowerCase()))}return null}makeQuickBooleanFilter(t,e){const r=/^(!=|=|!)?(.*)/.exec(`${e}`.trim());if(r===null)return null;const[,s,a]=r,l=s==="!"||s==="!=",i=a.trim().toLowerCase();let o=t.filter();try{const u=c.makeBooleanValue(i);return u!=null&&u?o=o.isTrue():u===null?o=o.isNull():o=o.isFalse(),l?o.not():o}catch{return null}}makeQuickDateFilter(t,e,n){const r=e.trim(),a=/\s*(>=|<=|=>|=<|>|<|!=|!|=)?(.*)/.exec(r);if(a==null||a.length<=2)throw new Error(`Unable to parse date filter: ${e}`);let l=null,i=null;[,l,i]=a;let o=d.eq;switch(l){case"<":o=d.lessThan;break;case"<=":case"=<":o=d.lessThanOrEqualTo;break;case">":o=d.greaterThan;break;case">=":case"=>":o=d.greaterThanOrEqualTo;break;case"!=":case"!":o=d.notEq;break;case"=":case"==":default:o=d.eq;break}return this.makeQuickDateFilterWithOperation(t,i,o,n)}makeQuickDateFilterWithOperation(t,e,n,r){const{dh:s}=this,[a,l]=V.parseDateRange(s,e,r),i=a!=null?s.FilterValue.ofNumber(a):null,o=l!=null?s.FilterValue.ofNumber(l):null,u=t.filter();if(i==null)return n===d.notEq?u.isNull().not():u.isNull();switch(n){case d.eq:{if(o!=null){const m=u.greaterThanOrEqualTo(i),p=u.lessThan(o);return m.and(p)}return u.eq(i)}case d.lessThan:return u.lessThan(i);case d.lessThanOrEqualTo:return o!=null?u.lessThan(o):u.lessThanOrEqualTo(i);case d.greaterThan:return o!=null?u.greaterThanOrEqualTo(o):u.greaterThan(i);case d.greaterThanOrEqualTo:return u.greaterThanOrEqualTo(i);case d.notEq:{if(o!=null){const m=u.lessThan(i),p=u.greaterThanOrEqualTo(o);return m.or(p)}return u.notEq(i)}default:throw new Error(`Invalid operator: ${n}`)}}makeQuickCharFilter(t,e){const{dh:n}=this,r=`${e}`.trim(),a=/^(>=|<=|=>|=<|>|<|!=|=|!)?(null|"."|'.'|.)?(.*)/.exec(r);let l=null,i=null,o=null;if(a!==null&&a.length>3&&([,l,i,o]=a),o!=null&&o.trim().length>0||i==null||i.length===0)return null;l==null&&(l="=");const u=t.filter();if(i.toLowerCase()==="null")switch(l){case"=":return u.isNull();case"!=":case"!":return u.isNull().not();default:return null}const m=n.FilterValue.ofString(c.isRangeOperation(l)?c.quoteValue(i):i);return c.makeRangeFilterWithOperation(u,l,m)}makeAdvancedFilter(t,e,n){const{filterItems:r,filterOperators:s,invertSelection:a,selectedValues:l}=e;let i=null;for(let u=0;u<r.length;u+=1){const m=r[u],{selectedType:p,value:M}=m;if(p!=null&&p.length>0&&M!=null&&M.length>0)try{const y=this.makeAdvancedValueFilter(t,p,M,n);if(y!=null){if(u===0)i=y;else if(i!==null&&u-1<s.length){const b=s[u-1];if(b===W.and)i=i.and(y);else if(b===W.or)i=i.or(y);else{k.error("Unexpected filter operator",b,y),i=null;break}}}else k.debug2("Empty filter ignored for",p,M)}catch(y){k.error("Unable to create filter",y),i=null;break}}const o=this.makeSelectValueFilter(t,l,a);return o!=null&&(i!=null?i=i.and(o):i=o),i}makeAdvancedValueFilter(t,e,n,r){if(c.isDateType(t.type))return this.makeQuickDateFilterWithOperation(t,n,e,r);if(c.isNumberType(t.type)||c.isCharType(t.type))return this.makeQuickFilter(t,`${c.getFilterOperatorString(e)}${n}`);const s=this.makeFilterValue(t.type,n),a=t.filter();switch(e){case d.eq:return a.eq(s);case d.eqIgnoreCase:return a.eqIgnoreCase(s);case d.notEq:return a.notEq(s);case d.notEqIgnoreCase:return a.notEqIgnoreCase(s);case d.greaterThan:return a.greaterThan(s);case d.greaterThanOrEqualTo:return a.greaterThanOrEqualTo(s);case d.lessThan:return a.lessThan(s);case d.lessThanOrEqualTo:return a.lessThanOrEqualTo(s);case d.isTrue:return a.isTrue();case d.isFalse:return a.isFalse();case d.isNull:return a.isNull();case d.contains:return a.isNull().not().and(a.invoke("matches",dh.FilterValue.ofString(`(?s)(?i).*\\Q${n}\\E.*`)));case d.notContains:return a.isNull().or(a.invoke("matches",dh.FilterValue.ofString(`(?s)(?i).*\\Q${n}\\E.*`)).not());case d.startsWith:return a.isNull().not().and(a.invoke("matches",dh.FilterValue.ofString(`(?s)(?i)^\\Q${n}\\E.*`)));case d.endsWith:return a.isNull().not().and(a.invoke("matches",dh.FilterValue.ofString(`(?s)(?i).*\\Q${n}\\E$`)));case d.in:case d.inIgnoreCase:case d.notIn:case d.notInIgnoreCase:case d.invoke:default:throw new Error(`Unexpected filter operation: ${e}`)}}static makeNeverFilter(t){let e=null;c.isTextType(t.type)?e=dh.FilterValue.ofString("a"):c.isBooleanType(t.type)?e=dh.FilterValue.ofBoolean(!0):c.isDateType(t.type)?e=dh.FilterValue.ofNumber(dh.DateWrapper.ofJsDate(new Date)):e=dh.FilterValue.ofNumber(0);const n=t.filter().eq(e),r=t.filter().notEq(e);return n.and(r)}makeFilterValue(t,e){const{dh:n}=this,r=c.getBaseType(t);return c.isTextType(r)?n.FilterValue.ofString(e):c.isLongType(r)?n.FilterValue.ofNumber(n.LongWrapper.ofString(c.removeCommas(e))):n.FilterValue.ofNumber(c.removeCommas(e))}makeFilterRawValue(t,e){const{dh:n}=this;return c.isTextType(t)?n.FilterValue.ofString(e):c.isBooleanType(t)?n.FilterValue.ofBoolean(e):n.FilterValue.ofNumber(e)}makeValue(t,e,n){const{dh:r}=this;if(e==="null")return null;if(c.isTextType(t))return e;if(c.isLongType(t))return r.LongWrapper.ofString(c.removeCommas(e));if(c.isBooleanType(t))return c.makeBooleanValue(e,!0);if(c.isDateType(t)){const[s]=V.parseDateRange(r,e,n);return s}return c.isNumberType(t)?c.makeNumberValue(e):(k.error("Unexpected column type",t),null)}makeSelectValueFilter(t,e,n){const{dh:r}=this;if(e.length===0)return n?null:c.makeNeverFilter(t);const s=[];let a=!1;for(let l=0;l<e.length;l+=1){const i=e[l];i==null?a=!0:c.isTextType(t.type)?s.push(r.FilterValue.ofString(typeof i=="number"?String.fromCharCode(i):i)):c.isBooleanType(t.type)?s.push(r.FilterValue.ofBoolean(Boolean(i))):s.push(r.FilterValue.ofNumber(i))}return a?s.length>0?n?t.filter().isNull().not().and(t.filter().notIn(s)):t.filter().isNull().or(t.filter().in(s)):n?t.filter().isNull().not():t.filter().isNull():n?t.filter().notIn(s):t.filter().in(s)}};let E=c;h(E,"dataType",{BOOLEAN:"boolean",CHAR:"char",DATETIME:"datetime",DECIMAL:"decimal",INT:"int",STRING:"string",UNKNOWN:"unknown"}),h(E,"sortDirection",{ascending:"ASC",descending:"DESC",reverse:"REVERSE",none:null}),h(E,"APPLY_TABLE_CHANGE_TIMEOUT_MS",3e4),h(E,"REVERSE_TYPE",Object.freeze({NONE:"none",PRE_SORT:"pre-sort",POST_SORT:"post-sort"})),h(E,"NUMBER_REGEX",/^-?\d+(\.\d+)?$/),h(E,"executeAndWaitForEvent",async(t,e,n,r=c.APPLY_TABLE_CHANGE_TIMEOUT_MS)=>{if(e==null)return null;const s=c.makeCancelableTableEventPromise(e,n,r);return t(e),await s,e});class ae{constructor(t=[],e,n,r,s=!1){h(this,"defaultColumnFormatter");h(this,"typeFormatterMap");h(this,"columnFormatMap");h(this,"truncateNumbersWithPound");this.defaultColumnFormatter=new Oe,this.typeFormatterMap=new Map([[E.dataType.BOOLEAN,new we],[E.dataType.CHAR,new ke],[E.dataType.DATETIME,new j(e)],[E.dataType.DECIMAL,new w(n)],[E.dataType.INT,new q(r)],[E.dataType.STRING,new $e]]),this.columnFormatMap=ae.makeColumnFormatMap(t),this.truncateNumbersWithPound=s}static makeColumnFormatMap(t){return t==null?new Map:t.reduce((e,n)=>{const r=E.getNormalizedType(n.columnType);if(r===null)return e;e.has(r)||e.set(r,new Map);const s=e.get(r);return s==null||s.set(n.columnName,n.format),e},new Map)}static makeColumnFormattingRule(t,e,n){return{columnType:t,columnName:e,format:n}}getColumnFormatMapForType(t,e=!1){const n=E.getNormalizedType(t);if(n!==null)return e&&!this.columnFormatMap.has(n)&&this.columnFormatMap.set(n,new Map),this.columnFormatMap.get(n)}getColumnFormat(t,e){const n=this.getColumnFormatMapForType(t);return(n==null?void 0:n.get(e))??null}getColumnTypeFormatter(t){const e=E.getNormalizedType(t);let n=this.defaultColumnFormatter;return e&&(n=this.typeFormatterMap.get(e)??n),n}getFormattedString(t,e,n="",r){if(t==null)return"";const s=this.getColumnTypeFormatter(e),a=r||this.getColumnFormat(e,n);return s.format(t,a??void 0)}get timeZone(){var e;const t=this.typeFormatterMap.get(E.dataType.DATETIME);return(e=t==null?void 0:t.dhTimeZone)==null?void 0:e.id}}function Re(f){if(f&&f.formatter){const{formatter:t}=f;return t}}function Le(f){return{timeZone:f==null?void 0:f.timeZone,defaultDateTimeFormatString:f==null?void 0:f.defaultDateTimeFormat,showTimeZone:f==null?void 0:f.showTimeZone,showTSeparator:f==null?void 0:f.showTSeparator}}function qe(f,t,e){const n=f.getColumnFormat(e,t);return n!=null&&(n.type===F.TYPE_CONTEXT_PRESET||n.type===F.TYPE_CONTEXT_CUSTOM)}const Ge={getColumnFormats:Re,getDateTimeFormatterOptions:Le,isCustomColumnFormatDefined:qe},Ve=H.module("@deephaven/jsapi-components.ConnectionBootstrap"),ie=v.createContext(null);function Qe({children:f}){const t=re(),e=be(),[n,r]=v.useState(),[s,a]=v.useState();return v.useEffect(function(){let i=!1;async function o(){try{const u=await e.getAsIdeConnection();if(i)return;a(u)}catch(u){if(i)return;r(u)}}return o(),()=>{i=!0}},[t,e]),v.useEffect(function(){if(s==null)return;function i(u){const{detail:m}=u;Ve.info("Shutdown",`${JSON.stringify(m)}`),r(`Server shutdown: ${m??"Unknown reason"}`)}return s.addEventListener(t.IdeConnection.EVENT_SHUTDOWN,i)},[t,s]),s==null||n!=null?T.jsx(ge,{"data-testid":"connection-bootstrap-loading",isLoading:s==null,errorMessage:n!=null?`${n}`:void 0}):T.jsx(ie.Provider,{value:s,children:f})}function ze(){return X(ie,"No IdeConnection available in useConnection. Was code wrapped in ConnectionBootstrap or ConnectionContext.Provider?")}export{we as B,Ke as C,V as D,Ge as F,q as I,z as P,$e as S,E as T,We as a,ae as b,re as c,X as d,A as e,Ee as f,Ye as g,se as h,Ue as i,be as j,ne as k,ke as l,j as m,w as n,Oe as o,F as p,Re as q,Le as r,qe as s,_ as t,ze as u,Qe as v,ie as w};
|
|
2
|
+
//# sourceMappingURL=useConnection-87b8bdaa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useConnection-87b8bdaa.js","sources":["../../../react-hooks/src/useContextOrThrow.ts","../../../utils/src/CanceledPromiseError.ts","../../../utils/src/TimeoutError.ts","../../../utils/src/PromiseUtils.ts","../../../utils/src/Asserts.ts","../../../utils/src/TextUtils.ts","../../../components/src/context-actions/ContextActionUtils.ts","../../../components/src/context-actions/ContextMenuItem.tsx","../../../components/src/context-actions/ContextMenu.tsx","../../../components/src/context-actions/ContextMenuRoot.tsx","../../../jsapi-bootstrap/src/useApi.ts","../../../jsapi-bootstrap/src/useCreateClient.ts","../../../jsapi-bootstrap/src/ClientBootstrap.tsx","../../../jsapi-bootstrap/src/useClient.ts","../../../jsapi-utils/src/formatters/TableColumnFormatter.ts","../../../jsapi-utils/src/formatters/BooleanColumnFormatter.ts","../../../jsapi-utils/src/formatters/CharColumnFormatter.ts","../../../jsapi-shim/src/dh.ts","../../../jsapi-utils/src/formatters/DateTimeColumnFormatter.ts","../../../jsapi-utils/src/formatters/DecimalColumnFormatter.ts","../../../jsapi-utils/src/formatters/DefaultColumnFormatter.ts","../../../jsapi-utils/src/formatters/IntegerColumnFormatter.ts","../../../jsapi-utils/src/formatters/StringColumnFormatter.ts","../../../jsapi-utils/src/DateUtils.ts","../../../filters/src/Operator.ts","../../../filters/src/Type.ts","../../../jsapi-utils/src/TableUtils.ts","../../../jsapi-utils/src/Formatter.ts","../../../jsapi-utils/src/FormatterUtils.ts","../../../app-utils/src/components/ConnectionBootstrap.tsx","../../../app-utils/src/components/useConnection.ts"],"sourcesContent":["import React, { useContext } from 'react';\n\n/**\n * Fetch a given context or throw an error if it is null or undefined.\n * @param context Context to use.\n * @param message Message to throw if context is null or undefined.\n * @returns Context, or throws\n */\nexport function useContextOrThrow<T>(\n context: React.Context<T>,\n message = 'No value available in context. Was code wrapped in a provider?'\n): NonNullable<T> {\n const value = useContext(context);\n if (value == null) {\n throw new Error(message);\n }\n return value;\n}\n\nexport default useContextOrThrow;\n","class CanceledPromiseError extends Error {\n isCanceled = true;\n}\n\nexport default CanceledPromiseError;\n","class TimeoutError extends Error {\n isTimeout = true;\n}\n\nexport default TimeoutError;\n","import CanceledPromiseError from './CanceledPromiseError';\nimport TimeoutError from './TimeoutError';\n\nexport interface CancelablePromise<T> extends Promise<T> {\n cancel: () => void;\n}\n\nexport class PromiseUtils {\n /**\n * Creates a promise that can be canceled by calling the `cancel` function\n * Pass an optional `cleanupFunc` to perform actions on the resolved item after promise is cancelled.\n * @param promise The item to resolve\n * @param cleanup Function to cleanup the resolved item after cancelation. Called after both this promise is cancelled and the wrapped item was resolved (order does not matter).\n */\n static makeCancelable<T>(\n promise: Promise<T> | T,\n cleanup?: (val: T) => void | null\n ): CancelablePromise<T> {\n let hasCanceled = false;\n let resolved: T | undefined;\n let rejectFn: (val?: unknown) => void;\n\n const wrappedPromise = new Promise((resolve, reject) => {\n rejectFn = reject;\n Promise.resolve(promise)\n .then(val => {\n if (hasCanceled) {\n if (cleanup) {\n cleanup(val);\n }\n } else {\n resolved = val;\n resolve(val);\n }\n })\n .catch(error => reject(error));\n });\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (wrappedPromise as any).cancel = () => {\n hasCanceled = true;\n rejectFn(new CanceledPromiseError());\n\n if (resolved != null && cleanup) {\n cleanup(resolved);\n }\n };\n\n return wrappedPromise as CancelablePromise<T>;\n }\n\n static isCanceled(error: unknown): boolean {\n return error instanceof CanceledPromiseError;\n }\n\n static isTimedOut(error: unknown): boolean {\n return error instanceof TimeoutError;\n }\n\n /**\n * Wrap a callback call in a Promise + setTimeout.\n * @param timeoutMs\n * @param callback\n */\n static withTimeout<T>(timeoutMs: number, callback: () => T): Promise<T> {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n try {\n resolve(callback());\n } catch (err) {\n reject(err);\n }\n }, timeoutMs);\n });\n }\n}\n","// eslint-disable-next-line import/prefer-default-export\nexport function assertNotNull<T>(\n value: T | null | undefined\n): asserts value is T {\n if (value == null) throw new Error('Value is null or undefined');\n}\n\n/**\n * Retrieve a value from a map. If the value is not found and no default value is provided, throw.\n * Use when the value _must_ be present\n * @param map The map to get the value from\n * @param key The key to fetch the value for\n * @param defaultValue A default value to set if the key is not present\n * @returns The value set for that key\n */\nexport function getOrThrow<K, V>(\n map: Map<K, V>,\n key: K,\n defaultValue: V | undefined = undefined\n): V {\n const value = map.get(key) ?? defaultValue;\n if (value !== undefined) {\n return value;\n }\n\n throw new Error(`Missing value for key ${key}`);\n}\n","class TextUtils {\n /**\n * Joins a list of strings with a comma, keeping the oxford comma and adding \"and\" as appropriate.\n * Eg.\n * One\n * One and Two\n * One, Two, and Three\n * @param items The items to join in a list\n * @param conjunction Conjunction to use between the last two items\n */\n static join(items: string[] | null, conjunction = 'and'): string {\n if (items == null || items.length === 0) {\n return '';\n }\n\n if (items.length === 1) {\n return items[0];\n }\n\n if (items.length === 2) {\n return `${items[0]} ${conjunction} ${items[1]}`;\n }\n\n const itemText = items.slice(0, items.length - 1).join(', ');\n const lastItem = items[items.length - 1];\n return `${itemText}, ${conjunction} ${lastItem}`;\n }\n\n /**\n * Converts text to lower case, handling null if necessary and returning an empty string\n * @param text The text to convert to lower case\n * @param isNullAllowed True if a null string should return an empty string from this function. If false an error is thrown if null is passed in.\n */\n static toLower(text: string | null, isNullAllowed = true): string {\n if (text == null) {\n if (isNullAllowed) {\n return '';\n }\n\n throw new Error('Null string passed in to TextUtils.toLower');\n }\n\n return text.toLowerCase();\n }\n\n /**\n *\n * @param a The string to sort\n * @param b Second string to sort\n * @param isAscending Whether to sort ascending or descending\n */\n static sort(a: string, b: string, isAscending = true): number {\n if (a < b) {\n return isAscending ? -1 : 1;\n }\n if (a > b) {\n return isAscending ? 1 : -1;\n }\n return 0;\n }\n}\n\nexport default TextUtils;\n","import { IconDefinition } from '@deephaven/icons';\nimport React from 'react';\nimport type { Shortcut } from '../shortcuts';\n\nexport type ResolvableContextAction =\n | ContextAction\n | Promise<ContextAction[]>\n | (() => Promise<ContextAction[]> | ContextAction[] | ContextAction);\n\nexport type MenuItem = ContextAction | Promise<ContextAction[]>;\n\nexport interface ContextAction {\n title?: string;\n description?: string;\n action?(event?: Event): void;\n actions?: ResolvableContextAction[];\n icon?: IconDefinition | React.ReactElement;\n iconColor?: string;\n shortcut?: Shortcut;\n isGlobal?: boolean;\n group?: number;\n order?: number;\n disabled?: boolean;\n menuElement?: React.ReactElement;\n iconOutline?: boolean;\n}\n\nexport interface ContextActionEvent extends MouseEvent {\n contextActions: ResolvableContextAction[];\n}\n\nexport function isPromise<A, T>(value: A | Promise<T>): value is Promise<T> {\n return (value as Promise<T>).then !== undefined;\n}\n\nclass ContextActionUtils {\n static actionsDisabled = false;\n\n static disableAllActions(): void {\n ContextActionUtils.actionsDisabled = true;\n }\n\n static enableAllActions(): void {\n ContextActionUtils.actionsDisabled = false;\n }\n\n static isContextActionEvent(e: MouseEvent): e is ContextActionEvent {\n return Array.isArray((e as ContextActionEvent).contextActions);\n }\n\n /**\n * Compare two action items. Useful in Array.sort\n * @param a First context action to compare\n * @param b Second context action to compare\n */\n static compareActions(a: ContextAction, b: ContextAction): number {\n if (a.group !== b.group) {\n return (a.group ?? 0) > (b.group ?? 0) ? 1 : -1;\n }\n\n if (a.order !== b.order) {\n return (a.order ?? 0) > (b.order ?? 0) ? 1 : -1;\n }\n\n if (a.title !== b.title) {\n return (a.title ?? '') > (b.title ?? '') ? 1 : -1;\n }\n\n if (a !== b) {\n return a > b ? 1 : -1;\n }\n\n return 0;\n }\n\n /**\n *\n * @param actions The array of actions to sort\n */\n static sortActions(actions: ContextAction[]): ContextAction[] {\n if (actions == null || !Array.isArray(actions)) {\n return [];\n }\n\n const sortedActions = actions.slice();\n sortedActions.sort(ContextActionUtils.compareActions);\n return sortedActions;\n }\n\n static isMacPlatform(): boolean {\n const { platform } = window.navigator;\n return platform.startsWith('Mac');\n }\n\n /**\n * Retrieve the preferred modifier key based on the current platform\n */\n static getModifierKey(): 'metaKey' | 'ctrlKey' {\n if (ContextActionUtils.isMacPlatform()) {\n return 'metaKey';\n }\n\n return 'ctrlKey';\n }\n\n /**\n * Returns true if the modifier key for the current platform is down for the event (Ctrl for windows/linux, Command (meta) for mac)\n * @param event The event to get the meta key status from\n */\n static isModifierKeyDown(\n event: KeyboardEvent | MouseEvent | React.KeyboardEvent | React.MouseEvent\n ): boolean {\n const modifierKey = ContextActionUtils.getModifierKey();\n return event[modifierKey];\n }\n\n /**\n * Returns the menu items for the provided context actions, or empty array if none found.\n * @param actionsParam The actions to get menu items for\n * @param includePromises Whether or not to include promises in the returned menu items\n */\n static getMenuItems(\n actionsParam: ResolvableContextAction | ResolvableContextAction[],\n includePromises?: true\n ): MenuItem[];\n\n // If ignoring promises, then the return type is narrowed\n static getMenuItems(\n actionsParam: ResolvableContextAction | ResolvableContextAction[],\n includePromises: false\n ): ContextAction[];\n\n static getMenuItems(\n actionsParam: ResolvableContextAction | ResolvableContextAction[],\n includePromises = true\n ): MenuItem[] {\n let menuItems: MenuItem[] = [];\n let actions = actionsParam;\n if (!Array.isArray(actions)) {\n actions = [actions];\n }\n\n for (let i = 0; i < actions.length; i += 1) {\n const action = actions[i];\n let newMenuItems:\n | ContextAction\n | ContextAction[]\n | Promise<ContextAction[]>;\n if (typeof action === 'function') {\n newMenuItems = action();\n } else {\n newMenuItems = action;\n }\n\n if (newMenuItems != null) {\n if (newMenuItems instanceof Promise) {\n if (includePromises) {\n menuItems.push(newMenuItems);\n }\n } else if (Array.isArray(newMenuItems)) {\n menuItems = menuItems.concat(newMenuItems);\n } else {\n menuItems.push(newMenuItems);\n }\n }\n }\n\n menuItems = menuItems.filter(\n action =>\n (action as ContextAction).title !== undefined ||\n (action as Promise<ContextAction[]>).then != null ||\n (action as ContextAction).menuElement\n );\n\n return menuItems;\n }\n\n /**\n * Returns the index of the next menu item in a list that doesn't have a disabled=true prop\n * @param startIndex the starting position for the iteration\n * @param delta the direction of travel, -1 or 1\n * @param menuItems an array of menuItems\n */\n static getNextMenuItem(\n startIndex: number,\n delta: -1 | 1,\n menuItems: MenuItem[]\n ): number {\n let firstIndex = startIndex;\n if (firstIndex < 0 && delta < 0) {\n // if menu index is -1 and delta -1 manually set start point\n firstIndex = menuItems.length;\n }\n // find the next non disabled menu option, iterating the list only once\n for (let i = 1; i < menuItems.length + 1; i += 1) {\n const menuIndex =\n (firstIndex + delta * i + menuItems.length) % menuItems.length;\n const item = menuItems[menuIndex];\n if (!(item instanceof Promise) && item.disabled !== true) {\n return menuIndex;\n }\n }\n return startIndex;\n }\n}\n\nexport default ContextActionUtils;\n","import React from 'react';\nimport classNames from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { vsChevronRight, IconDefinition } from '@deephaven/icons';\nimport type { ContextAction } from './ContextActionUtils';\n\ninterface ContextMenuItemProps {\n children?: React.ReactNode;\n closeMenu(closeAll: boolean): void;\n isKeyboardSelected?: boolean;\n isMouseSelected?: boolean;\n menuItem: ContextAction;\n onMenuItemClick(item: ContextAction, e: React.MouseEvent): void;\n onMenuItemMouseMove(item: ContextAction, e: React.MouseEvent): void;\n onMenuItemContextMenu(item: ContextAction, e: React.MouseEvent): void;\n 'data-testid'?: string;\n}\n\nconst ContextMenuItem = React.forwardRef<HTMLDivElement, ContextMenuItemProps>(\n (props: ContextMenuItemProps, ref) => {\n function handleMenuItemClick(e: React.MouseEvent) {\n const { menuItem, onMenuItemClick } = props;\n onMenuItemClick(menuItem, e);\n }\n\n function handleMenuItemMouseMove(e: React.MouseEvent) {\n const { menuItem, onMenuItemMouseMove } = props;\n onMenuItemMouseMove(menuItem, e);\n }\n\n function handleMenuItemContextMenu(e: React.MouseEvent) {\n const { menuItem, onMenuItemContextMenu } = props;\n onMenuItemContextMenu(menuItem, e);\n }\n\n function renderCustomMenuElement(\n element: React.ReactElement,\n iconElement: IconDefinition | React.ReactElement | null,\n displayShortcut: string | undefined\n ): JSX.Element {\n // Don't pass forwardedProps if menuElement is a native DOM node\n if (typeof element.type === 'string') {\n return element;\n }\n const {\n closeMenu,\n menuItem,\n isKeyboardSelected,\n isMouseSelected,\n 'data-testid': dataTestId,\n } = props;\n const forwardedProps = {\n menuItem,\n closeMenu,\n isKeyboardSelected,\n isMouseSelected,\n iconElement,\n displayShortcut,\n 'data-testid': dataTestId,\n };\n return React.cloneElement(element, {\n forwardedProps,\n });\n }\n\n const {\n children,\n menuItem,\n isKeyboardSelected = false,\n isMouseSelected = false,\n 'data-testid': dataTestId,\n } = props;\n\n const displayShortcut = menuItem.shortcut?.getDisplayText();\n let icon: IconDefinition | React.ReactElement | null = null;\n if (menuItem.icon) {\n const menuItemIcon = menuItem.icon;\n if (React.isValidElement(menuItemIcon)) {\n icon = menuItemIcon;\n } else {\n let style: React.CSSProperties | undefined;\n if (\n menuItem.iconColor != null &&\n (menuItem.disabled === undefined || !menuItem.disabled)\n ) {\n style = { color: menuItem.iconColor };\n }\n icon = <FontAwesomeIcon icon={menuItemIcon} style={style} />;\n }\n }\n\n let subMenuIndicator = null;\n const isSubMenuActive = Boolean(children);\n if (menuItem.actions) {\n subMenuIndicator = <FontAwesomeIcon icon={vsChevronRight} />;\n }\n let content = null;\n if (menuItem.menuElement) {\n content = (\n <div className=\"custom-menu-item\" onMouseMove={handleMenuItemMouseMove}>\n {renderCustomMenuElement(menuItem.menuElement, icon, displayShortcut)}\n </div>\n );\n } else {\n const menuItemDisabled = menuItem.disabled;\n const iconHasOutline = menuItem.iconOutline;\n content = (\n <button\n type=\"button\"\n className={classNames(\n 'btn-context-menu',\n { disabled: menuItemDisabled },\n {\n active:\n (isSubMenuActive || isMouseSelected) &&\n (menuItemDisabled === undefined || !menuItemDisabled),\n },\n {\n 'keyboard-active':\n isKeyboardSelected &&\n (menuItemDisabled === undefined || !menuItemDisabled),\n }\n )}\n onClick={handleMenuItemClick}\n onMouseMove={handleMenuItemMouseMove}\n onContextMenu={handleMenuItemContextMenu}\n title={menuItem.description ?? ''}\n >\n <div className=\"btn-context-menu-wrapper\">\n <span className={classNames('icon', { outline: iconHasOutline })}>\n {icon}\n </span>\n <span className=\"title\">{menuItem.title}</span>\n {displayShortcut !== undefined && (\n <span className=\"shortcut\">{displayShortcut}</span>\n )}\n {subMenuIndicator && (\n <span\n className={classNames('submenu-indicator', {\n disabled: menuItemDisabled,\n })}\n >\n {subMenuIndicator}\n </span>\n )}\n </div>\n </button>\n );\n }\n\n return (\n <div className=\"context-menu-item\" ref={ref} data-testid={dataTestId}>\n {children}\n {content}\n </div>\n );\n }\n);\n\nContextMenuItem.displayName = 'ContextMenuItem';\n\nContextMenuItem.defaultProps = {\n children: null,\n isKeyboardSelected: false,\n isMouseSelected: false,\n 'data-testid': undefined,\n};\n\nexport default ContextMenuItem;\n","import React, { PureComponent } from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport { PromiseUtils, CancelablePromise } from '@deephaven/utils';\nimport ContextActionUtils, {\n ContextAction,\n ResolvableContextAction,\n} from './ContextActionUtils';\nimport ContextMenuItem from './ContextMenuItem';\nimport LoadingSpinner from '../LoadingSpinner';\n\nconst log = Log.module('ContextMenu');\n\ninterface ContextMenuProps {\n top: number;\n left: number;\n updatePosition(top: number, left: number): void;\n // only submenus will have these, defaults to 0 otherwise\n // represents the width height of the parent menu item\n subMenuParentWidth: number;\n subMenuParentHeight: number;\n actions: ResolvableContextAction[];\n closeMenu(closeAll: boolean): void;\n onMenuClosed(menu: ContextMenu): void;\n onMenuOpened(menu: ContextMenu): void;\n options: {\n doNotVerifyPosition?: boolean;\n separateKeyboardMouse?: boolean;\n initialKeyboardIndex?: number;\n };\n menuStyle: React.CSSProperties;\n 'data-testid'?: string;\n}\n\ninterface ContextMenuState {\n menuItems: ContextAction[];\n pendingItems: CancelablePromise<ContextAction[]>[];\n activeSubMenu: number | null;\n hasOverflow: boolean;\n subMenuTop: number | null;\n subMenuLeft: number | null;\n subMenuParentWidth: number;\n subMenuParentHeight: number;\n keyboardIndex: number;\n mouseIndex: number;\n}\n\n/** Do not use this class directly. Use ContextMenuRoot and ContextActions instead. */\nclass ContextMenu extends PureComponent<ContextMenuProps, ContextMenuState> {\n static defaultProps = {\n subMenuParentWidth: 0,\n subMenuParentHeight: 0,\n closeMenu(): void {\n // no-op\n },\n onMenuOpened(): void {\n // no-op\n },\n onMenuClosed(): void {\n // no-op\n },\n options: {},\n menuStyle: {},\n 'data-testid': undefined,\n };\n\n static handleContextMenu(e: React.MouseEvent): void {\n if (e.metaKey) {\n return;\n }\n\n e.stopPropagation();\n e.preventDefault();\n }\n\n constructor(props: ContextMenuProps) {\n super(props);\n\n this.handleBlur = this.handleBlur.bind(this);\n this.handleCloseSubMenu = this.handleCloseSubMenu.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleMenuItemClick = this.handleMenuItemClick.bind(this);\n this.handleMenuItemContextMenu = this.handleMenuItemContextMenu.bind(this);\n this.handleMenuItemMouseMove = this.handleMenuItemMouseMove.bind(this);\n this.handleMouseLeave = this.handleMouseLeave.bind(this);\n this.handleWindowResize = this.handleWindowResize.bind(this);\n\n this.container = React.createRef();\n this.oldFocus = document.activeElement;\n this.activeSubMenuRef = React.createRef();\n this.subMenuTimer = 0;\n this.rAF = 0;\n\n this.initialPosition = { top: props.top, left: props.left };\n\n this.state = {\n menuItems: [],\n pendingItems: [],\n activeSubMenu: null,\n hasOverflow: false,\n subMenuTop: null,\n subMenuLeft: null,\n subMenuParentWidth: 0,\n subMenuParentHeight: 0,\n keyboardIndex: -1,\n mouseIndex: -1,\n };\n }\n\n componentDidMount(): void {\n this.initMenu();\n\n this.verifyPosition();\n\n window.addEventListener('resize', this.handleWindowResize);\n\n // rAF is needed to wait for a submenus popper to be created before\n // attempting to set focus, however on a quick mount/unmount when\n // mousing past an item, the submenu could be unmounted before the\n // async rAF finishes, so it is cancelled in willUnmount()\n this.rAF = window.requestAnimationFrame(() => {\n this.container.current?.focus();\n\n const { onMenuOpened } = this.props;\n onMenuOpened(this);\n });\n }\n\n componentDidUpdate(\n prevProps: ContextMenuProps,\n prevState: ContextMenuState\n ): void {\n const { actions } = this.props;\n const { activeSubMenu } = this.state;\n\n if (activeSubMenu !== prevState.activeSubMenu) {\n if (activeSubMenu == null) {\n // close sub menu, refocus parent menu\n this.container.current?.focus();\n } else {\n // open sub menu, set its initial position\n this.setActiveSubMenuPosition();\n }\n }\n\n if (prevProps.actions !== actions) {\n this.initMenu();\n\n if (\n this.container.current == null ||\n !this.container.current.contains(document.activeElement)\n ) {\n this.container.current?.focus();\n }\n }\n\n this.verifyPosition();\n }\n\n componentWillUnmount(): void {\n this.cancelPromises();\n window.removeEventListener('resize', this.handleWindowResize);\n cancelAnimationFrame(this.rAF);\n }\n\n container: React.RefObject<HTMLDivElement>;\n\n oldFocus: Element | null;\n\n activeSubMenuRef: React.RefObject<HTMLDivElement>;\n\n subMenuTimer: number;\n\n rAF: number;\n\n initialPosition: { top: number; left: number };\n\n getKeyboardIndex(): number {\n const { options } = this.props;\n if (\n options.separateKeyboardMouse !== undefined &&\n options.separateKeyboardMouse\n ) {\n const { keyboardIndex } = this.state;\n return keyboardIndex;\n }\n\n return this.getMouseIndex();\n }\n\n setKeyboardIndex(index: number): void {\n const { options } = this.props;\n if (\n options.separateKeyboardMouse !== undefined &&\n options.separateKeyboardMouse\n ) {\n this.setState({ keyboardIndex: index });\n } else {\n this.setMouseIndex(index);\n }\n }\n\n getMouseIndex(): number {\n const { mouseIndex } = this.state;\n return mouseIndex;\n }\n\n setMouseIndex(index: number): void {\n this.setState({ mouseIndex: index });\n }\n\n initMenu(): void {\n // cancel any pending close and promises\n this.cancelPromises();\n cancelAnimationFrame(this.rAF);\n\n const { options } = this.props;\n let keyboardIndex = options.initialKeyboardIndex;\n if (keyboardIndex === undefined) {\n keyboardIndex = -1;\n }\n\n const { actions } = this.props;\n const menuItems = ContextActionUtils.getMenuItems(actions);\n const nonPromiseItems: ContextAction[] = [];\n for (let i = menuItems.length - 1; i >= 0; i -= 1) {\n const menuItem = menuItems[i];\n if (menuItem instanceof Promise) {\n this.initMenuPromise(menuItem as Promise<ContextAction[]>);\n } else {\n nonPromiseItems.push(menuItem as ContextAction);\n }\n }\n\n this.setState({\n mouseIndex: -1,\n keyboardIndex,\n activeSubMenu: null,\n menuItems: ContextActionUtils.sortActions(nonPromiseItems),\n });\n }\n\n initMenuPromise(promise: Promise<ContextAction[]>): void {\n // make all promises cancellable\n const cancellablePromise = PromiseUtils.makeCancelable(promise);\n\n this.setState(state => ({\n pendingItems: state.pendingItems.concat(cancellablePromise),\n }));\n\n cancellablePromise.then(\n resolvedMenuItems => {\n this.setState(state => {\n const index = state.pendingItems.indexOf(cancellablePromise);\n if (index >= 0) {\n const pendingItems = state.pendingItems.slice();\n pendingItems.splice(index, 1);\n\n return {\n menuItems: ContextActionUtils.sortActions(\n state.menuItems.concat(resolvedMenuItems)\n ),\n pendingItems,\n };\n }\n // This item is stale, don't update the menu\n return null;\n });\n },\n error => {\n if (PromiseUtils.isCanceled(error)) {\n return; // Canceled promise is ignored\n }\n\n // remove failed item from pending list\n this.setState(state => {\n const index = state.pendingItems.indexOf(cancellablePromise);\n if (index >= 0) {\n const pendingItems = state.pendingItems.slice();\n pendingItems.splice(index, 1);\n return {\n pendingItems,\n };\n }\n return null;\n });\n\n // Log the error\n log.error(error);\n }\n );\n }\n\n cancelPromises(): void {\n const { pendingItems } = this.state;\n pendingItems.map(item => item.cancel());\n }\n\n /**\n * Sets the unverfied start position of a submenu. Submenu then self-verfies\n * its own position and potentially reports back a new position.\n */\n setActiveSubMenuPosition(): void {\n if (this.activeSubMenuRef.current === null) return;\n const parentRect = this.activeSubMenuRef.current.getBoundingClientRect();\n\n // intentionally rect.right, we want the sub menu to start at the right edge of the current menu\n this.setState({\n subMenuTop: parentRect.top,\n subMenuLeft: parentRect.right,\n subMenuParentHeight: parentRect.height,\n subMenuParentWidth: parentRect.width,\n });\n }\n\n /**\n * Verifies the position of this menu in relation to the parent to make sure it's on screen.\n * Will update the top left state (updatePosition) if necessary (causing a re-render)\n * By default it tries to top-align with parent, at the right side of the parent.\n * Because we aren't a native context menu and can't escape window bounds, we also do\n * somethings to better fit on screen, such as the \"nudge\" offset position, and further\n * allow overflow scrolling for large menus in a small window.\n */\n verifyPosition(): void {\n const {\n options,\n updatePosition,\n subMenuParentWidth,\n subMenuParentHeight,\n top: oldTop,\n left: oldLeft,\n } = this.props;\n\n if (\n !this.container.current ||\n (options.doNotVerifyPosition != null && options.doNotVerifyPosition)\n ) {\n return;\n }\n\n // initial position is used rather than current position,\n // as the number of menu items can change (actions can bubble)\n // and menu should always be positioned relative to spawn point\n let { top, left } = this.initialPosition;\n const {\n width,\n height,\n } = this.container.current?.getBoundingClientRect() ?? {\n width: 0,\n height: 0,\n };\n const hasOverflow =\n (this.container.current?.scrollHeight ?? 0) > window.innerHeight;\n\n if (height === 0 || width === 0) {\n // We don't have a height or width yet, don't bother doing anything\n return;\n }\n\n // does it fit below?\n if (top + height > window.innerHeight) {\n // can it be flipped to above? include offset if submenu (defaults to 0 if not submenu)\n if (top - height - subMenuParentHeight > 0) {\n // flip like a native menu would\n top -= height - subMenuParentHeight;\n } else {\n // still doesnt fit? okay, position at bottom edge\n top = window.innerHeight - height;\n }\n }\n\n if (left + width > window.innerWidth) {\n // less picky about left right positioning, just keep it going off to right\n left = left - width - subMenuParentWidth;\n }\n\n if (oldLeft !== left || oldTop !== top) {\n // parent owns positioning as single source of truth, ask to update props\n this.setState({ hasOverflow });\n updatePosition(top, left);\n }\n }\n\n // since window resize doesn't trigger blur, listen and close the menu\n handleWindowResize(): void {\n if (!this.container.current) {\n return;\n }\n this.closeMenu(true);\n }\n\n handleBlur(e: React.FocusEvent<HTMLDivElement>): void {\n if (!this.container.current) {\n log.warn('Container is null!');\n return;\n }\n\n if (!this.container.current.contains(e.relatedTarget as Node)) {\n let element: HTMLElement | null = e.relatedTarget as HTMLElement;\n let isContextMenuChild = false;\n while (element && !isContextMenuChild) {\n isContextMenuChild = element.hasAttribute('data-dh-context-menu');\n element = element.parentElement;\n }\n\n if (!isContextMenuChild) {\n // close all submenus on blur\n this.closeMenu(true);\n }\n }\n }\n\n /** Returns whether the specified key should remove the menu. Depends on the side the parent is on. */\n isEscapeKey(key: string): boolean {\n const { left } = this.props;\n return (\n key === 'Escape' ||\n (left < 0 && key === 'ArrowRight') ||\n key === 'ArrowLeft'\n );\n }\n\n handleKeyDown(e: React.KeyboardEvent<HTMLDivElement>): void {\n const { menuItems } = this.state;\n const oldFocus = this.getKeyboardIndex();\n let newFocus: number | null = oldFocus;\n let openSubMenu = false;\n\n if (e.key === 'Enter' || e.key === ' ') {\n if (oldFocus >= 0 && oldFocus < menuItems.length) {\n this.handleMenuItemClick(\n menuItems[oldFocus],\n (e as React.SyntheticEvent) as React.MouseEvent\n );\n }\n return;\n }\n\n if (e.key === 'ArrowRight') {\n if (oldFocus >= 0 && oldFocus <= menuItems.length) {\n openSubMenu = true;\n } else {\n newFocus = 0;\n }\n } else if (this.isEscapeKey(e.key)) {\n newFocus = null;\n } else if (e.key === 'ArrowUp' || (e.shiftKey && e.key === 'Tab')) {\n newFocus = ContextActionUtils.getNextMenuItem(newFocus, -1, menuItems);\n } else if (e.key === 'ArrowDown' || e.key === 'Tab') {\n newFocus = ContextActionUtils.getNextMenuItem(newFocus, 1, menuItems);\n }\n\n if (openSubMenu) {\n this.openSubMenu(oldFocus);\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n if (oldFocus !== newFocus) {\n if (newFocus !== null) {\n this.setKeyboardIndex(newFocus);\n } else {\n this.closeMenu();\n if (this.oldFocus instanceof HTMLElement) {\n this.oldFocus.focus();\n }\n }\n\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n openSubMenu(index: number): void {\n const { menuItems, activeSubMenu } = this.state;\n const newSubMenu = menuItems[index].actions ? index : null;\n if (activeSubMenu === newSubMenu) return;\n this.setState({\n activeSubMenu: newSubMenu,\n subMenuTop: null,\n subMenuLeft: null,\n });\n }\n\n closeMenu(closeAll = false): void {\n const { closeMenu, onMenuClosed } = this.props;\n cancelAnimationFrame(this.rAF);\n this.rAF = window.requestAnimationFrame(() => {\n closeMenu(closeAll);\n onMenuClosed(this);\n });\n }\n\n closeSubMenu(): void {\n this.setState({\n activeSubMenu: null,\n });\n }\n\n handleCloseSubMenu(closeAllMenus: boolean): void {\n if (closeAllMenus) {\n this.closeMenu(true);\n } else {\n this.closeSubMenu();\n }\n }\n\n handleMenuItemClick(menuItem: ContextAction, e: React.MouseEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n const { menuItems } = this.state;\n if (\n menuItem != null &&\n (menuItem.disabled === undefined || !menuItem.disabled)\n ) {\n if (menuItem.actions != null) {\n this.openSubMenu(menuItems.indexOf(menuItem));\n } else if (menuItem.action != null) {\n menuItem.action();\n this.closeMenu(true);\n }\n }\n }\n\n handleMenuItemContextMenu(\n menuItem: ContextAction,\n e: React.MouseEvent\n ): void {\n if (e.metaKey) {\n return;\n }\n\n this.handleMenuItemClick(menuItem, e);\n }\n\n handleMenuItemMouseMove(menuItem: ContextAction): void {\n const { menuItems } = this.state;\n const focusIndex = menuItems.indexOf(menuItem);\n this.setMouseIndex(focusIndex);\n\n if (\n focusIndex >= 0 &&\n focusIndex < menuItems.length &&\n (menuItem.disabled === undefined || !menuItem.disabled)\n ) {\n this.openSubMenu(focusIndex);\n }\n }\n\n handleMouseLeave(): void {\n this.setMouseIndex(-1);\n }\n\n render(): JSX.Element {\n const menuItemElements = [];\n const { top, left } = this.props;\n const {\n activeSubMenu,\n hasOverflow,\n keyboardIndex,\n menuItems,\n mouseIndex,\n pendingItems,\n subMenuTop,\n subMenuLeft,\n subMenuParentWidth,\n subMenuParentHeight,\n } = this.state;\n for (let i = 0; i < menuItems.length; i += 1) {\n const menuItem = menuItems[i];\n\n if (i > 0 && menuItem.group !== menuItems[i - 1].group) {\n menuItemElements.push(<hr key={`${i}.separator`} />);\n }\n\n const menuItemElement = (\n <ContextMenuItem\n key={i}\n ref={activeSubMenu === i ? this.activeSubMenuRef : null}\n isKeyboardSelected={keyboardIndex === i}\n isMouseSelected={mouseIndex === i}\n menuItem={menuItem}\n closeMenu={this.handleCloseSubMenu}\n onMenuItemClick={this.handleMenuItemClick}\n onMenuItemMouseMove={this.handleMenuItemMouseMove}\n onMenuItemContextMenu={this.handleMenuItemContextMenu}\n />\n );\n\n menuItemElements.push(menuItemElement);\n }\n\n let pendingElement = null;\n if (pendingItems.length > 0) {\n pendingElement = (\n <div className=\"loading\">\n <LoadingSpinner />\n </div>\n );\n }\n\n const { menuStyle, 'data-testid': dataTestId } = this.props;\n\n // don't show submenu until it has an position initialized\n const showSubmenu =\n activeSubMenu !== null && subMenuTop !== null && subMenuLeft !== null;\n\n return (\n <>\n <div\n className={classNames(\n { 'has-overflow': hasOverflow },\n 'context-menu-container'\n )}\n style={{ top, left, ...menuStyle }}\n ref={this.container}\n data-dh-context-menu\n onBlur={this.handleBlur}\n onKeyDown={this.handleKeyDown}\n onMouseLeave={this.handleMouseLeave}\n onContextMenu={ContextMenu.handleContextMenu}\n role=\"menuitem\"\n tabIndex={0}\n data-testid={dataTestId}\n >\n {menuItemElements}\n {pendingElement}\n </div>\n {showSubmenu &&\n activeSubMenu !== null &&\n subMenuTop !== null &&\n subMenuLeft !== null && (\n <ContextMenu\n key={`sub-${activeSubMenu}`}\n actions={menuItems[activeSubMenu].actions || []}\n closeMenu={this.handleCloseSubMenu}\n top={subMenuTop}\n left={subMenuLeft}\n updatePosition={(verifiedTop, verifiedLeft) => {\n this.setState({\n subMenuTop: verifiedTop,\n subMenuLeft: verifiedLeft,\n });\n }}\n subMenuParentWidth={subMenuParentWidth}\n subMenuParentHeight={subMenuParentHeight}\n />\n )}\n </>\n );\n }\n}\n\nexport default ContextMenu;\n","import React, { Component } from 'react';\nimport classNames from 'classnames';\nimport ContextMenu from './ContextMenu';\nimport ContextActionUtils, { MenuItem } from './ContextActionUtils';\n\ntype ContextMenuRootProps = Record<string, never> & {\n 'data-testid'?: string;\n};\n\ninterface ContextMenuRootState {\n actions: MenuItem[] | null;\n left: number;\n top: number;\n}\n\n/**\n * Put at your root container, any contextmenu events that are unhandled in the root container will be handled by this\n */\nclass ContextMenuRoot extends Component<\n ContextMenuRootProps,\n ContextMenuRootState\n> {\n constructor(props: ContextMenuRootProps) {\n super(props);\n\n this.handleMenuClose = this.handleMenuClose.bind(this);\n this.handleContextMenu = this.handleContextMenu.bind(this);\n this.container = React.createRef();\n this.openMenu = React.createRef();\n\n this.state = {\n actions: null,\n left: 0,\n top: 0,\n };\n }\n\n componentDidMount(): void {\n if (this.container.current?.parentElement) {\n this.container.current.parentElement.addEventListener(\n 'contextmenu',\n this.handleContextMenu\n );\n }\n }\n\n componentWillUnmount(): void {\n if (this.container.current?.parentElement) {\n this.container.current.parentElement.removeEventListener(\n 'contextmenu',\n this.handleContextMenu\n );\n }\n }\n\n container: React.RefObject<HTMLDivElement>;\n\n openMenu: React.RefObject<ContextMenu>;\n\n handleContextMenu(e: MouseEvent): void {\n if (!ContextActionUtils.isContextActionEvent(e)) {\n return;\n }\n\n if (!this.container.current) {\n return;\n }\n\n if (e.metaKey || e.ctrlKey) {\n // debug escape hatch to native menu\n return;\n }\n\n const contextActions = ContextActionUtils.getMenuItems(e.contextActions);\n\n const parentRect = this.container.current.getBoundingClientRect();\n const top = e.clientY - parentRect.top;\n const left = e.clientX - parentRect.left;\n\n if (contextActions.length === 0) {\n // This code path seems to only exist for Chrome on Mac\n // Mac appears to trigger contextmenu events on mousedown vs. mouseup on Windows\n // Mouseup on Windows triggers blur before contextmenu which effectively does what this path does\n if (e.target === this.container.current) {\n // re-emit right clicks that hit the context-root blocking layer\n e.preventDefault();\n\n // Set actions to null removes the menu\n // That allows a new menu to be opened on a different element so initial position is set properly\n // Otherwise the instance of this menu may be reused\n // A new contextmenu event is triggered on the element at the location the user clicked on the blocking layer\n this.setState({ actions: null }, () => {\n const element = document.elementFromPoint(left, top); // x y\n\n const mouseEvent = new MouseEvent('contextmenu', {\n clientX: e.clientX,\n clientY: e.clientY,\n bubbles: true,\n cancelable: true,\n });\n\n element?.dispatchEvent(mouseEvent);\n });\n return;\n }\n\n // target was a menu item\n return;\n }\n\n // new clicks, set actions\n e.preventDefault();\n this.setState({\n actions: contextActions,\n top,\n left,\n });\n }\n\n handleMenuClose(menu: ContextMenu): void {\n if (menu === this.openMenu.current) {\n this.setState({ actions: null });\n }\n }\n\n render(): JSX.Element {\n let menu = null;\n const { 'data-testid': dataTestId } = this.props;\n const { actions, top, left } = this.state;\n if (actions) {\n menu = (\n <ContextMenu\n ref={this.openMenu}\n actions={actions}\n onMenuClosed={this.handleMenuClose}\n top={top}\n left={left}\n updatePosition={(verifiedTop, verifiedLeft) => {\n this.setState({ top: verifiedTop, left: verifiedLeft });\n }}\n data-testid={dataTestId}\n />\n );\n }\n return (\n <div\n className={classNames('context-menu-root', { active: actions })}\n ref={this.container}\n >\n {menu}\n </div>\n );\n }\n}\n\nexport default ContextMenuRoot;\n","import { useContextOrThrow } from '@deephaven/react-hooks';\nimport { ApiContext } from './ApiBootstrap';\n\nexport function useApi() {\n return useContextOrThrow(\n ApiContext,\n 'No API available in useApi. Was code wrapped in ApiBootstrap or ApiContext.Provider?'\n );\n}\n\nexport default useApi;\n","import { ConnectOptions, CoreClient } from '@deephaven/jsapi-types';\nimport { useEffect, useMemo } from 'react';\nimport useApi from './useApi';\n\nexport function useCreateClient(\n serverUrl: string,\n options?: ConnectOptions\n): CoreClient {\n const api = useApi();\n const client = useMemo(() => new api.CoreClient(serverUrl, options), [\n api,\n serverUrl,\n options,\n ]);\n useEffect(\n () => () => {\n client.disconnect();\n },\n [client]\n );\n return client;\n}\n\nexport default useCreateClient;\n","import React, { createContext } from 'react';\nimport { ConnectOptions, CoreClient } from '@deephaven/jsapi-types';\nimport useCreateClient from './useCreateClient';\n\nexport const ClientContext = createContext<CoreClient | null>(null);\n\nexport type ClientBootstrapProps = {\n /** URL of the server to connect to */\n serverUrl: string;\n\n /** Connection options to pass to CoreClient when connecting */\n options?: ConnectOptions;\n\n /**\n * The children to render wrapped with the ClientContext.\n * Will not render children until the client is created.\n */\n children: React.ReactNode;\n};\n\n/**\n * ClientBootstrap component. Handles creating the client.\n */\nexport function ClientBootstrap({\n serverUrl,\n options,\n children,\n}: ClientBootstrapProps) {\n const client = useCreateClient(serverUrl, options);\n return (\n <ClientContext.Provider value={client}>{children}</ClientContext.Provider>\n );\n}\n\nexport default ClientBootstrap;\n","import { useContextOrThrow } from '@deephaven/react-hooks';\nimport { ClientContext } from './ClientBootstrap';\n\nexport function useClient() {\n return useContextOrThrow(\n ClientContext,\n 'No Client available in useClient. Was code wrapped in ClientBootstrap or ClientContext.Provider?'\n );\n}\n\nexport default useClient;\n","/* eslint class-methods-use-this: \"off\" */\n/**\n * Default column data formatter. Just interpolates the value as a string and returns.\n * Extend this class and register with TableUtils to make use of it.\n */\n\nexport type TableColumnFormatType =\n | 'type-global'\n | 'type-context-preset'\n | 'type-context-custom';\n\nexport type TableColumnFormat = {\n label: string;\n formatString: string;\n type: TableColumnFormatType;\n};\n\nexport class TableColumnFormatter<T = unknown> {\n static TYPE_GLOBAL: TableColumnFormatType = 'type-global';\n\n static TYPE_CONTEXT_PRESET: TableColumnFormatType = 'type-context-preset';\n\n static TYPE_CONTEXT_CUSTOM: TableColumnFormatType = 'type-context-custom';\n\n /**\n * Validates format object\n * @param format Format object\n * @returns true for valid object\n */\n static isValid(format: TableColumnFormat): boolean {\n return true;\n }\n\n /**\n * Check if the given formats match\n * @param formatA format object to check\n * @param formatB format object to check\n * @returns True if the formats match\n */\n static isSameFormat(\n formatA: TableColumnFormat | null,\n formatB: TableColumnFormat | null\n ): boolean {\n throw new Error('isSameFormat not implemented');\n }\n\n /**\n * Create and return a Format object\n * @param label The label of the format object\n * @param formatString Format string to use for the format\n * @param type The type of column to use for this format\n * @returns A format object\n */\n static makeFormat(\n label: string,\n formatString: string,\n type: TableColumnFormatType\n ): TableColumnFormat {\n return { label, formatString, type };\n }\n\n /**\n * @param value The value to format\n * @param format Optional format object with value transformation options\n * @returns String the formatted text string of the value passed in.\n */\n format(value: T, format?: Partial<TableColumnFormat>): string {\n return '';\n }\n}\n\nexport default TableColumnFormatter;\n","/* eslint class-methods-use-this: \"off\" */\n/* eslint no-unused-vars: \"off\" */\nimport TableColumnFormatter from './TableColumnFormatter';\n\n/** Column formatter for booleans */\nclass BooleanColumnFormatter extends TableColumnFormatter<boolean | number> {\n format(value: boolean | number): string {\n switch (value) {\n case 1:\n case true:\n return 'true';\n case 0:\n case false:\n return 'false';\n default:\n return '';\n }\n }\n}\n\nexport default BooleanColumnFormatter;\n","/* eslint class-methods-use-this: \"off\" */\n/* eslint no-unused-vars: \"off\" */\nimport TableColumnFormatter from './TableColumnFormatter';\n\n/** Column formatter for chars */\nclass CharColumnFormatter extends TableColumnFormatter<number> {\n format(value: number): string {\n return String.fromCharCode(value);\n }\n}\n\nexport default CharColumnFormatter;\n","// The Deephaven API script isn't packaged as a module (yet), and is just included in index.html, exported to the global namespace\n// This include file is simply a wrapper so that it behaves like a module, and can be mocked easily for unit tests\nimport type { dh as DhType } from '@deephaven/jsapi-types';\n\ndeclare global {\n // eslint-disable-next-line vars-on-top,no-var\n var dh: DhType;\n}\n\nconst { dh } = globalThis;\n\nexport default dh;\n","/* eslint class-methods-use-this: \"off\" */\nimport dh from '@deephaven/jsapi-shim';\nimport type { DateWrapper, TimeZone } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\nimport TableColumnFormatter, {\n TableColumnFormat,\n} from './TableColumnFormatter';\n\nconst log = Log.module('DateTimeColumnFormatter');\n\nexport type DateTimeColumnFormatterOptions = {\n // Time zone\n timeZone?: string;\n\n // Show time zone in DateTime values\n showTimeZone?: boolean;\n\n // Show 'T' separator in DateTime values\n showTSeparator?: boolean;\n\n // DateTime format to use if columnFormats for DateTime isn't set\n defaultDateTimeFormatString?: string;\n};\n\nexport class DateTimeColumnFormatter extends TableColumnFormatter<\n Date | DateWrapper | number\n> {\n /**\n * Validates format object\n * @param format Format object\n * @returns true for valid object\n */\n static isValid(format: Pick<TableColumnFormat, 'formatString'>): boolean {\n try {\n dh.i18n.DateTimeFormat.format(format.formatString, new Date());\n return true;\n } catch (e) {\n return false;\n }\n }\n\n static makeFormat(\n label: string,\n formatString: string,\n type = TableColumnFormatter.TYPE_CONTEXT_PRESET\n ): TableColumnFormat {\n return {\n label,\n formatString,\n type,\n };\n }\n\n /**\n * Check if the given formats match\n * @param formatA format object to check\n * @param formatB format object to check\n * @returns True if the formats match\n */\n static isSameFormat(\n formatA: TableColumnFormat | null,\n formatB: TableColumnFormat | null\n ): boolean {\n return (\n formatA === formatB ||\n (formatA !== null &&\n formatB !== null &&\n formatA.type === formatB.type &&\n formatA.formatString === formatB.formatString)\n );\n }\n\n static DEFAULT_DATETIME_FORMAT_STRING = 'yyyy-MM-dd HH:mm:ss.SSS';\n\n static DEFAULT_TIME_ZONE_ID = 'America/New_York';\n\n static makeGlobalFormatStringMap(\n showTimeZone: boolean,\n showTSeparator: boolean\n ): Map<string, string> {\n const separator = showTSeparator ? `'T'` : ' ';\n const tz = showTimeZone ? ' z' : '';\n return new Map([\n ['yyyy-MM-dd HH:mm:ss', `yyyy-MM-dd${separator}HH:mm:ss${tz}`],\n ['yyyy-MM-dd HH:mm:ss.SSS', `yyyy-MM-dd${separator}HH:mm:ss.SSS${tz}`],\n [\n 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS',\n `yyyy-MM-dd${separator}HH:mm:ss.SSSSSSSSS${tz}`,\n ],\n ]);\n }\n\n static getGlobalFormats(\n showTimeZone: boolean,\n showTSeparator: boolean\n ): string[] {\n const formatStringMap = DateTimeColumnFormatter.makeGlobalFormatStringMap(\n showTimeZone,\n showTSeparator\n );\n return [...formatStringMap.keys()];\n }\n\n static makeFormatStringMap(\n showTimeZone?: boolean,\n showTSeparator?: boolean\n ): Map<string, string> {\n const separator =\n showTSeparator !== undefined && showTSeparator ? `'T'` : ' ';\n const tz = showTimeZone !== undefined && showTimeZone ? ' z' : '';\n return new Map([\n ['yyyy-MM-dd', `yyyy-MM-dd${tz}`],\n ['MM-dd-yyyy', `MM-dd-yyyy${tz}`],\n ['HH:mm:ss', `HH:mm:ss${tz}`],\n ['HH:mm:ss.SSS', `HH:mm:ss.SSS${tz}`],\n ['HH:mm:ss.SSSSSSSSS', `HH:mm:ss.SSSSSSSSS${tz}`],\n ['yyyy-MM-dd HH:mm:ss', `yyyy-MM-dd${separator}HH:mm:ss${tz}`],\n ['yyyy-MM-dd HH:mm:ss.SSS', `yyyy-MM-dd${separator}HH:mm:ss.SSS${tz}`],\n [\n 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS',\n `yyyy-MM-dd${separator}HH:mm:ss.SSSSSSSSS${tz}`,\n ],\n ]);\n }\n\n static getFormats(\n showTimeZone?: boolean,\n showTSeparator?: boolean\n ): string[] {\n const formatStringMap = DateTimeColumnFormatter.makeFormatStringMap(\n showTimeZone,\n showTSeparator\n );\n return [...formatStringMap.keys()];\n }\n\n dhTimeZone: TimeZone;\n\n defaultDateTimeFormatString: string;\n\n showTimeZone: boolean;\n\n showTSeparator: boolean;\n\n formatStringMap: Map<string, string>;\n\n constructor({\n timeZone: timeZoneParam = '',\n showTimeZone = true,\n showTSeparator = false,\n defaultDateTimeFormatString = DateTimeColumnFormatter.DEFAULT_DATETIME_FORMAT_STRING,\n }: DateTimeColumnFormatterOptions = {}) {\n super();\n\n const timeZone =\n timeZoneParam || DateTimeColumnFormatter.DEFAULT_TIME_ZONE_ID;\n\n try {\n this.dhTimeZone = dh.i18n.TimeZone.getTimeZone(timeZone);\n } catch (e) {\n log.error('Unsupported time zone id', timeZone);\n this.dhTimeZone = dh.i18n.TimeZone.getTimeZone(\n DateTimeColumnFormatter.DEFAULT_TIME_ZONE_ID\n );\n }\n\n this.defaultDateTimeFormatString = defaultDateTimeFormatString;\n this.showTimeZone = showTimeZone;\n this.showTSeparator = showTSeparator;\n this.formatStringMap = DateTimeColumnFormatter.makeFormatStringMap(\n showTimeZone,\n showTSeparator\n );\n }\n\n getEffectiveFormatString(baseFormatString: string): string {\n return this.formatStringMap.get(baseFormatString) ?? baseFormatString;\n }\n\n format(\n value: Date | DateWrapper | number,\n format: Partial<TableColumnFormat> = {}\n ): string {\n const baseFormatString =\n format.formatString != null && format.formatString !== ''\n ? format.formatString\n : this.defaultDateTimeFormatString;\n const formatString = this.getEffectiveFormatString(baseFormatString);\n try {\n return dh.i18n.DateTimeFormat.format(\n formatString,\n value,\n this.dhTimeZone\n );\n } catch (e) {\n log.error('Invalid format arguments');\n }\n return '';\n }\n}\n\nexport default DateTimeColumnFormatter;\n","/* eslint class-methods-use-this: \"off\" */\nimport dh from '@deephaven/jsapi-shim';\nimport Log from '@deephaven/log';\nimport TableColumnFormatter, {\n TableColumnFormat,\n} from './TableColumnFormatter';\n\nconst log = Log.module('DecimalColumnFormatter');\n\nexport type DecimalColumnFormat = TableColumnFormat & {\n multiplier?: number | null;\n};\n\nexport type DecimalColumnFormatterOptions = {\n // Default format string to use. Defaults to DecimalColumnFormatter.DEFAULT_FORMAT_STRING\n defaultFormatString?: string;\n};\n\nexport class DecimalColumnFormatter extends TableColumnFormatter<number> {\n /**\n * Validates format object\n * @param format Format object\n * @returns true for valid object\n */\n static isValid(format: Pick<TableColumnFormat, 'formatString'>): boolean {\n try {\n dh.i18n.NumberFormat.format(format.formatString, 0);\n return true;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Create a DecimalColumnFormat object with the parameters specified\n * @param label Label for the format\n * @param formatString Format string for the format\n * @param multiplier Optional multiplier for the formatter\n * @param type Type of format created\n * @returns DecimalColumnFormat object\n */\n static makeFormat(\n label: string,\n formatString: string,\n type = TableColumnFormatter.TYPE_CONTEXT_PRESET,\n multiplier?: number\n ): DecimalColumnFormat {\n return {\n label,\n type,\n formatString,\n multiplier,\n };\n }\n\n /**\n * Convenient function to create a DecimalFormatObject with Preset type set\n * @param label Label for this format object\n * @param formatString Format string to use\n * @param multiplier Multiplier to use\n * @returns DecimalColumnFormat object\n */\n static makePresetFormat(\n label: string,\n formatString = '',\n multiplier?: number\n ): DecimalColumnFormat {\n return DecimalColumnFormatter.makeFormat(\n label,\n formatString,\n TableColumnFormatter.TYPE_CONTEXT_PRESET,\n multiplier\n );\n }\n\n /**\n * Convenient function to create a DecimalFormatObject with a default 'Custom Format' label and Custom type\n * @param formatString Format string to use\n * @param multiplier Multiplier to use\n * @returns DecimalColumnFormat object\n */\n static makeCustomFormat(\n formatString = '',\n multiplier?: number\n ): DecimalColumnFormat {\n return DecimalColumnFormatter.makeFormat(\n 'Custom Format',\n formatString,\n TableColumnFormatter.TYPE_CONTEXT_CUSTOM,\n multiplier\n );\n }\n\n static DEFAULT_FORMAT_STRING = '###,##0.0000';\n\n static FORMAT_PERCENT = DecimalColumnFormatter.makePresetFormat(\n 'Percent',\n '##0.00%'\n );\n\n static FORMAT_BASIS_POINTS = DecimalColumnFormatter.makePresetFormat(\n 'Basis Points',\n '###,##0 bp',\n 10000\n );\n\n static FORMAT_MILLIONS = DecimalColumnFormatter.makePresetFormat(\n 'Millions',\n '###,##0.000 mm',\n 0.000001\n );\n\n static FORMAT_SCIENTIFIC_NOTATION = DecimalColumnFormatter.makePresetFormat(\n 'Scientific Notation',\n '0.0000E0'\n );\n\n static FORMAT_ROUND = DecimalColumnFormatter.makePresetFormat(\n 'Round',\n '###,##0'\n );\n\n static FORMAT_ROUND_TWO_DECIMALS = DecimalColumnFormatter.makePresetFormat(\n '0.00',\n '###,##0.00'\n );\n\n static FORMAT_ROUND_FOUR_DECIMALS = DecimalColumnFormatter.makePresetFormat(\n '0.0000',\n '###,##0.0000'\n );\n\n /**\n * Check if the given formats match\n * @param formatA format object to check\n * @param formatB format object to check\n * @returns True if the formats match\n */\n static isSameFormat(\n formatA: DecimalColumnFormat | null,\n formatB: DecimalColumnFormat | null\n ): boolean {\n return (\n formatA === formatB ||\n (formatA != null &&\n formatB != null &&\n formatA.type === formatB.type &&\n formatA.formatString === formatB.formatString &&\n formatA.multiplier === formatB.multiplier)\n );\n }\n\n defaultFormatString: string;\n\n constructor({\n defaultFormatString = DecimalColumnFormatter.DEFAULT_FORMAT_STRING,\n }: DecimalColumnFormatterOptions = {}) {\n super();\n\n this.defaultFormatString = defaultFormatString;\n }\n\n /**\n * Format a value with the provided format object\n * @param valueParam Value to format\n * @param format Format object\n * @returns Formatted string\n */\n format(\n valueParam: number,\n format: Partial<DecimalColumnFormat> = {}\n ): string {\n const formatString =\n format.formatString != null && format.formatString !== ''\n ? format.formatString\n : this.defaultFormatString;\n const value =\n format.multiplier != null && format.multiplier !== 0\n ? valueParam * format.multiplier\n : valueParam;\n try {\n return dh.i18n.NumberFormat.format(formatString, value);\n } catch (e) {\n log.error('Invalid format arguments');\n }\n return '';\n }\n}\n\nexport default DecimalColumnFormatter;\n","/* eslint class-methods-use-this: \"off\" */\n/* eslint no-unused-vars: \"off\" */\nimport TableColumnFormatter from './TableColumnFormatter';\n\nclass DefaultColumnFormatter extends TableColumnFormatter {\n format(value: unknown): string {\n return `${value}`;\n }\n}\n\nexport default DefaultColumnFormatter;\n","/* eslint class-methods-use-this: \"off\" */\nimport dh from '@deephaven/jsapi-shim';\nimport Log from '@deephaven/log';\nimport TableColumnFormatter, {\n TableColumnFormat,\n} from './TableColumnFormatter';\n\nconst log = Log.module('IntegerColumnFormatter');\n\nexport type IntegerColumnFormat = TableColumnFormat & {\n multiplier?: number | null;\n};\n\nexport type IntegerColumnFormatterOptions = {\n // Default format string to use. Defaults to IntegerColumnFormatter.DEFAULT_FORMAT_STRING\n defaultFormatString?: string;\n};\n\n/** Column formatter for integers/whole numbers */\nexport class IntegerColumnFormatter extends TableColumnFormatter<number> {\n /**\n * Validates format object\n * @param format Format object\n * @returns true for valid object\n */\n static isValid(format: Pick<TableColumnFormat, 'formatString'>): boolean {\n try {\n dh.i18n.NumberFormat.format(format.formatString, 0);\n return true;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Create an IntegerColumnFormat object with the parameters specified\n * @param label Label for the format\n * @param formatString Format string for the format\n * @param multiplier Optional multiplier for the formatter\n * @param type Type of format created\n * @returns IntegerColumnFormat object\n */\n static makeFormat(\n label: string,\n formatString: string,\n type = TableColumnFormatter.TYPE_CONTEXT_PRESET,\n multiplier?: number\n ): IntegerColumnFormat {\n return {\n label,\n type,\n formatString,\n multiplier,\n };\n }\n\n /**\n * Convenient function to create a IntegerFormatObject with Preset type set\n * @param label Label for this format object\n * @param formatString Format string to use\n * @param multiplier Multiplier to use\n * @returns IntegerColumnFormat object\n */\n static makePresetFormat(\n label: string,\n formatString = '',\n multiplier?: number\n ): IntegerColumnFormat {\n return IntegerColumnFormatter.makeFormat(\n label,\n formatString,\n TableColumnFormatter.TYPE_CONTEXT_PRESET,\n multiplier\n );\n }\n\n /**\n * Convenient function to create a IntegerFormatObject with a default 'Custom Format' label and Custom type\n * @param formatString Format string to use\n * @param multiplier Multiplier to use\n * @returns IntegerColumnFormat object\n */\n static makeCustomFormat(\n formatString = '',\n multiplier?: number\n ): IntegerColumnFormat {\n return IntegerColumnFormatter.makeFormat(\n 'Custom Format',\n formatString,\n TableColumnFormatter.TYPE_CONTEXT_CUSTOM,\n multiplier\n );\n }\n\n /**\n * Check if the given formats match\n * @param formatA format object to check\n * @param formatB format object to check\n * @returns True if the formats match\n */\n static isSameFormat(\n formatA: IntegerColumnFormat | null,\n formatB: IntegerColumnFormat | null\n ): boolean {\n return (\n formatA === formatB ||\n (formatA != null &&\n formatB != null &&\n formatA.type === formatB.type &&\n formatA.formatString === formatB.formatString &&\n formatA.multiplier === formatB.multiplier)\n );\n }\n\n static DEFAULT_FORMAT_STRING = '###,##0';\n\n static FORMAT_MILLIONS = IntegerColumnFormatter.makePresetFormat(\n 'Millions',\n '###,##0.000 mm',\n 0.000001\n );\n\n static FORMAT_SCIENTIFIC_NOTATION = IntegerColumnFormatter.makePresetFormat(\n 'Scientific Notation',\n '0.0000E0'\n );\n\n defaultFormatString: string;\n\n constructor({\n defaultFormatString = IntegerColumnFormatter.DEFAULT_FORMAT_STRING,\n }: IntegerColumnFormatterOptions = {}) {\n super();\n\n this.defaultFormatString = defaultFormatString;\n }\n\n /**\n * Format a value with the provided format object\n * @param valueParam Value to format\n * @param format Format object\n * @returns Formatted string\n */\n format(\n valueParam: number,\n format: Partial<IntegerColumnFormat> = {}\n ): string {\n const formatString =\n format.formatString != null && format.formatString !== ''\n ? format.formatString\n : this.defaultFormatString;\n const value =\n format.multiplier != null && format.multiplier !== 0\n ? valueParam * format.multiplier\n : valueParam;\n try {\n return dh.i18n.NumberFormat.format(formatString, value);\n } catch (e) {\n log.error('Invalid format arguments');\n }\n return '';\n }\n}\n\nexport default IntegerColumnFormatter;\n","/* eslint class-methods-use-this: \"off\" */\nimport TableColumnFormatter from './TableColumnFormatter';\n\n/** Column formatter for strings */\nexport class StringColumnFormatter extends TableColumnFormatter<string> {\n format(value: string): string {\n return value;\n }\n}\n\nexport default StringColumnFormatter;\n","import type { DateWrapper, dh as DhType } from '@deephaven/jsapi-types';\n\ninterface DateParts<T> {\n year: T;\n month: T;\n date: T;\n hours: T;\n minutes: T;\n seconds: T;\n nanos: T;\n}\n\nexport class DateUtils {\n static FULL_DATE_FORMAT = 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS';\n\n static months = [\n 'january',\n 'february',\n 'march',\n 'april',\n 'may',\n 'june',\n 'july',\n 'august',\n 'september',\n 'october',\n 'november',\n 'december',\n ];\n\n /**\n *\n * @param timeZone The time zone to parse this time in. E.g. America/New_York\n * @param year The year for the date\n * @param month The month, starting at 0\n * @param day The day, starting at 1\n * @param hour The hours\n * @param minute The minutes\n * @param second The seconds\n * @param ns The nanoseconds\n */\n static makeDateWrapper(\n dh: DhType,\n timeZone: string,\n year: number,\n month = 0,\n day = 1,\n hour = 0,\n minute = 0,\n second = 0,\n ns = 0\n ): DateWrapper {\n if (!timeZone) {\n throw new Error('No timezone provided');\n }\n const yearString = `${year}`.padStart(4, '0');\n const monthString = `${month + 1}`.padStart(2, '0');\n const dayString = `${day}`.padStart(2, '0');\n const hourString = `${hour}`.padStart(2, '0');\n const minuteString = `${minute}`.padStart(2, '0');\n const secondString = `${second}`.padStart(2, '0');\n const nanoString = `${ns}`.padStart(9, '0');\n\n const dateString = `${yearString}-${monthString}-${dayString} ${hourString}:${minuteString}:${secondString}.${nanoString}`;\n return dh.i18n.DateTimeFormat.parse(\n DateUtils.FULL_DATE_FORMAT,\n dateString,\n dh.i18n.TimeZone.getTimeZone(timeZone)\n );\n }\n\n /**\n * Takes the string the user entered and returns the next nanos value\n * @param nanoString The nano string to get the next one of\n * @returns The value of the next nanos\n */\n static getNextNanos(nanoString: string): number {\n const sigNanos = parseInt(nanoString, 10);\n // Get the zeroes needed for padding before adding one so we handle overflow properly.\n const zeros = '0'.repeat(9 - nanoString.length);\n const nextNanoString = `${sigNanos + 1}${zeros}`;\n return parseInt(nextNanoString, 10);\n }\n\n /**\n * @param components The string components that were parsed from the original string\n * @param values The values that were parsed from the components\n * @param timeZone The time zone to parse the date in. E.g. America/New_York\n * @returns Returns the DateWrapper for the next date, or null if a full date was passed in\n */\n static getNextDate(\n dh: DhType,\n components: DateParts<string>,\n values: DateParts<number>,\n timeZone: string\n ): DateWrapper | null {\n let { year, month, date, hours, minutes, seconds, nanos } = values;\n\n if (components.nanos != null) {\n if (components.nanos.length === 9) {\n // They want an exact match\n return null;\n }\n nanos = DateUtils.getNextNanos(components.nanos);\n if (nanos > 999999999) {\n // There's an overflow, add it to the seconds manually\n seconds += 1;\n nanos = 0;\n }\n } else if (components.seconds != null) {\n seconds += 1;\n } else if (components.minutes != null) {\n minutes += 1;\n } else if (components.hours != null) {\n hours += 1;\n } else if (components.date != null) {\n date += 1;\n } else if (components.month != null) {\n month += 1;\n } else {\n year += 1;\n }\n\n // Use the JS date to handle overflow rather than doing our own logic\n // Because handling leap years and stuff is a pain\n // Still need to add nanos after, and the overflow from that is already added to seconds above\n const jsDate = new Date(year, month, date, hours, minutes, seconds);\n return DateUtils.makeDateWrapper(\n dh,\n timeZone,\n jsDate.getFullYear(),\n jsDate.getMonth(),\n jsDate.getDate(),\n jsDate.getHours(),\n jsDate.getMinutes(),\n jsDate.getSeconds(),\n nanos\n );\n }\n\n /**\n * Get the JS month value for the provided string.\n * Matches digits or a month name (eg. '1', '01', 'jan', 'january' should all work)\n * @param monthString The string to parse to a JS month value\n * @returns number The JS month value, which starts at 0 for january, or NaN if nothing could be parsed\n */\n static parseMonth(monthString: string): number {\n const month = parseInt(monthString, 10);\n if (!Number.isNaN(month)) {\n if (month >= 1 && month <= 12) {\n return month - 1;\n }\n return NaN;\n }\n\n const cleanMonthString = monthString.trim().toLowerCase();\n if (cleanMonthString.length >= 3) {\n for (let i = 0; i < DateUtils.months.length; i += 1) {\n if (DateUtils.months[i].startsWith(cleanMonthString)) {\n return i;\n }\n }\n }\n\n return NaN;\n }\n\n /**\n * Parse a date object out of the provided string segments.\n * Also using `parseMonth` to get month names like Aug/August rather than\n * simply doing `parseInt`.\n * @param yearString The year part of the string\n * @param monthString The month part of the string\n * @param dayString The day part of the string\n * @param hourString The hour part of the string\n * @param minuteString The minute part of the string\n * @param secondString The second part of the string\n * @param nanoString The milli part of the string\n */\n static parseDateValues(\n yearString: string,\n monthString: string,\n dayString: string,\n hourString: string,\n minuteString: string,\n secondString: string,\n nanoString: string\n ): DateParts<number> | null {\n const year = parseInt(yearString, 10);\n const month = monthString != null ? this.parseMonth(monthString) : 0;\n const date = dayString != null ? parseInt(dayString, 10) : 1;\n const hours = hourString != null ? parseInt(hourString, 10) : 0;\n const minutes = minuteString != null ? parseInt(minuteString, 10) : 0;\n const seconds = secondString != null ? parseInt(secondString, 10) : 0;\n const nanos =\n nanoString != null ? parseInt(nanoString.padEnd(9, '0'), 10) : 0;\n if (\n Number.isNaN(year) ||\n Number.isNaN(month) ||\n Number.isNaN(date) ||\n Number.isNaN(hours) ||\n Number.isNaN(minutes) ||\n Number.isNaN(seconds) ||\n Number.isNaN(nanos)\n ) {\n return null;\n }\n\n return { year, month, date, hours, minutes, seconds, nanos };\n }\n\n /**\n * Parse out a date time string into it's string components.\n * Anything that is not captured in the string will be undefined.\n *\n * @param dateTimeString The date time string to parse\n * @returns Containing the date time components\n */\n static parseDateTimeString(dateTimeString: string): DateParts<string> {\n const regex = /\\s*(\\d{4})([-./]([\\da-z]+))?([-./](\\d{1,2}))?([tT\\s](\\d{2})([:](\\d{2}))?([:](\\d{2}))?([.](\\d{1,9}))?)?(.*)/;\n const result = regex.exec(dateTimeString);\n if (result == null) {\n throw new Error(`Unexpected date string: ${dateTimeString}`);\n }\n\n const [\n ,\n year,\n ,\n month,\n ,\n date,\n ,\n hours,\n ,\n minutes,\n ,\n seconds,\n ,\n nanos,\n overflow,\n ] = result;\n if (overflow != null && overflow.length > 0) {\n throw new Error(\n `Unexpected characters after date string '${dateTimeString}': ${overflow}`\n );\n }\n\n return { year, month, date, hours, minutes, seconds, nanos };\n }\n\n /**\n * Parses the date range provided from a string of text.\n * @param text The string to parse the date from. Can be a keyword like \"today\", or in the format \"2018-08-04\"\n * @param timeZone The time zone to parse this range in. E.g. America/New_York\n * @returns A tuple with the start and end value/null for that date range, or both null\n */\n static parseDateRange(\n dh: DhType,\n text: string,\n timeZone: string\n ): [DateWrapper, DateWrapper | null] | [null, null] {\n const cleanText = text.trim().toLowerCase();\n if (cleanText.length === 0) {\n throw new Error('Cannot parse date range from empty string');\n }\n\n if (cleanText === 'null') {\n return [null, null];\n }\n\n if (cleanText === 'today') {\n const now = new Date(Date.now());\n const startDate = DateUtils.makeDateWrapper(\n dh,\n timeZone,\n now.getFullYear(),\n now.getMonth(),\n now.getDate()\n );\n const endDate = DateUtils.makeDateWrapper(\n dh,\n timeZone,\n now.getFullYear(),\n now.getMonth(),\n now.getDate() + 1\n );\n return [startDate, endDate];\n }\n\n if (cleanText === 'yesterday') {\n const now = new Date(Date.now());\n const startDate = DateUtils.makeDateWrapper(\n dh,\n timeZone,\n now.getFullYear(),\n now.getMonth(),\n now.getDate() - 1\n );\n const endDate = DateUtils.makeDateWrapper(\n dh,\n timeZone,\n now.getFullYear(),\n now.getMonth(),\n now.getDate()\n );\n return [startDate, endDate];\n }\n\n if (cleanText === 'now') {\n const now = new Date(Date.now());\n const date = dh.DateWrapper.ofJsDate(now);\n return [date, null];\n }\n\n const components = DateUtils.parseDateTimeString(cleanText);\n if (\n components.year == null &&\n components.month == null &&\n components.date == null\n ) {\n throw new Error(`Unable to extract year, month, or day ${cleanText}`);\n }\n\n const values = DateUtils.parseDateValues(\n components.year,\n components.month,\n components.date,\n components.hours,\n components.minutes,\n components.seconds,\n components.nanos\n );\n\n if (values == null) {\n throw new Error(`Unable to extract date values from ${components}`);\n }\n\n const startDate = DateUtils.makeDateWrapper(\n dh,\n timeZone,\n values.year,\n values.month,\n values.date,\n values.hours,\n values.minutes,\n values.seconds,\n values.nanos\n );\n\n const endDate = DateUtils.getNextDate(dh, components, values, timeZone);\n return [startDate, endDate];\n }\n\n /**\n * Gets the Js Date object from the provided DateWrapper.\n * In unit test, DateWrapper is just a number provided in millis, so handles that case.\n * @param dateWrapper The DateWrapper object, or time in millis\n */\n static getJsDate(dateWrapper: DateWrapper | number): Date {\n if (typeof dateWrapper === 'number') {\n return new Date(dateWrapper);\n }\n return dateWrapper.asDate();\n }\n}\n\nexport default DateUtils;\n","export class Operator {\n static readonly not = 'not';\n\n static readonly and = 'and';\n\n static readonly or = 'or';\n}\n\nexport type OperatorValue = typeof Operator[Exclude<\n keyof typeof Operator,\n 'prototype'\n>];\n\nexport function assertOperatorValue(\n operator?: string\n): asserts operator is OperatorValue {\n if (!(operator === 'not' || operator === 'and' || operator === 'or')) {\n throw new Error('operator is not a valid FilterOperatorValue');\n }\n}\n","/** Different filter conditions user can select */\nexport class Type {\n static readonly eq = 'eq';\n\n static readonly eqIgnoreCase = 'eqIgnoreCase';\n\n static readonly notEq = 'notEq';\n\n static readonly notEqIgnoreCase = 'notEqIgnoreCase';\n\n static readonly greaterThan = 'greaterThan';\n\n static readonly greaterThanOrEqualTo = 'greaterThanOrEqualTo';\n\n static readonly lessThan = 'lessThan';\n\n static readonly lessThanOrEqualTo = 'lessThanOrEqualTo';\n\n static readonly in = 'in';\n\n static readonly inIgnoreCase = 'inIgnoreCase';\n\n static readonly notIn = 'notIn';\n\n static readonly notInIgnoreCase = 'notInIgnoreCase';\n\n static readonly isTrue = 'isTrue';\n\n static readonly isFalse = 'isFalse';\n\n static readonly isNull = 'isNull';\n\n static readonly invoke = 'invoke';\n\n static readonly contains = 'contains';\n\n static readonly notContains = 'notContains';\n\n static readonly startsWith = 'startsWith';\n\n static readonly endsWith = 'endsWith';\n\n static readonly containsAny = 'containsAny';\n}\n\nexport type TypeValue = typeof Type[Exclude<keyof typeof Type, 'prototype'>];\n","import {\n Type as FilterType,\n Operator as FilterOperator,\n TypeValue as FilterTypeValue,\n OperatorValue as FilterOperatorValue,\n} from '@deephaven/filters';\nimport Log from '@deephaven/log';\nimport type {\n Column,\n CustomColumn,\n dh as DhType,\n FilterCondition,\n FilterValue,\n LongWrapper,\n RemoverFn,\n Sort,\n Table,\n TreeTable,\n} from '@deephaven/jsapi-types';\nimport {\n CancelablePromise,\n PromiseUtils,\n TextUtils,\n TimeoutError,\n} from '@deephaven/utils';\nimport DateUtils from './DateUtils';\nimport { ColumnName } from './Formatter';\n\nconst log = Log.module('TableUtils');\n\ntype Values<T> = T[keyof T];\nexport type DataType = Values<typeof TableUtils.dataType>;\nexport type SortDirection = Values<typeof TableUtils.sortDirection>;\nexport type ReverseType = Values<typeof TableUtils.REVERSE_TYPE>;\nexport type AdvancedFilterItemType = {\n selectedType: FilterTypeValue;\n value: string;\n};\n\nexport interface FilterItem {\n selectedType: FilterTypeValue;\n value: string;\n}\n\nexport type AdvancedFilterOptions = {\n filterItems: FilterItem[];\n filterOperators: FilterOperatorValue[];\n invertSelection: boolean;\n selectedValues: unknown[];\n};\n\nexport type RowDataMapValue = {\n type: string;\n text: string;\n value: unknown;\n isExpandable: boolean;\n isGrouped: boolean;\n visibleIndex: number;\n};\n\nexport type RowDataMap = Record<ColumnName, RowDataMapValue>;\n\n/** Utility class to provide some functions for working with tables */\nexport class TableUtils {\n static dataType = {\n BOOLEAN: 'boolean',\n CHAR: 'char',\n DATETIME: 'datetime',\n DECIMAL: 'decimal',\n INT: 'int',\n STRING: 'string',\n UNKNOWN: 'unknown',\n } as const;\n\n static sortDirection = {\n ascending: 'ASC',\n descending: 'DESC',\n reverse: 'REVERSE',\n none: null,\n } as const;\n\n static APPLY_TABLE_CHANGE_TIMEOUT_MS = 30000;\n\n static REVERSE_TYPE = Object.freeze({\n NONE: 'none',\n PRE_SORT: 'pre-sort',\n POST_SORT: 'post-sort',\n } as const);\n\n // Regex looking for a negative or positive integer or decimal number\n static NUMBER_REGEX = /^-?\\d+(\\.\\d+)?$/;\n\n /**\n * Executes a callback on a given table and returns a Promise that will resolve\n * the next time a particular event type fires on the table.\n * @param exec Callback function to execute.\n * @param table Table that gets passed to the `exec` function and that is\n * subscribed to for a given `eventType`.\n * @param eventType The event type to listen for.\n * @param timeout If the event doesn't fire within the timeout, the returned\n * Promise will be rejected.\n * @returns a Promise to the original table that resolves on next `eventType`\n * event\n */\n static executeAndWaitForEvent = async <T extends Table | TreeTable>(\n exec: (maybeTable: T | null | undefined) => void,\n table: T | null | undefined,\n eventType: string,\n timeout = TableUtils.APPLY_TABLE_CHANGE_TIMEOUT_MS\n ): Promise<T | null> => {\n if (table == null) {\n return null;\n }\n\n const eventPromise = TableUtils.makeCancelableTableEventPromise(\n table,\n eventType,\n timeout\n );\n\n exec(table);\n\n await eventPromise;\n\n return table;\n };\n\n /**\n * Apply custom columns to a given table. Return a Promise that resolves with\n * the table once the dh.Table.EVENT_CUSTOMCOLUMNSCHANGED event has fired.\n * @param table The table to apply custom columns to.\n * @param columns The list of column expressions or definitions to apply.\n * @returns A Promise that will be resolved with the given table after the\n * columns are applied.\n */\n static async applyCustomColumns(\n table: Table | null | undefined,\n columns: (string | CustomColumn)[],\n timeout = TableUtils.APPLY_TABLE_CHANGE_TIMEOUT_MS\n ): Promise<Table | null> {\n return TableUtils.executeAndWaitForEvent(\n t => t?.applyCustomColumns(columns),\n table,\n dh.Table.EVENT_CUSTOMCOLUMNSCHANGED,\n timeout\n );\n }\n\n /**\n * Apply filters to a given table.\n * @param table Table to apply filters to\n * @param filters Filters to apply\n * @param timeout Timeout before cancelling the promise that waits for the next\n * dh.Table.EVENT_FILTERCHANGED event\n * @returns a Promise to the Table that resolves after the next\n * dh.Table.EVENT_FILTERCHANGED event\n */\n static async applyFilter<T extends Table | TreeTable>(\n table: T | null | undefined,\n filters: FilterCondition[],\n timeout = TableUtils.APPLY_TABLE_CHANGE_TIMEOUT_MS\n ): Promise<T | null> {\n return TableUtils.executeAndWaitForEvent(\n t => t?.applyFilter(filters),\n table,\n dh.Table.EVENT_FILTERCHANGED,\n timeout\n );\n }\n\n /**\n * Apply a filter to a table that won't match anything.\n * @table The table to apply the filter to\n * @columnName The name of the column to apploy the filter to\n * @param timeout Timeout before cancelling the promise that waits for the next\n * dh.Table.EVENT_FILTERCHANGED event\n * @returns a Promise to the Table that resolves after the next\n * dh.Table.EVENT_FILTERCHANGED event\n */\n static async applyNeverFilter<T extends Table | TreeTable>(\n table: T | null | undefined,\n columnName: string,\n timeout = TableUtils.APPLY_TABLE_CHANGE_TIMEOUT_MS\n ): Promise<T | null> {\n if (table == null) {\n return null;\n }\n\n const column = table.findColumn(columnName);\n const filters = [TableUtils.makeNeverFilter(column)];\n\n await TableUtils.applyFilter(table, filters, timeout);\n\n return table;\n }\n\n /**\n * Apply sorts to a given Table.\n * @param table The table to apply sorts to\n * @param sorts The sorts to apply\n * @param timeout Timeout before cancelling the promise that waits for the next\n * dh.Table.EVENT_SORTCHANGED event\n * @returns a Promise to the Table that resolves after the next\n * dh.Table.EVENT_SORTCHANGED event\n */\n static async applySort<T extends Table | TreeTable>(\n table: T | null | undefined,\n sorts: Sort[],\n timeout = TableUtils.APPLY_TABLE_CHANGE_TIMEOUT_MS\n ): Promise<T | null> {\n return TableUtils.executeAndWaitForEvent(\n t => t?.applySort(sorts),\n table,\n dh.Table.EVENT_SORTCHANGED,\n timeout\n );\n }\n\n static getSortIndex(\n sort: readonly Sort[],\n columnName: ColumnName\n ): number | null {\n for (let i = 0; i < sort.length; i += 1) {\n const s = sort[i];\n if (s.column?.name === columnName) {\n return i;\n }\n }\n\n return null;\n }\n\n /**\n * @param tableSort The sorts from the table to get the sort from\n * @param columnName The name of the column to get the sort for\n * @returns The sort for the column, or null if it's not sorted\n */\n static getSortForColumn(\n tableSort: readonly Sort[],\n columnName: ColumnName\n ): Sort | null {\n const sortIndex = TableUtils.getSortIndex(tableSort, columnName);\n if (sortIndex != null) {\n return tableSort[sortIndex];\n }\n return null;\n }\n\n static getFilterText(filter?: FilterCondition | null): string | null {\n if (filter) {\n return filter.toString();\n }\n return null;\n }\n\n /** Return the valid filter types for the column */\n static getFilterTypes(columnType: string): FilterTypeValue[] {\n if (TableUtils.isBooleanType(columnType)) {\n return [FilterType.isTrue, FilterType.isFalse, FilterType.isNull];\n }\n if (\n TableUtils.isCharType(columnType) ||\n TableUtils.isNumberType(columnType) ||\n TableUtils.isDateType(columnType)\n ) {\n return [\n FilterType.eq,\n FilterType.notEq,\n FilterType.greaterThan,\n FilterType.greaterThanOrEqualTo,\n FilterType.lessThan,\n FilterType.lessThanOrEqualTo,\n ];\n }\n if (TableUtils.isTextType(columnType)) {\n return [\n FilterType.eq,\n FilterType.eqIgnoreCase,\n FilterType.notEq,\n FilterType.notEqIgnoreCase,\n FilterType.contains,\n FilterType.notContains,\n FilterType.startsWith,\n FilterType.endsWith,\n ];\n }\n return [];\n }\n\n static getNextSort(\n columns: readonly Column[],\n sorts: readonly Sort[],\n columnIndex: number\n ): Sort | null {\n if (columnIndex < 0 || columnIndex >= columns.length) {\n return null;\n }\n\n const sort = TableUtils.getSortForColumn(sorts, columns[columnIndex].name);\n if (sort === null) {\n return columns[columnIndex].sort().asc();\n }\n if (sort.direction === TableUtils.sortDirection.ascending) {\n return sort.desc();\n }\n return null;\n }\n\n static makeColumnSort(\n columns: readonly Column[],\n columnIndex: number,\n direction: SortDirection,\n isAbs: boolean\n ): Sort | null {\n if (columnIndex < 0 || columnIndex >= columns.length) {\n return null;\n }\n\n if (direction === TableUtils.sortDirection.none) {\n return null;\n }\n\n let sort = columns[columnIndex].sort();\n\n switch (direction) {\n case TableUtils.sortDirection.ascending:\n sort = sort.asc();\n break;\n case TableUtils.sortDirection.descending:\n sort = sort.desc();\n break;\n default:\n break;\n }\n if (isAbs) {\n sort = sort.abs();\n }\n return sort;\n }\n\n /**\n * Toggles the sort for the specified column\n * @param sorts The current sorts from IrisGrid.state\n * @param columns The columns to apply the sort to\n * @param columnIndex The column index to apply the sort to\n * @param addToExisting Add this sort to the existing sort\n */\n static toggleSortForColumn(\n sorts: readonly Sort[],\n columns: readonly Column[],\n columnIndex: number,\n addToExisting = false\n ): Sort[] {\n if (columnIndex < 0 || columnIndex >= columns.length) {\n return [];\n }\n\n const newSort = TableUtils.getNextSort(columns, sorts, columnIndex);\n\n return TableUtils.setSortForColumn(\n sorts,\n columns[columnIndex].name,\n newSort,\n addToExisting\n );\n }\n\n static sortColumn(\n sorts: readonly Sort[],\n columns: readonly Column[],\n modelColumn: number,\n direction: SortDirection,\n isAbs: boolean,\n addToExisting: boolean\n ): Sort[] {\n if (modelColumn < 0 || modelColumn >= columns.length) {\n return [];\n }\n\n const newSort = TableUtils.makeColumnSort(\n columns,\n modelColumn,\n direction,\n isAbs\n );\n\n return TableUtils.setSortForColumn(\n sorts,\n columns[modelColumn].name,\n newSort,\n addToExisting\n );\n }\n\n /**\n * Sets the sort for the given column *and* removes any reverses\n * @param tableSort The current sorts from IrisGrid.state\n * @param columnName The column name to apply the sort to\n * @param sort The sort object to add\n * @param addToExisting Add this sort to the existing sort\n * @returns Returns the modified array of sorts - removing reverses\n */\n static setSortForColumn(\n tableSort: readonly Sort[],\n columnName: ColumnName,\n sort: Sort | null,\n addToExisting = false\n ): Sort[] {\n const sortIndex = TableUtils.getSortIndex(tableSort, columnName);\n let sorts: Sort[] = [];\n if (addToExisting) {\n sorts = sorts.concat(\n tableSort.filter(\n ({ direction }) => direction !== TableUtils.sortDirection.reverse\n )\n );\n if (sortIndex !== null) {\n sorts.splice(sortIndex, 1);\n }\n }\n\n if (sort !== null) {\n sorts.push(sort);\n }\n\n return sorts;\n }\n\n static getNormalizedType(columnType?: string | null): DataType {\n switch (columnType) {\n case 'boolean':\n case 'java.lang.Boolean':\n case TableUtils.dataType.BOOLEAN:\n return TableUtils.dataType.BOOLEAN;\n case 'char':\n case 'java.lang.Character':\n case TableUtils.dataType.CHAR:\n return TableUtils.dataType.CHAR;\n case 'java.lang.String':\n case TableUtils.dataType.STRING:\n return TableUtils.dataType.STRING;\n case 'io.deephaven.db.tables.utils.DBDateTime':\n case 'io.deephaven.time.DateTime':\n case 'com.illumon.iris.db.tables.utils.DBDateTime':\n case 'java.time.Instant':\n case 'java.time.ZonedDateTime':\n case TableUtils.dataType.DATETIME:\n return TableUtils.dataType.DATETIME;\n case 'double':\n case 'java.lang.Double':\n case 'float':\n case 'java.lang.Float':\n case 'java.math.BigDecimal':\n case TableUtils.dataType.DECIMAL:\n return TableUtils.dataType.DECIMAL;\n case 'int':\n case 'java.lang.Integer':\n case 'long':\n case 'java.lang.Long':\n case 'short':\n case 'java.lang.Short':\n case 'byte':\n case 'java.lang.Byte':\n case 'java.math.BigInteger':\n case TableUtils.dataType.INT:\n return TableUtils.dataType.INT;\n default:\n return TableUtils.dataType.UNKNOWN;\n }\n }\n\n static isLongType(columnType: string): boolean {\n switch (columnType) {\n case 'long':\n case 'java.lang.Long':\n return true;\n default:\n return false;\n }\n }\n\n static isDateType(columnType: string): boolean {\n switch (columnType) {\n case 'io.deephaven.db.tables.utils.DBDateTime':\n case 'io.deephaven.time.DateTime':\n case 'java.time.Instant':\n case 'java.time.ZonedDateTime':\n case 'com.illumon.iris.db.tables.utils.DBDateTime':\n return true;\n default:\n return false;\n }\n }\n\n static isNumberType(columnType: string): boolean {\n return (\n TableUtils.isIntegerType(columnType) ||\n TableUtils.isDecimalType(columnType)\n );\n }\n\n static isIntegerType(columnType: string): boolean {\n switch (columnType) {\n case 'int':\n case 'java.lang.Integer':\n case 'java.math.BigInteger':\n case 'long':\n case 'java.lang.Long':\n case 'short':\n case 'java.lang.Short':\n case 'byte':\n case 'java.lang.Byte':\n return true;\n default:\n return false;\n }\n }\n\n static isDecimalType(columnType: string): boolean {\n switch (columnType) {\n case 'double':\n case 'java.lang.Double':\n case 'java.math.BigDecimal':\n case 'float':\n case 'java.lang.Float':\n return true;\n default:\n return false;\n }\n }\n\n static isBigDecimalType(columnType: string): boolean {\n switch (columnType) {\n case 'java.math.BigDecimal':\n return true;\n default:\n return false;\n }\n }\n\n static isBigIntegerType(columnType: string): boolean {\n switch (columnType) {\n case 'java.math.BigInteger':\n return true;\n default:\n return false;\n }\n }\n\n static isBooleanType(columnType: string): boolean {\n switch (columnType) {\n case 'boolean':\n case 'java.lang.Boolean':\n return true;\n default:\n return false;\n }\n }\n\n static isCharType(columnType: string): boolean {\n switch (columnType) {\n case 'char':\n case 'java.lang.Character':\n return true;\n default:\n return false;\n }\n }\n\n static isStringType(columnType: string): boolean {\n switch (columnType) {\n case 'java.lang.String':\n return true;\n default:\n return false;\n }\n }\n\n static isTextType(columnType: string): boolean {\n return this.isStringType(columnType) || this.isCharType(columnType);\n }\n\n /**\n * Get base column type\n * @param columnType Column type\n * @returns Element type for array columns, original type for non-array columns\n */\n static getBaseType(columnType: string): string {\n return columnType.split('[]')[0];\n }\n\n /**\n * Check if the column types are compatible\n * @param type1 Column type to check\n * @param type2 Column type to check\n * @returns True, if types are compatible\n */\n static isCompatibleType(\n type1?: string | null,\n type2?: string | null\n ): boolean {\n return (\n TableUtils.getNormalizedType(type1) ===\n TableUtils.getNormalizedType(type2)\n );\n }\n\n /**\n * Adds quotes to a value if they're not already added\n * @param value Value to add quotes around\n */\n static quoteValue(value: string): string {\n if (\n value.length >= 2 &&\n ((value.charAt(0) === '\"' && value.charAt(value.length - 1) === '\"') ||\n (value.charAt(0) === \"'\" && value.charAt(value.length - 1) === \"'\"))\n ) {\n return value;\n }\n return `\"${value}\"`;\n }\n\n static isRangeOperation(operation: string): boolean {\n switch (operation) {\n case '<':\n case '<=':\n case '=<':\n case '>':\n case '>=':\n case '=>':\n return true;\n default:\n return false;\n }\n }\n\n /**\n * @param filter The column filter to apply the range operation to\n * @param operation The range operation to run\n * @param value The value to use for the operation\n * @returns The condition with the specified operation\n */\n static makeRangeFilterWithOperation(\n filter: FilterValue,\n operation: string,\n value: FilterValue\n ): FilterCondition | null {\n switch (operation) {\n case '=':\n return filter.eq(value);\n case '<':\n return filter.lessThan(value);\n case '<=':\n case '=<':\n return filter.lessThanOrEqualTo(value);\n case '>':\n return filter.greaterThan(value);\n case '>=':\n case '=>':\n return filter.greaterThanOrEqualTo(value);\n case '!=':\n case '!':\n return filter.notEq(value);\n default:\n return null;\n }\n }\n\n /**\n * Wraps a table promise in a cancelable promise that will close the table if the promise is cancelled.\n * Use in a component that loads a table, and call cancel when unmounting.\n * @param table The table promise to wrap\n */\n static makeCancelableTablePromise(\n table: Promise<Table> | Table\n ): CancelablePromise<Table> {\n return PromiseUtils.makeCancelable(table, resolved => {\n resolved.close();\n });\n }\n\n /**\n * Make a cancelable promise for a one-shot table event with a timeout.\n * @param table Table to listen for events on\n * @param eventName Event to listen for\n * @param timeout Event timeout in milliseconds, defaults to 0\n * @param matcher Optional function to determine if the promise can be resolved or stays pending\n * @returns Resolves with the event data\n */\n static makeCancelableTableEventPromise(\n table: Table | TreeTable,\n eventName: string,\n timeout = 0,\n matcher: ((event: CustomEvent) => boolean) | null = null\n ): CancelablePromise<CustomEvent> {\n let eventCleanup: RemoverFn;\n let timeoutId: ReturnType<typeof setTimeout>;\n let isPending = true;\n const wrappedPromise = new Promise((resolve, reject) => {\n timeoutId = setTimeout(() => {\n eventCleanup();\n isPending = false;\n reject(new TimeoutError(`Event \"${eventName}\" timed out.`));\n }, timeout);\n eventCleanup = table.addEventListener(eventName, event => {\n if (matcher != null && !matcher(event)) {\n log.debug2('Event triggered, but matcher returned false.');\n return;\n }\n log.debug2('Event triggered, resolving.');\n eventCleanup();\n clearTimeout(timeoutId);\n isPending = false;\n resolve(event);\n });\n }) as CancelablePromise<CustomEvent>;\n wrappedPromise.cancel = () => {\n if (isPending) {\n log.debug2('Pending promise cleanup.');\n eventCleanup();\n clearTimeout(timeoutId);\n isPending = false;\n return;\n }\n log.debug2('Ignoring non-pending promise cancel.');\n };\n return wrappedPromise;\n }\n\n static removeCommas(value: string): string {\n return value.replace(/[\\s|,]/g, '');\n }\n\n static makeBooleanValue(text: string, allowEmpty = false): boolean | null {\n if (text === '' && allowEmpty) {\n return null;\n }\n\n switch (text?.toLowerCase()) {\n case 'null':\n return null;\n case '0':\n case 'f':\n case 'fa':\n case 'fal':\n case 'fals':\n case 'false':\n case 'n':\n case 'no':\n return false;\n case '1':\n case 't':\n case 'tr':\n case 'tru':\n case 'true':\n case 'y':\n case 'ye':\n case 'yes':\n return true;\n default:\n throw new Error(`Invalid boolean '${text}'`);\n }\n }\n\n static makeNumberValue(text: string): number | null {\n if (text === 'null' || text === '') {\n return null;\n }\n\n const cleanText = text.toLowerCase().trim();\n if (cleanText === '∞' || cleanText === 'infinity' || cleanText === 'inf') {\n return Number.POSITIVE_INFINITY;\n }\n if (\n cleanText === '-∞' ||\n cleanText === '-infinity' ||\n cleanText === '-inf'\n ) {\n return Number.NEGATIVE_INFINITY;\n }\n\n const numberText = TableUtils.removeCommas(cleanText);\n if (TableUtils.NUMBER_REGEX.test(numberText)) {\n return parseFloat(numberText);\n }\n\n throw new Error(`Invalid number '${text}'`);\n }\n\n static getFilterOperatorString(operation: FilterTypeValue): string {\n switch (operation) {\n case FilterType.eq:\n return '=';\n case FilterType.notEq:\n return '!=';\n case FilterType.greaterThan:\n return '>';\n case FilterType.greaterThanOrEqualTo:\n return '>=';\n case FilterType.lessThan:\n return '<';\n case FilterType.lessThanOrEqualTo:\n return '<=';\n case FilterType.contains:\n return '~';\n case FilterType.notContains:\n return '!~';\n default:\n throw new Error(`Unexpected filter type ${operation}`);\n }\n }\n\n static isTreeTable(table: unknown): table is TreeTable {\n return (\n table != null &&\n (table as TreeTable).expand !== undefined &&\n (table as TreeTable).collapse !== undefined\n );\n }\n\n /**\n * Copies the provided array, sorts by column name case insensitive, and returns the sorted array.\n * @param columns The columns to sort\n * @param isAscending Whether to sort ascending\n */\n static sortColumns(columns: readonly Column[], isAscending = true): Column[] {\n return [...columns].sort((a, b) => {\n const aName = a.name.toUpperCase();\n const bName = b.name.toUpperCase();\n return TextUtils.sort(aName, bName, isAscending);\n });\n }\n\n dh: DhType;\n\n constructor(dh: DhType) {\n this.dh = dh;\n }\n\n /**\n * Create filter with the provided column and text. Handles multiple filters joined with && or ||\n * @param column The column to set the filter on\n * @param text The text string to create the filter from\n * @param timeZone The time zone to make this value in if it is a date type. E.g. America/New_York\n * @returns Returns the created filter, null if text could not be parsed\n */\n makeQuickFilter(\n column: Column,\n text: string,\n timeZone?: string\n ): FilterCondition | null {\n const orComponents = text.split('||');\n let orFilter = null;\n for (let i = 0; i < orComponents.length; i += 1) {\n const orComponent = orComponents[i];\n const andComponents = orComponent.split('&&');\n let andFilter = null;\n for (let j = 0; j < andComponents.length; j += 1) {\n const andComponent = andComponents[j].trim();\n if (andComponent.length > 0) {\n const filter = this.makeQuickFilterFromComponent(\n column,\n andComponent,\n timeZone\n );\n if (filter) {\n if (andFilter) {\n andFilter = andFilter.and(filter);\n } else {\n andFilter = filter;\n }\n } else {\n throw new Error(`Unable to parse quick filter from text ${text}`);\n }\n }\n }\n\n if (orFilter && andFilter) {\n orFilter = orFilter.or(andFilter);\n } else {\n orFilter = andFilter;\n }\n }\n\n return orFilter;\n }\n\n /**\n * Create filter with the provided column and text of one component (no multiple conditions)\n * @param column The column to set the filter on\n * @param text The text string to create the filter from\n * @param timeZone The time zone to make this filter in if it is a date type. E.g. America/New_York\n * @returns Returns the created filter, null if text could not be parsed\n */\n makeQuickFilterFromComponent(\n column: Column,\n text: string,\n timeZone?: string\n ): FilterCondition | null {\n const { type } = column;\n if (TableUtils.isNumberType(type)) {\n return this.makeQuickNumberFilter(column, text);\n }\n if (TableUtils.isBooleanType(type)) {\n return this.makeQuickBooleanFilter(column, text);\n }\n if (timeZone != null && TableUtils.isDateType(type)) {\n return this.makeQuickDateFilter(column, text, timeZone);\n }\n if (TableUtils.isCharType(type)) {\n return this.makeQuickCharFilter(column, text);\n }\n return this.makeQuickTextFilter(column, text);\n }\n\n makeQuickNumberFilter(column: Column, text: string): FilterCondition | null {\n const columnFilter = column.filter();\n const { dh } = this;\n let filter = null;\n\n const regex = /\\s*(>=|<=|=>|=<|>|<|!=|=|!)?(\\s*-\\s*)?(\\s*\\d*(?:,\\d{3})*(?:\\.\\d*)?\\s*)?(null|nan|infinity|inf|\\u221E)?(.*)/i;\n const result = regex.exec(text);\n\n let operation = null;\n let negativeSign = null;\n let value = null;\n let abnormalValue = null; // includes nan, null and infinity(positive & negative)\n let overflow = null;\n\n if (result !== null && result.length > 3) {\n [, operation, negativeSign, value, abnormalValue, overflow] = result;\n }\n\n if (overflow != null && overflow.trim().length > 0) {\n // Some bad characters after the number, bail out!\n return null;\n }\n\n if (operation == null) {\n operation = '=';\n }\n\n if (abnormalValue != null) {\n if (!(operation === '=' || operation === '!' || operation === '!=')) {\n // only equal and not equal operations are supported for abnormal value filter\n return null;\n }\n abnormalValue = abnormalValue.trim().toLowerCase();\n switch (abnormalValue) {\n case 'null':\n filter = columnFilter.isNull();\n break;\n case 'nan':\n filter = dh.FilterCondition.invoke('isNaN', columnFilter);\n break;\n case 'infinity':\n case 'inf':\n case '\\u221E':\n if (negativeSign != null) {\n filter = dh.FilterCondition.invoke('isInf', columnFilter).and(\n columnFilter.lessThan(dh.FilterValue.ofNumber(0))\n );\n } else {\n filter = dh.FilterCondition.invoke('isInf', columnFilter).and(\n columnFilter.greaterThan(dh.FilterValue.ofNumber(0))\n );\n }\n break;\n default:\n break;\n }\n if (filter !== null && (operation === '!' || operation === '!=')) {\n filter = filter.not();\n }\n return filter;\n }\n\n if (value == null) {\n return null;\n }\n\n value = TableUtils.removeCommas(value);\n if (TableUtils.isLongType(column.type)) {\n try {\n value = dh.FilterValue.ofNumber(\n dh.LongWrapper.ofString(`${negativeSign != null ? '-' : ''}${value}`)\n );\n } catch (error) {\n log.warn('Unable to create long filter', error);\n return null;\n }\n } else {\n value = parseFloat(value);\n if (value == null || Number.isNaN(value)) {\n return null;\n }\n\n value = dh.FilterValue.ofNumber(negativeSign != null ? 0 - value : value);\n }\n\n filter = column.filter();\n\n return TableUtils.makeRangeFilterWithOperation(filter, operation, value);\n }\n\n makeQuickTextFilter(column: Column, text: string): FilterCondition | null {\n const { dh } = this;\n const cleanText = `${text}`.trim();\n const regex = /^(!~|!=|~|=|!)?(.*)/;\n const result = regex.exec(cleanText);\n\n let operation = null;\n let value = null;\n if (result !== null && result.length > 2) {\n [, operation, value] = result;\n if (value != null) {\n value = value.trim();\n }\n }\n\n if (value == null || value.length === 0) {\n return null;\n }\n\n if (operation == null) {\n operation = '=';\n }\n\n const filter = column.filter();\n if (value.toLowerCase() === 'null') {\n // Null is a special case!\n switch (operation) {\n case '=':\n return filter.isNull();\n case '!=':\n case '!':\n return filter.isNull().not();\n default:\n // For all other operations, treat null as a string value\n }\n }\n\n let prefix = null;\n let suffix = null;\n if (value.startsWith('*')) {\n prefix = '*';\n value = value.substring(1);\n } else if (value.endsWith('*') && !value.endsWith('\\\\*')) {\n suffix = '*';\n value = value.substring(0, value.length - 1);\n }\n\n value = value.replace('\\\\', '');\n\n switch (operation) {\n case '~': {\n return filter\n .isNull()\n .not()\n .and(\n filter.invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i).*\\\\Q${value}\\\\E.*`)\n )\n );\n }\n case '!~':\n return filter\n .isNull()\n .or(\n filter\n .invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i).*\\\\Q${value}\\\\E.*`)\n )\n .not()\n );\n case '!=':\n if (prefix === '*') {\n // Does not end with\n return filter\n .isNull()\n .or(\n filter\n .invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i).*\\\\Q${value}\\\\E$`)\n )\n .not()\n );\n }\n if (suffix === '*') {\n // Does not start with\n return filter\n .isNull()\n .or(\n filter\n .invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i)^\\\\Q${value}\\\\E.*`)\n )\n .not()\n );\n }\n return filter.notEqIgnoreCase(\n dh.FilterValue.ofString(value.toLowerCase())\n );\n\n case '=':\n if (prefix === '*') {\n // Ends with\n return filter\n .isNull()\n .not()\n .and(\n filter.invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i).*\\\\Q${value}\\\\E$`)\n )\n );\n }\n if (suffix === '*') {\n // Starts with\n return filter\n .isNull()\n .not()\n .and(\n filter.invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i)^\\\\Q${value}\\\\E.*`)\n )\n );\n }\n return filter.eqIgnoreCase(\n dh.FilterValue.ofString(value.toLowerCase())\n );\n\n default:\n break;\n }\n\n return null;\n }\n\n // eslint-disable-next-line class-methods-use-this\n makeQuickBooleanFilter(\n column: Column,\n text: string | number\n ): FilterCondition | null {\n const regex = /^(!=|=|!)?(.*)/;\n const result = regex.exec(`${text}`.trim());\n if (result === null) {\n return null;\n }\n const [, operation, value] = result;\n const notEqual = operation === '!' || operation === '!=';\n const cleanValue = value.trim().toLowerCase();\n\n let filter: FilterCondition | FilterValue = column.filter();\n\n try {\n const boolValue = TableUtils.makeBooleanValue(cleanValue);\n if (boolValue != null && boolValue) {\n filter = filter.isTrue();\n } else if (boolValue === null) {\n filter = filter.isNull();\n } else {\n filter = filter.isFalse();\n }\n\n return notEqual ? filter.not() : filter;\n } catch (e) {\n return null;\n }\n }\n\n /**\n * Builds a date filter parsed from the text string which may or may not include an operator.\n * @param column The column to build the filter from, with or without a leading operator.\n * @param text The date string text to parse.\n * @param timeZone The time zone to make this filter in if it is a date type. E.g. America/New_York\n */\n makeQuickDateFilter(\n column: Column,\n text: string,\n timeZone: string\n ): FilterCondition {\n const cleanText = text.trim();\n const regex = /\\s*(>=|<=|=>|=<|>|<|!=|!|=)?(.*)/;\n const result = regex.exec(cleanText);\n if (result == null || result.length <= 2) {\n throw new Error(`Unable to parse date filter: ${text}`);\n }\n\n let operation = null;\n let dateText = null;\n\n [, operation, dateText] = result;\n\n let filterOperation: FilterTypeValue = FilterType.eq;\n switch (operation) {\n case '<':\n filterOperation = FilterType.lessThan;\n break;\n case '<=':\n case '=<':\n filterOperation = FilterType.lessThanOrEqualTo;\n break;\n case '>':\n filterOperation = FilterType.greaterThan;\n break;\n case '>=':\n case '=>':\n filterOperation = FilterType.greaterThanOrEqualTo;\n break;\n case '!=':\n case '!':\n filterOperation = FilterType.notEq;\n break;\n case '=':\n case '==':\n default:\n filterOperation = FilterType.eq;\n break;\n }\n\n return this.makeQuickDateFilterWithOperation(\n column,\n dateText,\n filterOperation,\n timeZone\n );\n }\n\n /**\n * Builds a date filter parsed from the text string with the provided filter.\n * @param column The column to build the filter from.\n * @param text The date string text to parse, without an operator.\n * @param operation The filter operation to use.\n * @param timeZone The time zone to make this filter with. E.g. America/New_York\n */\n makeQuickDateFilterWithOperation(\n column: Column,\n text: string,\n operation: FilterTypeValue,\n timeZone: string\n ): FilterCondition {\n const { dh } = this;\n const [startDate, endDate] = DateUtils.parseDateRange(dh, text, timeZone);\n\n const startValue =\n startDate != null ? dh.FilterValue.ofNumber(startDate) : null;\n const endValue = endDate != null ? dh.FilterValue.ofNumber(endDate) : null;\n\n const filter = column.filter();\n if (startValue == null) {\n return operation === FilterType.notEq\n ? filter.isNull().not()\n : filter.isNull();\n }\n\n switch (operation) {\n case FilterType.eq: {\n if (endValue != null) {\n const startFilter = filter.greaterThanOrEqualTo(startValue);\n const endFilter = filter.lessThan(endValue);\n return startFilter.and(endFilter);\n }\n return filter.eq(startValue);\n }\n case FilterType.lessThan: {\n return filter.lessThan(startValue);\n }\n case FilterType.lessThanOrEqualTo: {\n if (endValue != null) {\n return filter.lessThan(endValue);\n }\n return filter.lessThanOrEqualTo(startValue);\n }\n case FilterType.greaterThan: {\n if (endValue != null) {\n return filter.greaterThanOrEqualTo(endValue);\n }\n return filter.greaterThan(startValue);\n }\n case FilterType.greaterThanOrEqualTo:\n return filter.greaterThanOrEqualTo(startValue);\n case FilterType.notEq: {\n if (endValue != null) {\n const startFilter = filter.lessThan(startValue);\n const endFilter = filter.greaterThanOrEqualTo(endValue);\n return startFilter.or(endFilter);\n }\n return filter.notEq(startValue);\n }\n\n default:\n throw new Error(`Invalid operator: ${operation}`);\n }\n }\n\n makeQuickCharFilter(column: Column, text: string): FilterCondition | null {\n const { dh } = this;\n const cleanText = `${text}`.trim();\n const regex = /^(>=|<=|=>|=<|>|<|!=|=|!)?(null|\".\"|'.'|.)?(.*)/;\n const result = regex.exec(cleanText);\n\n let operation = null;\n let value = null;\n let overflow = null;\n if (result !== null && result.length > 3) {\n [, operation, value, overflow] = result;\n }\n if (overflow != null && overflow.trim().length > 0) {\n // Some bad characters after the number, bail out!\n return null;\n }\n\n if (value == null || value.length === 0) {\n return null;\n }\n\n if (operation == null) {\n operation = '=';\n }\n\n const filter = column.filter();\n if (value.toLowerCase() === 'null') {\n // Null is a special case!\n switch (operation) {\n case '=':\n return filter.isNull();\n case '!=':\n case '!':\n return filter.isNull().not();\n default:\n return null;\n }\n }\n\n // We need to put quotes around range operations or else the API fails\n const filterValue = dh.FilterValue.ofString(\n TableUtils.isRangeOperation(operation)\n ? TableUtils.quoteValue(value)\n : value\n );\n return TableUtils.makeRangeFilterWithOperation(\n filter,\n operation,\n filterValue\n );\n }\n\n makeAdvancedFilter(\n column: Column,\n options: AdvancedFilterOptions,\n timeZone: string\n ): FilterCondition | null {\n const {\n filterItems,\n filterOperators,\n invertSelection,\n selectedValues,\n } = options;\n let filter = null;\n for (let i = 0; i < filterItems.length; i += 1) {\n const filterItem = filterItems[i];\n const { selectedType, value } = filterItem;\n if (\n selectedType != null &&\n selectedType.length > 0 &&\n value != null &&\n value.length > 0\n ) {\n try {\n const newFilter = this.makeAdvancedValueFilter(\n column,\n selectedType,\n value,\n timeZone\n );\n if (newFilter != null) {\n if (i === 0) {\n filter = newFilter;\n } else if (filter !== null && i - 1 < filterOperators.length) {\n const filterOperator = filterOperators[i - 1];\n if (filterOperator === FilterOperator.and) {\n filter = filter.and(newFilter);\n } else if (filterOperator === FilterOperator.or) {\n filter = filter.or(newFilter);\n } else {\n log.error(\n 'Unexpected filter operator',\n filterOperator,\n newFilter\n );\n filter = null;\n break;\n }\n }\n } else {\n log.debug2('Empty filter ignored for', selectedType, value);\n }\n } catch (err) {\n log.error('Unable to create filter', err);\n filter = null;\n break;\n }\n }\n }\n\n const selectValueFilter = this.makeSelectValueFilter(\n column,\n selectedValues,\n invertSelection\n );\n if (selectValueFilter != null) {\n if (filter != null) {\n filter = filter.and(selectValueFilter);\n } else {\n filter = selectValueFilter;\n }\n }\n\n return filter;\n }\n\n makeAdvancedValueFilter(\n column: Column,\n operation: FilterTypeValue,\n value: string,\n timeZone: string\n ): FilterCondition | null {\n if (TableUtils.isDateType(column.type)) {\n return this.makeQuickDateFilterWithOperation(\n column,\n value,\n operation,\n timeZone\n );\n }\n\n if (\n TableUtils.isNumberType(column.type) ||\n TableUtils.isCharType(column.type)\n ) {\n return this.makeQuickFilter(\n column,\n `${TableUtils.getFilterOperatorString(operation)}${value}`\n );\n }\n\n const filterValue = this.makeFilterValue(column.type, value);\n const filter = column.filter();\n switch (operation) {\n case FilterType.eq:\n return filter.eq(filterValue);\n case FilterType.eqIgnoreCase:\n return filter.eqIgnoreCase(filterValue);\n case FilterType.notEq:\n return filter.notEq(filterValue);\n case FilterType.notEqIgnoreCase:\n return filter.notEqIgnoreCase(filterValue);\n case FilterType.greaterThan:\n return filter.greaterThan(filterValue);\n case FilterType.greaterThanOrEqualTo:\n return filter.greaterThanOrEqualTo(filterValue);\n case FilterType.lessThan:\n return filter.lessThan(filterValue);\n case FilterType.lessThanOrEqualTo:\n return filter.lessThanOrEqualTo(filterValue);\n case FilterType.isTrue:\n return filter.isTrue();\n case FilterType.isFalse:\n return filter.isFalse();\n case FilterType.isNull:\n return filter.isNull();\n case FilterType.contains:\n return filter\n .isNull()\n .not()\n .and(\n filter.invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i).*\\\\Q${value}\\\\E.*`)\n )\n );\n case FilterType.notContains:\n return filter\n .isNull()\n .or(\n filter\n .invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i).*\\\\Q${value}\\\\E.*`)\n )\n .not()\n );\n case FilterType.startsWith:\n return filter\n .isNull()\n .not()\n .and(\n filter.invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i)^\\\\Q${value}\\\\E.*`)\n )\n );\n case FilterType.endsWith:\n return filter\n .isNull()\n .not()\n .and(\n filter.invoke(\n 'matches',\n dh.FilterValue.ofString(`(?s)(?i).*\\\\Q${value}\\\\E$`)\n )\n );\n case FilterType.in:\n case FilterType.inIgnoreCase:\n case FilterType.notIn:\n case FilterType.notInIgnoreCase:\n case FilterType.invoke:\n default:\n throw new Error(`Unexpected filter operation: ${operation}`);\n }\n }\n\n /**\n * Create a filter condition that results in zero results for a given column\n * @param column\n */\n static makeNeverFilter(column: Column): FilterCondition {\n let value = null;\n\n if (TableUtils.isTextType(column.type)) {\n // Use 'a' so that it can work for String or Character types\n value = dh.FilterValue.ofString('a');\n } else if (TableUtils.isBooleanType(column.type)) {\n value = dh.FilterValue.ofBoolean(true);\n } else if (TableUtils.isDateType(column.type)) {\n value = dh.FilterValue.ofNumber(dh.DateWrapper.ofJsDate(new Date()));\n } else {\n value = dh.FilterValue.ofNumber(0);\n }\n\n const eqFilter = column.filter().eq(value);\n const notEqFilter = column.filter().notEq(value);\n\n return eqFilter.and(notEqFilter);\n }\n\n /**\n * @param columnType The column type to make the filter value from.\n * @param value The value to make the filter value from.\n * @returns The FilterValue item for this column/value combination\n */\n makeFilterValue(columnType: string, value: string): FilterValue {\n const { dh } = this;\n const type = TableUtils.getBaseType(columnType);\n if (TableUtils.isTextType(type)) {\n return dh.FilterValue.ofString(value);\n }\n if (TableUtils.isLongType(type)) {\n return dh.FilterValue.ofNumber(\n dh.LongWrapper.ofString(TableUtils.removeCommas(value))\n );\n }\n\n return dh.FilterValue.ofNumber(TableUtils.removeCommas(value));\n }\n\n /**\n * Takes a value and converts it to an `dh.FilterValue`\n *\n * @param columnType The column type to make the filter value from.\n * @param value The value to actually set\n * @returns The FilterValue item for this column/value combination\n */\n makeFilterRawValue(columnType: string, rawValue: unknown): FilterValue {\n const { dh } = this;\n if (TableUtils.isTextType(columnType)) {\n return dh.FilterValue.ofString(rawValue);\n }\n\n if (TableUtils.isBooleanType(columnType)) {\n return dh.FilterValue.ofBoolean(rawValue);\n }\n\n return dh.FilterValue.ofNumber(rawValue);\n }\n\n /**\n * Converts a string value to a value appropriate for the column\n * @param columnType The column type to make the value for\n * @param text The string value to make a type for\n * @param timeZone The time zone to make this value in if it is a date type. E.g. America/New_York\n */\n makeValue(\n columnType: string,\n text: string,\n timeZone: string\n ): string | number | boolean | LongWrapper | null {\n const { dh } = this;\n if (text === 'null') {\n return null;\n }\n if (TableUtils.isTextType(columnType)) {\n return text;\n }\n if (TableUtils.isLongType(columnType)) {\n return dh.LongWrapper.ofString(TableUtils.removeCommas(text));\n }\n if (TableUtils.isBooleanType(columnType)) {\n return TableUtils.makeBooleanValue(text, true);\n }\n if (TableUtils.isDateType(columnType)) {\n const [date] = DateUtils.parseDateRange(dh, text, timeZone);\n return date;\n }\n\n if (TableUtils.isNumberType(columnType)) {\n return TableUtils.makeNumberValue(text);\n }\n\n log.error('Unexpected column type', columnType);\n return null;\n }\n\n /**\n * Create a filter using the selected items\n * Has a flag for invertSelection as we start from a \"Select All\" state and a user just deselects items.\n * Since there may be millions of distinct items, it's easier to build an inverse filter.\n * @param column The column to set the filter on\n * @param selectedValues The values that are selected\n * @param invertSelection Invert the selection (eg. All items are selected, then you deselect items)\n * @returns Returns a `in` or `notIn` FilterCondition as necessary, or null if no filtering should be applied (everything selected)\n */\n makeSelectValueFilter<TInvert extends boolean>(\n column: Column,\n selectedValues: unknown[],\n invertSelection: TInvert\n ): TInvert extends true ? FilterCondition | null : FilterCondition {\n const { dh } = this;\n if (selectedValues.length === 0) {\n if (invertSelection) {\n // No filter means select everything\n return null as TInvert extends true\n ? FilterCondition | null\n : FilterCondition;\n }\n\n // KLUDGE: Return a conflicting filter to show no results.\n // Could recognize this situation at a higher or lower level and pause updates on the\n // table, but this situation should be rare and that wouldn't be much gains for some added complexity\n return TableUtils.makeNeverFilter(column);\n }\n\n const values = [];\n let isNullSelected = false;\n for (let i = 0; i < selectedValues.length; i += 1) {\n const value = selectedValues[i];\n if (value == null) {\n isNullSelected = true;\n } else if (TableUtils.isTextType(column.type)) {\n values.push(\n dh.FilterValue.ofString(\n typeof value === 'number' ? String.fromCharCode(value) : value\n )\n );\n } else if (TableUtils.isBooleanType(column.type)) {\n values.push(dh.FilterValue.ofBoolean(Boolean(value)));\n } else {\n values.push(dh.FilterValue.ofNumber(value));\n }\n }\n\n if (isNullSelected) {\n if (values.length > 0) {\n if (invertSelection) {\n return column\n .filter()\n .isNull()\n .not()\n .and(column.filter().notIn(values));\n }\n return column.filter().isNull().or(column.filter().in(values));\n }\n if (invertSelection) {\n return column.filter().isNull().not();\n }\n\n return column.filter().isNull();\n }\n\n if (invertSelection) {\n return column.filter().notIn(values);\n }\n\n return column.filter().in(values);\n }\n}\n\nexport default TableUtils;\n","import TableUtils, { DataType } from './TableUtils';\nimport {\n BooleanColumnFormatter,\n CharColumnFormatter,\n DateTimeColumnFormatter,\n DecimalColumnFormatter,\n DefaultColumnFormatter,\n IntegerColumnFormatter,\n StringColumnFormatter,\n TableColumnFormat,\n TableColumnFormatter,\n} from './formatters';\n\nexport type ColumnName = string;\n\nexport interface FormattingRule {\n columnType: string;\n columnName: ColumnName;\n format: TableColumnFormat;\n}\n\nexport class Formatter {\n /**\n * Converts FormattingRule[] to Map\n * @param columnFormattingRules Array or column formatting rules\n * @returns Map of columnName-to-format Maps indexed by normalized dataType\n */\n static makeColumnFormatMap(\n columnFormattingRules: FormattingRule[]\n ): Map<DataType, Map<ColumnName, TableColumnFormat>> {\n if (columnFormattingRules == null) {\n return new Map();\n }\n return columnFormattingRules.reduce((map, next) => {\n const dataType = TableUtils.getNormalizedType(next.columnType);\n if (dataType === null) {\n return map;\n }\n\n if (!map.has(dataType)) {\n map.set(dataType, new Map());\n }\n const formatMap = map.get(dataType);\n formatMap?.set(next.columnName, next.format);\n return map;\n }, new Map<DataType, Map<ColumnName, TableColumnFormat>>());\n }\n\n /**\n * Creates a column formatting rule\n * @param columnType Normalized data type\n * @param columnName Column name\n * @param format Format object\n */\n static makeColumnFormattingRule(\n columnType: DataType,\n columnName: ColumnName,\n format: TableColumnFormat\n ): FormattingRule {\n return {\n columnType,\n columnName,\n format,\n };\n }\n\n /**\n * @param columnFormattingRules Optional array of column formatting rules\n * @param dateTimeOptions Optional object with DateTime configuration\n * @param decimalFormatOptions Optional object with Decimal configuration\n * @param integerFormatOptions Optional object with Integer configuration\n * @param truncateNumbersWithPound Determine if numbers should be truncated w/ repeating # instead of ellipsis at the end\n */\n constructor(\n columnFormattingRules: FormattingRule[] = [],\n dateTimeOptions?: ConstructorParameters<typeof DateTimeColumnFormatter>[0],\n decimalFormatOptions?: ConstructorParameters<\n typeof DecimalColumnFormatter\n >[0],\n integerFormatOptions?: ConstructorParameters<\n typeof IntegerColumnFormatter\n >[0],\n truncateNumbersWithPound = false\n ) {\n // Formatting order:\n // - columnFormatMap[type][name]\n // - typeFormatterMap[type]\n // - defaultColumnFormatter\n\n this.defaultColumnFormatter = new DefaultColumnFormatter();\n\n // Default formatters by data type\n this.typeFormatterMap = new Map<DataType, TableColumnFormatter>([\n [TableUtils.dataType.BOOLEAN, new BooleanColumnFormatter()],\n [TableUtils.dataType.CHAR, new CharColumnFormatter()],\n [\n TableUtils.dataType.DATETIME,\n new DateTimeColumnFormatter(dateTimeOptions),\n ],\n [\n TableUtils.dataType.DECIMAL,\n new DecimalColumnFormatter(decimalFormatOptions),\n ],\n [\n TableUtils.dataType.INT,\n new IntegerColumnFormatter(integerFormatOptions),\n ],\n [TableUtils.dataType.STRING, new StringColumnFormatter()],\n ]);\n\n // Formats indexed by data type and column name\n this.columnFormatMap = Formatter.makeColumnFormatMap(columnFormattingRules);\n this.truncateNumbersWithPound = truncateNumbersWithPound;\n }\n\n defaultColumnFormatter: TableColumnFormatter;\n\n typeFormatterMap: Map<DataType, TableColumnFormatter>;\n\n columnFormatMap: Map<DataType, Map<string, TableColumnFormat>>;\n\n truncateNumbersWithPound: boolean;\n\n /**\n * Gets columnFormatMap indexed by name for a given column type, creates new Map entry if necessary\n * @param columnType column type\n * @param createIfNecessary create new entry if true\n * @returns Map of format strings indexed by column name or undefined if it doesn't exist\n */\n getColumnFormatMapForType(\n columnType: string,\n createIfNecessary = false\n ): Map<string, TableColumnFormat> | undefined {\n const dataType = TableUtils.getNormalizedType(columnType);\n if (dataType === null) {\n return undefined;\n }\n\n if (createIfNecessary && !this.columnFormatMap.has(dataType)) {\n this.columnFormatMap.set(dataType, new Map());\n }\n return this.columnFormatMap.get(dataType);\n }\n\n /**\n * Gets a column format object for a given column type and name\n * @param columnType column type\n * @param columnName column name\n * @returns format object or null for Default\n */\n getColumnFormat(\n columnType: string,\n columnName: ColumnName\n ): TableColumnFormat | null {\n const columnFormatMap = this.getColumnFormatMapForType(columnType);\n return columnFormatMap?.get(columnName) ?? null;\n }\n\n getColumnTypeFormatter(columnType: string): TableColumnFormatter {\n const dataType = TableUtils.getNormalizedType(columnType);\n let columnTypeFormatter = this.defaultColumnFormatter;\n if (dataType) {\n columnTypeFormatter =\n this.typeFormatterMap.get(dataType) ?? columnTypeFormatter;\n }\n return columnTypeFormatter;\n }\n\n /**\n * Gets formatted string for a given value, column type and name\n * @param value Value to format\n * @param columnType Column type used to determine the formatting settings\n * @param columnName Column name used to determine the formatting settings\n * @param formatOverride Format object passed to the formatter in place of the format defined in columnFormatMap\n */\n getFormattedString(\n value: unknown,\n columnType: string,\n columnName = '',\n formatOverride?: Partial<TableColumnFormat>\n ): string {\n if (value == null) {\n return '';\n }\n\n const formatter = this.getColumnTypeFormatter(columnType);\n const format =\n formatOverride || this.getColumnFormat(columnType, columnName);\n\n return formatter.format(value, format ?? undefined);\n }\n\n /**\n * Gets the timeZone name\n * @returns The time zone name E.g. America/New_York\n */\n get timeZone(): string {\n const formatter = this.typeFormatterMap.get(\n TableUtils.dataType.DATETIME\n ) as DateTimeColumnFormatter;\n return formatter?.dhTimeZone?.id;\n }\n}\n\nexport default Formatter;\n","import type { FormattingRule } from './Formatter';\nimport Formatter from './Formatter';\nimport { DateTimeColumnFormatter, TableColumnFormatter } from './formatters';\nimport { ColumnFormatSettings, DateTimeFormatSettings } from './Settings';\n\nexport function getColumnFormats(\n settings?: ColumnFormatSettings\n): FormattingRule[] | undefined {\n if (settings && settings.formatter) {\n const { formatter } = settings;\n return formatter;\n }\n return undefined;\n}\n\nexport function getDateTimeFormatterOptions(\n settings?: DateTimeFormatSettings | null\n): ConstructorParameters<typeof DateTimeColumnFormatter>[0] {\n return {\n timeZone: settings?.timeZone,\n defaultDateTimeFormatString: settings?.defaultDateTimeFormat,\n showTimeZone: settings?.showTimeZone,\n showTSeparator: settings?.showTSeparator,\n };\n}\n\n/**\n * Check if the formatter has a custom format defined for the column name and type\n * @param formatter Formatter to check\n * @param columnName Column name\n * @param columnType Column type\n * @returns True, if a custom format is defined\n */\nexport function isCustomColumnFormatDefined(\n formatter: Formatter,\n columnName: string,\n columnType: string\n): boolean {\n const columnFormat = formatter.getColumnFormat(columnType, columnName);\n return (\n columnFormat != null &&\n (columnFormat.type === TableColumnFormatter.TYPE_CONTEXT_PRESET ||\n columnFormat.type === TableColumnFormatter.TYPE_CONTEXT_CUSTOM)\n );\n}\n\nexport default {\n getColumnFormats,\n getDateTimeFormatterOptions,\n isCustomColumnFormatDefined,\n};\n","import React, { createContext, useEffect, useState } from 'react';\nimport { LoadingOverlay } from '@deephaven/components';\nimport { useApi, useClient } from '@deephaven/jsapi-bootstrap';\nimport { IdeConnection } from '@deephaven/jsapi-types';\nimport Log from '@deephaven/log';\n\nconst log = Log.module('@deephaven/jsapi-components.ConnectionBootstrap');\n\nexport const ConnectionContext = createContext<IdeConnection | null>(null);\n\nexport type ConnectionBootstrapProps = {\n /**\n * The children to render wrapped with the ConnectionContext.\n * Will not render children until the connection is created.\n */\n children: React.ReactNode;\n};\n\n/**\n * ConnectionBootstrap component. Handles initializing the connection.\n */\nexport function ConnectionBootstrap({ children }: ConnectionBootstrapProps) {\n const api = useApi();\n const client = useClient();\n const [error, setError] = useState<unknown>();\n const [connection, setConnection] = useState<IdeConnection>();\n useEffect(\n function initConnection() {\n let isCanceled = false;\n async function loadConnection() {\n try {\n const newConnection = await client.getAsIdeConnection();\n if (isCanceled) {\n return;\n }\n setConnection(newConnection);\n } catch (e) {\n if (isCanceled) {\n return;\n }\n setError(e);\n }\n }\n loadConnection();\n return () => {\n isCanceled = true;\n };\n },\n [api, client]\n );\n\n useEffect(\n function listenForShutdown() {\n if (connection == null) return;\n\n function handleShutdown(event: CustomEvent) {\n const { detail } = event;\n log.info('Shutdown', `${JSON.stringify(detail)}`);\n setError(`Server shutdown: ${detail ?? 'Unknown reason'}`);\n }\n\n const removerFn = connection.addEventListener(\n api.IdeConnection.EVENT_SHUTDOWN,\n handleShutdown\n );\n return removerFn;\n },\n [api, connection]\n );\n\n if (connection == null || error != null) {\n return (\n <LoadingOverlay\n data-testid=\"connection-bootstrap-loading\"\n isLoading={connection == null}\n errorMessage={error != null ? `${error}` : undefined}\n />\n );\n }\n\n return (\n <ConnectionContext.Provider value={connection}>\n {children}\n </ConnectionContext.Provider>\n );\n}\n\nexport default ConnectionBootstrap;\n","import { useContextOrThrow } from '@deephaven/react-hooks';\nimport { ConnectionContext } from './ConnectionBootstrap';\n\nexport function useConnection() {\n return useContextOrThrow(\n ConnectionContext,\n 'No IdeConnection available in useConnection. Was code wrapped in ConnectionBootstrap or ConnectionContext.Provider?'\n );\n}\n\nexport default useConnection;\n"],"names":["useContextOrThrow","context","message","value","useContext","CanceledPromiseError","__publicField","CanceledPromiseError$1","TimeoutError","TimeoutError$1","PromiseUtils","promise","cleanup","hasCanceled","resolved","rejectFn","wrappedPromise","resolve","reject","val","error","timeoutMs","callback","err","assertNotNull","TextUtils","items","conjunction","itemText","lastItem","text","isNullAllowed","a","b","isAscending","TextUtils$1","isPromise","_ContextActionUtils","e","actions","sortedActions","platform","event","modifierKey","actionsParam","includePromises","menuItems","i","action","newMenuItems","startIndex","delta","firstIndex","menuIndex","item","ContextActionUtils","ContextActionUtils$1","ContextMenuItem","React","props","ref","handleMenuItemClick","menuItem","onMenuItemClick","handleMenuItemMouseMove","onMenuItemMouseMove","handleMenuItemContextMenu","onMenuItemContextMenu","renderCustomMenuElement","element","iconElement","displayShortcut","closeMenu","isKeyboardSelected","isMouseSelected","dataTestId","forwardedProps","children","_a","icon","menuItemIcon","style","jsx","FontAwesomeIcon","subMenuIndicator","isSubMenuActive","vsChevronRight","content","menuItemDisabled","iconHasOutline","classNames","jsxs","ContextMenuItem$1","log","Log","_ContextMenu","PureComponent","onMenuOpened","prevProps","prevState","activeSubMenu","_b","options","keyboardIndex","index","mouseIndex","nonPromiseItems","cancellablePromise","state","resolvedMenuItems","pendingItems","parentRect","updatePosition","subMenuParentWidth","subMenuParentHeight","oldTop","oldLeft","top","left","width","height","hasOverflow","isContextMenuChild","key","oldFocus","newFocus","openSubMenu","newSubMenu","closeAll","onMenuClosed","closeAllMenus","focusIndex","menuItemElements","subMenuTop","subMenuLeft","menuItemElement","pendingElement","LoadingSpinner","menuStyle","showSubmenu","Fragment","verifiedTop","verifiedLeft","ContextMenu","ContextMenu$1","ContextMenuRoot","Component","contextActions","mouseEvent","menu","ContextMenuRoot$1","useApi","ApiContext","useCreateClient","serverUrl","api","client","useMemo","useEffect","ClientContext","createContext","ClientBootstrap","useClient","TableColumnFormatter","format","formatA","formatB","label","formatString","type","TableColumnFormatter$1","BooleanColumnFormatter","BooleanColumnFormatter$1","CharColumnFormatter","CharColumnFormatter$1","dh","shim","_DateTimeColumnFormatter","timeZoneParam","showTimeZone","showTSeparator","defaultDateTimeFormatString","timeZone","separator","tz","baseFormatString","DateTimeColumnFormatter","_DecimalColumnFormatter","defaultFormatString","multiplier","valueParam","DecimalColumnFormatter","DefaultColumnFormatter","DefaultColumnFormatter$1","_IntegerColumnFormatter","IntegerColumnFormatter","StringColumnFormatter","_DateUtils","year","month","day","hour","minute","second","ns","yearString","monthString","dayString","hourString","minuteString","secondString","nanoString","dateString","sigNanos","zeros","nextNanoString","components","values","date","hours","minutes","seconds","nanos","jsDate","cleanMonthString","dateTimeString","result","overflow","cleanText","now","startDate","endDate","dateWrapper","DateUtils","Operator","Type","_TableUtils","table","columns","timeout","t","filters","columnName","column","sorts","sort","tableSort","sortIndex","filter","columnType","FilterType","columnIndex","direction","isAbs","addToExisting","newSort","modelColumn","type1","type2","operation","eventName","matcher","eventCleanup","timeoutId","isPending","allowEmpty","numberText","aName","bName","orComponents","orFilter","andComponents","andFilter","j","andComponent","columnFilter","negativeSign","abnormalValue","prefix","suffix","notEqual","cleanValue","boolValue","dateText","filterOperation","startValue","endValue","startFilter","endFilter","filterValue","filterItems","filterOperators","invertSelection","selectedValues","filterItem","selectedType","newFilter","filterOperator","FilterOperator","selectValueFilter","eqFilter","notEqFilter","rawValue","isNullSelected","TableUtils","exec","eventType","eventPromise","Formatter","columnFormattingRules","dateTimeOptions","decimalFormatOptions","integerFormatOptions","truncateNumbersWithPound","map","next","dataType","formatMap","createIfNecessary","columnFormatMap","columnTypeFormatter","formatOverride","formatter","getColumnFormats","settings","getDateTimeFormatterOptions","isCustomColumnFormatDefined","columnFormat","FormatterUtils","ConnectionContext","ConnectionBootstrap","setError","useState","connection","setConnection","isCanceled","loadConnection","newConnection","handleShutdown","detail","LoadingOverlay","useConnection"],"mappings":"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"}
|