/** * Custom positioning reference element. * @see https://floating-ui.com/docs/virtual-elements */ const t=Math.min,e=Math.max,n=Math.round,o=Math.floor,i=t=>({x:t,y:t}),r={left:"right",right:"left",bottom:"top",top:"bottom"},l={start:"end",end:"start"};function c(n,o,i){return e(n,t(o,i))}function s(t,e){return"function"==typeof t?t(e):t}function a(t){return t.split("-")[0]}function f(t){return t.split("-")[1]}function u(t){return"x"===t?"y":"x"}function d(t){return"y"===t?"height":"width"}function h(t){return["top","bottom"].includes(a(t))?"y":"x"}function m(t){return u(h(t))}function p(t){return t.replace(/start|end/g,(t=>l[t]))}function g(t){return t.replace(/left|right|bottom|top/g,(t=>r[t]))}function y(t){return"number"!=typeof t?function(t){return{top:0,right:0,bottom:0,left:0,...t}}(t):{top:t,right:t,bottom:t,left:t}}function w(t){const{x:e,y:n,width:o,height:i}=t;return{width:o,height:i,top:n,left:e,right:e+o,bottom:n+i,x:e,y:n}}function x(t,e,n){let{reference:o,floating:i}=t;const r=h(e),l=m(e),c=d(l),s=a(e),u="y"===r,p=o.x+o.width/2-i.width/2,g=o.y+o.height/2-i.height/2,y=o[c]/2-i[c]/2;let w;switch(s){case"top":w={x:p,y:o.y-i.height};break;case"bottom":w={x:p,y:o.y+o.height};break;case"right":w={x:o.x+o.width,y:g};break;case"left":w={x:o.x-i.width,y:g};break;default:w={x:o.x,y:o.y}}switch(f(e)){case"start":w[l]-=y*(n&&u?-1:1);break;case"end":w[l]+=y*(n&&u?-1:1)}return w} /** * Computes the `x` and `y` coordinates that will place the floating element * next to a given reference element. * * This export does not have any `platform` interface logic. You will need to * write one for the platform you are using Floating UI with. */ /** * Resolves with an object of overflow side offsets that determine how much the * element is overflowing a given clipping boundary on each side. * - positive = overflowing the boundary by that number of pixels * - negative = how many pixels left before it will overflow * - 0 = lies flush with the boundary * @see https://floating-ui.com/docs/detectOverflow */ async function v(t,e){var n;void 0===e&&(e={});const{x:o,y:i,platform:r,rects:l,elements:c,strategy:a}=t,{boundary:f="clippingAncestors",rootBoundary:u="viewport",elementContext:d="floating",altBoundary:h=!1,padding:m=0}=s(e,t),p=y(m),g=c[h?"floating"===d?"reference":"floating":d],x=w(await r.getClippingRect({element:null==(n=await(null==r.isElement?void 0:r.isElement(g)))||n?g:g.contextElement||await(null==r.getDocumentElement?void 0:r.getDocumentElement(c.floating)),boundary:f,rootBoundary:u,strategy:a})),v="floating"===d?{x:o,y:i,width:l.floating.width,height:l.floating.height}:l.reference,b=await(null==r.getOffsetParent?void 0:r.getOffsetParent(c.floating)),R=await(null==r.isElement?void 0:r.isElement(b))&&await(null==r.getScale?void 0:r.getScale(b))||{x:1,y:1},T=w(r.convertOffsetParentRelativeRectToViewportRelativeRect?await r.convertOffsetParentRelativeRectToViewportRelativeRect({elements:c,rect:v,offsetParent:b,strategy:a}):v);return{top:(x.top-T.top+p.top)/R.y,bottom:(T.bottom-x.bottom+p.bottom)/R.y,left:(x.left-T.left+p.left)/R.x,right:(T.right-x.right+p.right)/R.x}} /** * Provides data to position an inner element of the floating element so that it * appears centered to the reference element. * @see https://floating-ui.com/docs/arrow */function b(){return"undefined"!=typeof window}function R(t){return E(t)?(t.nodeName||"").toLowerCase():"#document"; // Mocked nodes in testing environments may not be instances of Node. By // returning `#document` an infinite loop won't occur. // https://github.com/floating-ui/floating-ui/issues/2317 }function T(t){var e;return(null==t||null==(e=t.ownerDocument)?void 0:e.defaultView)||window}function L(t){var e;return null==(e=(E(t)?t.ownerDocument:t.document)||window.document)?void 0:e.documentElement}function E(t){return!!b()&&(t instanceof Node||t instanceof T(t).Node)}function A(t){return!!b()&&(t instanceof Element||t instanceof T(t).Element)}function D(t){return!!b()&&(t instanceof HTMLElement||t instanceof T(t).HTMLElement)}function O(t){return!(!b()||"undefined"==typeof ShadowRoot)&&(t instanceof ShadowRoot||t instanceof T(t).ShadowRoot)}function S(t){const{overflow:e,overflowX:n,overflowY:o,display:i}=H(t);return/auto|scroll|overlay|hidden|clip/.test(e+o+n)&&!["inline","contents"].includes(i)}function C(t){return["table","td","th"].includes(R(t))}function P(t){return[":popover-open",":modal"].some((e=>{try{return t.matches(e)}catch(n){return!1}}))}function F(t){const e=k(),n=A(t)?H(t):t; // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block // https://drafts.csswg.org/css-transforms-2/#individual-transforms return["transform","translate","scale","rotate","perspective"].some((t=>!!n[t]&&"none"!==n[t]))||!!n.containerType&&"normal"!==n.containerType||!e&&!!n.backdropFilter&&"none"!==n.backdropFilter||!e&&!!n.filter&&"none"!==n.filter||["transform","translate","scale","rotate","perspective","filter"].some((t=>(n.willChange||"").includes(t)))||["paint","layout","strict","content"].some((t=>(n.contain||"").includes(t)))}function k(){return!("undefined"==typeof CSS||!CSS.supports)&&CSS.supports("-webkit-backdrop-filter","none")}function B(t){return["html","body","#document"].includes(R(t))}function H(t){return T(t).getComputedStyle(t)}function W(t){return A(t)?{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop}:{scrollLeft:t.scrollX,scrollTop:t.scrollY}}function V(t){if("html"===R(t))return t;const e= // Step into the shadow DOM of the parent of a slotted node. t.assignedSlot|| // DOM Element detected. t.parentNode|| // ShadowRoot detected. O(t)&&t.host|| // Fallback. L(t);return O(e)?e.host:e}function M(t){const e=V(t);return B(e)?t.ownerDocument?t.ownerDocument.body:t.body:D(e)&&S(e)?e:M(e)}function z(t,e,n){var o;void 0===e&&(e=[]),void 0===n&&(n=!0);const i=M(t),r=i===(null==(o=t.ownerDocument)?void 0:o.body),l=T(i);if(r){const t=N(l);return e.concat(l,l.visualViewport||[],S(i)?i:[],t&&n?z(t):[])}return e.concat(i,z(i,[],n))}function N(t){return t.parent&&Object.getPrototypeOf(t.parent)?t.frameElement:null}function I(t){const e=H(t); // In testing environments, the `width` and `height` properties are empty // strings for SVG elements, returning NaN. Fallback to `0` in this case. let o=parseFloat(e.width)||0,i=parseFloat(e.height)||0;const r=D(t),l=r?t.offsetWidth:o,c=r?t.offsetHeight:i,s=n(o)!==l||n(i)!==c;return s&&(o=l,i=c),{width:o,height:i,$:s}}function j(t){return A(t)?t:t.contextElement}function q(t){const e=j(t);if(!D(e))return i(1);const o=e.getBoundingClientRect(),{width:r,height:l,$:c}=I(e);let s=(c?n(o.width):o.width)/r,a=(c?n(o.height):o.height)/l; // 0, NaN, or Infinity should always fallback to 1. return s&&Number.isFinite(s)||(s=1),a&&Number.isFinite(a)||(a=1),{x:s,y:a}}const X=i(0);function Y(t){const e=T(t);return k()&&e.visualViewport?{x:e.visualViewport.offsetLeft,y:e.visualViewport.offsetTop}:X}function $(t,e,n,o){void 0===e&&(e=!1),void 0===n&&(n=!1);const r=t.getBoundingClientRect(),l=j(t);let c=i(1);e&&(o?A(o)&&(c=q(o)):c=q(t));const s=function(t,e,n){return void 0===e&&(e=!1),!(!n||e&&n!==T(t))&&e}(l,n,o)?Y(l):i(0);let a=(r.left+s.x)/c.x,f=(r.top+s.y)/c.y,u=r.width/c.x,d=r.height/c.y;if(l){const t=T(l),e=o&&A(o)?T(o):o;let n=t,i=N(n);for(;i&&o&&e!==n;){const t=q(i),e=i.getBoundingClientRect(),o=H(i),r=e.left+(i.clientLeft+parseFloat(o.paddingLeft))*t.x,l=e.top+(i.clientTop+parseFloat(o.paddingTop))*t.y;a*=t.x,f*=t.y,u*=t.x,d*=t.y,a+=r,f+=l,n=T(i),i=N(n)}}return w({width:u,height:d,x:a,y:f})} // If has a CSS width greater than the viewport, then this will be // incorrect for RTL. function _(t,e){const n=W(t).scrollLeft;return e?e.left+n:$(L(t)).left+n}function G(t,e,n){void 0===n&&(n=!1);const o=t.getBoundingClientRect();return{x:o.left+e.scrollLeft-(n?0: // RTL
scrollbar. _(t,o)),y:o.top+e.scrollTop}}function J(t,n,o){let r;if("viewport"===n)r=function(t,e){const n=T(t),o=L(t),i=n.visualViewport;let r=o.clientWidth,l=o.clientHeight,c=0,s=0;if(i){r=i.width,l=i.height;const t=k();(!t||t&&"fixed"===e)&&(c=i.offsetLeft,s=i.offsetTop)}return{width:r,height:l,x:c,y:s}} // Returns the inner client rect, subtracting scrollbars if present. (t,o);else if("document"===n)r= // Gets the entire size of the scrollable document area, even extending outside // of the `` and `` rect bounds if horizontally scrollable. function(t){const n=L(t),o=W(t),i=t.ownerDocument.body,r=e(n.scrollWidth,n.clientWidth,i.scrollWidth,i.clientWidth),l=e(n.scrollHeight,n.clientHeight,i.scrollHeight,i.clientHeight);let c=-o.scrollLeft+_(t);const s=-o.scrollTop;return"rtl"===H(i).direction&&(c+=e(n.clientWidth,i.clientWidth)-r),{width:r,height:l,x:c,y:s}}(L(t));else if(A(n))r=function(t,e){const n=$(t,!0,"fixed"===e),o=n.top+t.clientTop,r=n.left+t.clientLeft,l=D(t)?q(t):i(1);return{width:t.clientWidth*l.x,height:t.clientHeight*l.y,x:r*l.x,y:o*l.y}}(n,o);else{const e=Y(t);r={x:n.x-e.x,y:n.y-e.y,width:n.width,height:n.height}}return w(r)}function K(t,e){const n=V(t);return!(n===e||!A(n)||B(n))&&("fixed"===H(n).position||K(n,e))} // A "clipping ancestor" is an `overflow` element with the characteristic of // clipping (or hiding) child elements. This returns all clipping ancestors // of the given element up the tree. function Q(t,e,n){const o=D(e),r=L(e),l="fixed"===n,c=$(t,!0,l,e);let s={scrollLeft:0,scrollTop:0};const a=i(0);if(o||!o&&!l)if(("body"!==R(e)||S(r))&&(s=W(e)),o){const t=$(e,!0,l,e);a.x=t.x+e.clientLeft,a.y=t.y+e.clientTop}else r&&( // If the scrollbar appears on the left (e.g. RTL systems). Use // Firefox with layout.scrollbar.side = 3 in about:config to test this. a.x=_(r));const f=!r||o||l?i(0):G(r,s);return{x:c.left+s.scrollLeft-a.x-f.x,y:c.top+s.scrollTop-a.y-f.y,width:c.width,height:c.height}}function U(t){return"static"===H(t).position}function Z(t,e){if(!D(t)||"fixed"===H(t).position)return null;if(e)return e(t);let n=t.offsetParent; // Firefox returns the element as the offsetParent if it's non-static, // while Chrome and Safari return the element. The element must // be used to perform the correct calculations even if the element is // non-static. return L(t)===n&&(n=n.ownerDocument.body),n} // Gets the closest ancestor positioned element. Handles some edge cases, // such as table ancestors and cross browser bugs. function tt(t,e){const n=T(t);if(P(t))return n;if(!D(t)){let e=V(t);for(;e&&!B(e);){if(A(e)&&!U(e))return e;e=V(e)}return n}let o=Z(t,e);for(;o&&C(o)&&U(o);)o=Z(o,e);return o&&B(o)&&U(o)&&!F(o)?n:o||function(t){let e=V(t);for(;D(e)&&!B(e);){if(F(e))return e;if(P(e))return null;e=V(e)}return null}(t)||n}const et={convertOffsetParentRelativeRectToViewportRelativeRect:function(t){let{elements:e,rect:n,offsetParent:o,strategy:r}=t;const l="fixed"===r,c=L(o),s=!!e&&P(e.floating);if(o===c||s&&l)return n;let a={scrollLeft:0,scrollTop:0},f=i(1);const u=i(0),d=D(o);if((d||!d&&!l)&&(("body"!==R(o)||S(c))&&(a=W(o)),D(o))){const t=$(o);f=q(o),u.x=t.x+o.clientLeft,u.y=t.y+o.clientTop}const h=!c||d||l?i(0):G(c,a,!0);return{width:n.width*f.x,height:n.height*f.y,x:n.x*f.x-a.scrollLeft*f.x+u.x+h.x,y:n.y*f.y-a.scrollTop*f.y+u.y+h.y}},getDocumentElement:L,getClippingRect: // Gets the maximum area that the element is visible in due to any number of // clipping ancestors. function(n){let{element:o,boundary:i,rootBoundary:r,strategy:l}=n;const c=[..."clippingAncestors"===i?P(o)?[]:function(t,e){const n=e.get(t);if(n)return n;let o=z(t,[],!1).filter((t=>A(t)&&"body"!==R(t))),i=null;const r="fixed"===H(t).position;let l=r?V(t):t; // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block for(;A(l)&&!B(l);){const e=H(l),n=F(l);n||"fixed"!==e.position||(i=null),(r?!n&&!i:!n&&"static"===e.position&&i&&["absolute","fixed"].includes(i.position)||S(l)&&!n&&K(t,l))? // Drop non-containing blocks. o=o.filter((t=>t!==l)): // Record last containing block for next iteration. i=e,l=V(l)}return e.set(t,o),o}(o,this._c):[].concat(i),r],s=c[0],a=c.reduce(((n,i)=>{const r=J(o,i,l);return n.top=e(r.top,n.top),n.right=t(r.right,n.right),n.bottom=t(r.bottom,n.bottom),n.left=e(r.left,n.left),n}),J(o,s,l));return{width:a.right-a.left,height:a.bottom-a.top,x:a.left,y:a.top}},getOffsetParent:tt,getElementRects:async function(t){const e=this.getOffsetParent||tt,n=this.getDimensions,o=await n(t.floating);return{reference:Q(t.reference,await e(t.floating),t.strategy),floating:{x:0,y:0,width:o.width,height:o.height}}},getClientRects:function(t){return Array.from(t.getClientRects())},getDimensions:function(t){const{width:e,height:n}=I(t);return{width:e,height:n}},getScale:q,isElement:A,isRTL:function(t){return"rtl"===H(t).direction}};function nt(t,e){return t.x===e.x&&t.y===e.y&&t.width===e.width&&t.height===e.height} // https://samthor.au/2021/observing-dom/ /** * Automatically updates the position of the floating element when necessary. * Should only be called when the floating element is mounted on the DOM or * visible on the screen. * @returns cleanup function that should be invoked when the floating element is * removed from the DOM or hidden from the screen. * @see https://floating-ui.com/docs/autoUpdate */ function ot(n,i,r,l){void 0===l&&(l={});const{ancestorScroll:c=!0,ancestorResize:s=!0,elementResize:a="function"==typeof ResizeObserver,layoutShift:f="function"==typeof IntersectionObserver,animationFrame:u=!1}=l,d=j(n),h=c||s?[...d?z(d):[],...z(i)]:[];h.forEach((t=>{c&&t.addEventListener("scroll",r,{passive:!0}),s&&t.addEventListener("resize",r)}));const m=d&&f?function(n,i){let r,l=null;const c=L(n);function s(){var t;clearTimeout(r),null==(t=l)||t.disconnect(),l=null}return function a(f,u){void 0===f&&(f=!1),void 0===u&&(u=1),s();const d=n.getBoundingClientRect(),{left:h,top:m,width:p,height:g}=d;if(f||i(),!p||!g)return;const y={rootMargin:-o(m)+"px "+-o(c.clientWidth-(h+p))+"px "+-o(c.clientHeight-(m+g))+"px "+-o(h)+"px",threshold:e(0,t(1,u))||1};let w=!0;function x(t){const e=t[0].intersectionRatio;if(e!==u){if(!w)return a();e?a(!1,e): // If the reference is clipped, the ratio is 0. Throttle the refresh // to prevent an infinite loop of updates. r=setTimeout((()=>{a(!1,1e-7)}),1e3)}1!==e||nt(d,n.getBoundingClientRect())|| // It's possible that even though the ratio is reported as 1, the // element is not actually fully within the IntersectionObserver's root // area anymore. This can happen under performance constraints. This may // be a bug in the browser's IntersectionObserver implementation. To // work around this, we compare the element's bounding rect now with // what it was at the time we created the IntersectionObserver. If they // are not equal then the element moved, so we refresh. a(),w=!1} // Older browsers don't support a `document` as the root and will throw an // error. try{l=new IntersectionObserver(x,{...y, // Handle