UNPKG

@grafana/ui

Version:
1 lines • 24.8 kB
{"version":3,"file":"useSplitter.mjs","sources":["../../../../src/components/Splitter/useSplitter.ts"],"sourcesContent":["import { css } from '@emotion/css';\nimport { clamp } from 'lodash';\nimport { useCallback, useId, useRef } from 'react';\nimport * as React from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nimport { useStyles2 } from '../../themes/ThemeContext';\nimport { ComponentSize } from '../../types/size';\nimport { DragHandlePosition, getDragStyles } from '../DragHandle/DragHandle';\n\nexport interface UseSplitterOptions {\n /**\n * The initial size of the primary pane between 0-1, defaults to 0.5\n * If `usePixels` is true, this is the initial size in pixels of the second pane.\n */\n initialSize?: number;\n direction: 'row' | 'column';\n dragPosition?: DragHandlePosition;\n usePixels?: boolean;\n /**\n * Called when ever the size of the primary pane changes\n * @param flexSize (float from 0-1)\n */\n onSizeChanged?: (flexSize: number, firstPanePixels: number, secondPanePixels: number) => void;\n onResizing?: (flexSize: number, firstPanePixels: number, secondPanePixels: number) => void;\n\n // Size of the region left of the handle indicator that is responsive to dragging. At the same time acts as a margin\n // pushing the left pane content left.\n handleSize?: ComponentSize;\n}\n\nconst PIXELS_PER_MS = 0.3 as const;\nconst VERTICAL_KEYS = new Set(['ArrowUp', 'ArrowDown']);\nconst HORIZONTAL_KEYS = new Set(['ArrowLeft', 'ArrowRight']);\n\nconst propsForDirection = {\n row: {\n dim: 'width',\n axis: 'clientX',\n min: 'minWidth',\n max: 'maxWidth',\n },\n column: {\n dim: 'height',\n axis: 'clientY',\n min: 'minHeight',\n max: 'maxHeight',\n },\n} as const;\n\nexport function useSplitter(options: UseSplitterOptions) {\n const {\n direction,\n initialSize = options.usePixels ? 300 : 0.5,\n dragPosition = 'middle',\n onResizing,\n onSizeChanged,\n usePixels,\n } = options;\n\n const handleSize = getPixelSize(options.handleSize);\n const splitterRef = useRef<HTMLDivElement | null>(null);\n const firstPaneRef = useRef<HTMLDivElement | null>(null);\n const secondPaneRef = useRef<HTMLDivElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const containerSize = useRef<number | null>(null);\n const primarySizeRef = useRef<number | null>(null);\n const referencePaneSize = useRef<MeasureResult | undefined>(undefined);\n const savedPos = useRef<string | undefined>(undefined);\n\n const measurementProp = propsForDirection[direction].dim;\n const clientAxis = propsForDirection[direction].axis;\n const minDimProp = propsForDirection[direction].min;\n const maxDimProp = propsForDirection[direction].max;\n const dragStart = useRef<number | null>(null);\n\n const onPointerDown = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (!firstPaneRef.current || !secondPaneRef.current) {\n return;\n }\n\n // measure left-side width\n primarySizeRef.current = firstPaneRef.current!.getBoundingClientRect()[measurementProp];\n containerSize.current = containerRef.current!.getBoundingClientRect()[measurementProp];\n\n dragStart.current = e[clientAxis];\n splitterRef.current!.setPointerCapture(e.pointerId);\n\n if (usePixels) {\n referencePaneSize.current = measureElement(secondPaneRef.current, usePixels);\n } else {\n referencePaneSize.current = measureElement(firstPaneRef.current);\n }\n\n savedPos.current = undefined;\n },\n [measurementProp, clientAxis, usePixels]\n );\n\n const onUpdateSize = useCallback(\n (diff: number) => {\n if (!containerSize.current || !primarySizeRef.current || !secondPaneRef.current) {\n return;\n }\n\n const firstPanePixels = primarySizeRef.current;\n const secondPanePixels = containerSize.current - firstPanePixels - handleSize;\n const dims = referencePaneSize.current!;\n\n if (usePixels) {\n const newSize = clamp(secondPanePixels - diff, dims[minDimProp], dims[maxDimProp]);\n secondPaneRef.current!.style.flexBasis = `${newSize}px`;\n splitterRef.current!.ariaValueNow = `${newSize}`;\n onResizing?.(newSize, firstPanePixels + diff, newSize);\n } else {\n const newSize = clamp(primarySizeRef.current + diff, dims[minDimProp], dims[maxDimProp]);\n const newFlex = newSize / (containerSize.current! - handleSize);\n firstPaneRef.current!.style.flexGrow = `${newFlex}`;\n secondPaneRef.current!.style.flexGrow = `${1 - newFlex}`;\n splitterRef.current!.ariaValueNow = ariaValue(newSize, dims[minDimProp], dims[maxDimProp]);\n onResizing?.(newFlex, newSize, secondPanePixels - diff);\n }\n },\n [onResizing, handleSize, usePixels, minDimProp, maxDimProp]\n );\n\n const onPointerMove = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (dragStart.current !== null) {\n onUpdateSize(e[clientAxis] - dragStart.current);\n }\n },\n [onUpdateSize, clientAxis]\n );\n\n const onPointerUp = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n e.preventDefault();\n e.stopPropagation();\n\n dragStart.current = null;\n\n splitterRef.current!.releasePointerCapture(e.pointerId);\n\n const firstPaneSize = firstPaneRef.current!.getBoundingClientRect()[measurementProp];\n const secondPanePixels = containerSize.current! - firstPaneSize - handleSize;\n\n onSizeChanged?.(parseFloat(firstPaneRef.current!.style.flexGrow), firstPaneSize, secondPanePixels);\n },\n [onSizeChanged, handleSize, measurementProp]\n );\n\n const pressedKeys = useRef(new Set<string>());\n const keysLastHandledAt = useRef<number | null>(null);\n const handlePressedKeys = useCallback(\n (time: number) => {\n const nothingPressed = pressedKeys.current.size === 0;\n if (nothingPressed) {\n keysLastHandledAt.current = null;\n return;\n } else if (primarySizeRef.current === null) {\n return;\n }\n\n const dt = time - (keysLastHandledAt.current ?? time);\n const dx = dt * PIXELS_PER_MS;\n let sizeChange = 0;\n\n if (direction === 'row') {\n if (pressedKeys.current.has('ArrowLeft')) {\n sizeChange -= dx;\n }\n if (pressedKeys.current.has('ArrowRight')) {\n sizeChange += dx;\n }\n } else {\n if (pressedKeys.current.has('ArrowUp')) {\n sizeChange -= dx;\n }\n if (pressedKeys.current.has('ArrowDown')) {\n sizeChange += dx;\n }\n }\n\n // measure primary and container\n primarySizeRef.current = firstPaneRef.current!.getBoundingClientRect()[measurementProp];\n containerSize.current = containerRef.current!.getBoundingClientRect()[measurementProp];\n\n onUpdateSize(sizeChange);\n\n keysLastHandledAt.current = time;\n\n window.requestAnimationFrame(handlePressedKeys);\n },\n [direction, measurementProp, onUpdateSize]\n );\n\n const onKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (!firstPaneRef.current || !secondPaneRef.current || !splitterRef.current || !containerRef.current) {\n return;\n }\n\n if (\n !(\n (direction === 'column' && VERTICAL_KEYS.has(e.key)) ||\n (direction === 'row' && HORIZONTAL_KEYS.has(e.key))\n ) ||\n pressedKeys.current.has(e.key)\n ) {\n return;\n }\n\n savedPos.current = undefined;\n e.preventDefault();\n e.stopPropagation();\n\n primarySizeRef.current = firstPaneRef.current.getBoundingClientRect()[measurementProp];\n containerSize.current = containerRef.current!.getBoundingClientRect()[measurementProp];\n\n if (usePixels) {\n referencePaneSize.current = measureElement(secondPaneRef.current!);\n } else {\n referencePaneSize.current = measureElement(firstPaneRef.current!);\n }\n\n const newKey = !pressedKeys.current.has(e.key);\n\n if (newKey) {\n const initiateAnimationLoop = pressedKeys.current.size === 0;\n pressedKeys.current.add(e.key);\n\n if (initiateAnimationLoop) {\n window.requestAnimationFrame(handlePressedKeys);\n }\n }\n },\n [direction, handlePressedKeys, , measurementProp, usePixels]\n );\n\n const onKeyUp = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (\n (direction === 'row' && !HORIZONTAL_KEYS.has(e.key)) ||\n (direction === 'column' && !VERTICAL_KEYS.has(e.key))\n ) {\n return;\n }\n\n pressedKeys.current.delete(e.key);\n\n if (primarySizeRef.current !== null) {\n const secondPanePixels = containerSize.current! - primarySizeRef.current - handleSize;\n onSizeChanged?.(parseFloat(firstPaneRef.current!.style.flexGrow), primarySizeRef.current, secondPanePixels);\n }\n },\n [direction, onSizeChanged, handleSize]\n );\n\n const onDoubleClick = useCallback(() => {\n if (!firstPaneRef.current || !secondPaneRef.current) {\n return;\n }\n\n if (usePixels) {\n secondPaneRef.current.style.flexBasis = `${initialSize}px`;\n } else {\n firstPaneRef.current.style.flexGrow = '0.5';\n secondPaneRef.current.style.flexGrow = '0.5';\n primarySizeRef.current = firstPaneRef.current!.getBoundingClientRect()[measurementProp];\n splitterRef.current!.ariaValueNow = `50`;\n }\n }, [measurementProp, usePixels, initialSize]);\n\n const onBlur = useCallback(() => {\n // If focus is lost while keys are held, stop changing panel sizes\n if (pressedKeys.current.size > 0) {\n pressedKeys.current.clear();\n dragStart.current = null;\n\n if (typeof primarySizeRef.current === 'number') {\n const secondPanePixels = containerSize.current! - primarySizeRef.current - handleSize;\n onSizeChanged?.(parseFloat(firstPaneRef.current!.style.flexGrow), primarySizeRef.current, secondPanePixels);\n }\n }\n }, [onSizeChanged, handleSize]);\n\n const styles = useStyles2(getStyles, direction);\n const dragStyles = useStyles2(getDragStyles, dragPosition);\n const dragHandleStyle = direction === 'column' ? dragStyles.dragHandleHorizontal : dragStyles.dragHandleVertical;\n const id = useId();\n\n const primaryStyles: React.CSSProperties = {\n flexGrow: clamp(initialSize, 0, 1),\n [minDimProp]: 'min-content',\n };\n\n const secondaryStyles: React.CSSProperties = {\n flexGrow: clamp(1 - initialSize, 0, 1),\n [minDimProp]: 'min-content',\n };\n\n if (usePixels) {\n primaryStyles.flexGrow = 1;\n secondaryStyles.flexGrow = 'unset';\n secondaryStyles.flexBasis = `${initialSize}px`;\n }\n\n const primaryId = `start-panel-${id}`;\n\n return {\n containerProps: {\n ref: containerRef,\n className: styles.container,\n },\n primaryProps: {\n ref: firstPaneRef,\n className: styles.panel,\n style: primaryStyles,\n id: primaryId,\n },\n secondaryProps: {\n ref: secondPaneRef,\n className: styles.panel,\n style: secondaryStyles,\n },\n splitterProps: {\n onPointerUp,\n onPointerDown,\n onPointerMove,\n onKeyDown,\n onKeyUp,\n onDoubleClick,\n onBlur,\n ref: splitterRef,\n style: { [measurementProp]: `${handleSize}px` },\n role: 'separator',\n 'aria-valuemin': 0,\n 'aria-valuemax': 100,\n 'aria-valuenow': initialSize * 100,\n 'aria-controls': primaryId,\n 'aria-label': 'Pane resize widget',\n tabIndex: 0,\n className: dragHandleStyle,\n },\n };\n}\n\nfunction ariaValue(value: number, min: number, max: number) {\n return `${clamp(((value - min) / (max - min)) * 100, 0, 100)}`;\n}\n\ninterface MeasureResult {\n minWidth: number;\n maxWidth: number;\n minHeight: number;\n maxHeight: number;\n}\n\nfunction measureElement<T extends HTMLElement>(ref: T, usePixels?: boolean): MeasureResult {\n const savedBodyOverflow = document.body.style.overflow;\n const savedWidth = ref.style.width;\n const savedHeight = ref.style.height;\n const savedFlex = ref.style.flexGrow;\n const savedFlexBasis = ref.style.flexBasis;\n\n document.body.style.overflow = 'hidden';\n\n ref.style.flexGrow = '0';\n ref.style.flexBasis = '0';\n\n const { width: minWidth, height: minHeight } = ref.getBoundingClientRect();\n\n ref.style.flexGrow = '100';\n\n const { width: maxWidth, height: maxHeight } = ref.getBoundingClientRect();\n\n document.body.style.overflow = savedBodyOverflow;\n\n ref.style.width = savedWidth;\n ref.style.height = savedHeight;\n ref.style.flexGrow = savedFlex;\n ref.style.flexBasis = savedFlexBasis;\n\n return { minWidth, maxWidth, minHeight, maxHeight };\n}\n\nfunction getStyles(theme: GrafanaTheme2, direction: UseSplitterOptions['direction']) {\n return {\n container: css({\n display: 'flex',\n flexDirection: direction === 'row' ? 'row' : 'column',\n width: '100%',\n flexGrow: 1,\n overflow: 'hidden',\n }),\n panel: css({ display: 'flex', position: 'relative', flexBasis: 0 }),\n };\n}\n\nfunction getPixelSize(size: ComponentSize = 'md') {\n return {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 32,\n }[size];\n}\n"],"names":[],"mappings":";;;;;;;AAgCA,MAAM,aAAA,GAAgB,GAAA;AACtB,MAAM,gCAAgB,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,WAAW,CAAC,CAAA;AACtD,MAAM,kCAAkB,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,YAAY,CAAC,CAAA;AAE3D,MAAM,iBAAA,GAAoB;AAAA,EACxB,GAAA,EAAK;AAAA,IACH,GAAA,EAAK,OAAA;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,GAAA,EAAK,UAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACP;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,GAAA,EAAK,QAAA;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,GAAA,EAAK,WAAA;AAAA,IACL,GAAA,EAAK;AAAA;AAET,CAAA;AAEO,SAAS,YAAY,OAAA,EAA6B;AACvD,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,WAAA,GAAc,OAAA,CAAQ,SAAA,GAAY,GAAA,GAAM,GAAA;AAAA,IACxC,YAAA,GAAe,QAAA;AAAA,IACf,UAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,UAAA,GAAa,YAAA,CAAa,OAAA,CAAQ,UAAU,CAAA;AAClD,EAAA,MAAM,WAAA,GAAc,OAA8B,IAAI,CAAA;AACtD,EAAA,MAAM,YAAA,GAAe,OAA8B,IAAI,CAAA;AACvD,EAAA,MAAM,aAAA,GAAgB,OAA8B,IAAI,CAAA;AACxD,EAAA,MAAM,YAAA,GAAe,OAA8B,IAAI,CAAA;AACvD,EAAA,MAAM,aAAA,GAAgB,OAAsB,IAAI,CAAA;AAChD,EAAA,MAAM,cAAA,GAAiB,OAAsB,IAAI,CAAA;AACjD,EAAA,MAAM,iBAAA,GAAoB,OAAkC,KAAA,CAAS,CAAA;AACrE,EAAA,MAAM,QAAA,GAAW,OAA2B,KAAA,CAAS,CAAA;AAErD,EAAA,MAAM,eAAA,GAAkB,iBAAA,CAAkB,SAAS,CAAA,CAAE,GAAA;AACrD,EAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,SAAS,CAAA,CAAE,IAAA;AAChD,EAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,SAAS,CAAA,CAAE,GAAA;AAChD,EAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,SAAS,CAAA,CAAE,GAAA;AAChD,EAAA,MAAM,SAAA,GAAY,OAAsB,IAAI,CAAA;AAE5C,EAAA,MAAM,aAAA,GAAgB,WAAA;AAAA,IACpB,CAAC,CAAA,KAA0C;AACzC,MAAA,IAAI,CAAC,YAAA,CAAa,OAAA,IAAW,CAAC,cAAc,OAAA,EAAS;AACnD,QAAA;AAAA,MACF;AAGA,MAAA,cAAA,CAAe,OAAA,GAAU,YAAA,CAAa,OAAA,CAAS,qBAAA,GAAwB,eAAe,CAAA;AACtF,MAAA,aAAA,CAAc,OAAA,GAAU,YAAA,CAAa,OAAA,CAAS,qBAAA,GAAwB,eAAe,CAAA;AAErF,MAAA,SAAA,CAAU,OAAA,GAAU,EAAE,UAAU,CAAA;AAChC,MAAA,WAAA,CAAY,OAAA,CAAS,iBAAA,CAAkB,CAAA,CAAE,SAAS,CAAA;AAElD,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,iBAAA,CAAkB,OAAA,GAAU,cAAA,CAAe,aAAA,CAAc,OAAA,EAAS,SAAS,CAAA;AAAA,MAC7E,CAAA,MAAO;AACL,QAAA,iBAAA,CAAkB,OAAA,GAAU,cAAA,CAAe,YAAA,CAAa,OAAO,CAAA;AAAA,MACjE;AAEA,MAAA,QAAA,CAAS,OAAA,GAAU,KAAA,CAAA;AAAA,IACrB,CAAA;AAAA,IACA,CAAC,eAAA,EAAiB,UAAA,EAAY,SAAS;AAAA,GACzC;AAEA,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,IAAA,KAAiB;AAChB,MAAA,IAAI,CAAC,cAAc,OAAA,IAAW,CAAC,eAAe,OAAA,IAAW,CAAC,cAAc,OAAA,EAAS;AAC/E,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,kBAAkB,cAAA,CAAe,OAAA;AACvC,MAAA,MAAM,gBAAA,GAAmB,aAAA,CAAc,OAAA,GAAU,eAAA,GAAkB,UAAA;AACnE,MAAA,MAAM,OAAO,iBAAA,CAAkB,OAAA;AAE/B,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAM,OAAA,GAAU,MAAM,gBAAA,GAAmB,IAAA,EAAM,KAAK,UAAU,CAAA,EAAG,IAAA,CAAK,UAAU,CAAC,CAAA;AACjF,QAAA,aAAA,CAAc,OAAA,CAAS,KAAA,CAAM,SAAA,GAAY,CAAA,EAAG,OAAO,CAAA,EAAA,CAAA;AACnD,QAAA,WAAA,CAAY,OAAA,CAAS,YAAA,GAAe,CAAA,EAAG,OAAO,CAAA,CAAA;AAC9C,QAAA,UAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,UAAA,CAAa,OAAA,EAAS,kBAAkB,IAAA,EAAM,OAAA,CAAA;AAAA,MAChD,CAAA,MAAO;AACL,QAAA,MAAM,OAAA,GAAU,KAAA,CAAM,cAAA,CAAe,OAAA,GAAU,IAAA,EAAM,KAAK,UAAU,CAAA,EAAG,IAAA,CAAK,UAAU,CAAC,CAAA;AACvF,QAAA,MAAM,OAAA,GAAU,OAAA,IAAW,aAAA,CAAc,OAAA,GAAW,UAAA,CAAA;AACpD,QAAA,YAAA,CAAa,OAAA,CAAS,KAAA,CAAM,QAAA,GAAW,CAAA,EAAG,OAAO,CAAA,CAAA;AACjD,QAAA,aAAA,CAAc,OAAA,CAAS,KAAA,CAAM,QAAA,GAAW,CAAA,EAAG,IAAI,OAAO,CAAA,CAAA;AACtD,QAAA,WAAA,CAAY,OAAA,CAAS,eAAe,SAAA,CAAU,OAAA,EAAS,KAAK,UAAU,CAAA,EAAG,IAAA,CAAK,UAAU,CAAC,CAAA;AACzF,QAAA,UAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,UAAA,CAAa,OAAA,EAAS,SAAS,gBAAA,GAAmB,IAAA,CAAA;AAAA,MACpD;AAAA,IACF,CAAA;AAAA,IACA,CAAC,UAAA,EAAY,UAAA,EAAY,SAAA,EAAW,YAAY,UAAU;AAAA,GAC5D;AAEA,EAAA,MAAM,aAAA,GAAgB,WAAA;AAAA,IACpB,CAAC,CAAA,KAA0C;AACzC,MAAA,IAAI,SAAA,CAAU,YAAY,IAAA,EAAM;AAC9B,QAAA,YAAA,CAAa,CAAA,CAAE,UAAU,CAAA,GAAI,SAAA,CAAU,OAAO,CAAA;AAAA,MAChD;AAAA,IACF,CAAA;AAAA,IACA,CAAC,cAAc,UAAU;AAAA,GAC3B;AAEA,EAAA,MAAM,WAAA,GAAc,WAAA;AAAA,IAClB,CAAC,CAAA,KAA0C;AACzC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,CAAA,CAAE,eAAA,EAAgB;AAElB,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAEpB,MAAA,WAAA,CAAY,OAAA,CAAS,qBAAA,CAAsB,CAAA,CAAE,SAAS,CAAA;AAEtD,MAAA,MAAM,aAAA,GAAgB,YAAA,CAAa,OAAA,CAAS,qBAAA,GAAwB,eAAe,CAAA;AACnF,MAAA,MAAM,gBAAA,GAAmB,aAAA,CAAc,OAAA,GAAW,aAAA,GAAgB,UAAA;AAElE,MAAA,aAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,aAAA,CAAgB,WAAW,YAAA,CAAa,OAAA,CAAS,KAAA,CAAM,QAAQ,GAAG,aAAA,EAAe,gBAAA,CAAA;AAAA,IACnF,CAAA;AAAA,IACA,CAAC,aAAA,EAAe,UAAA,EAAY,eAAe;AAAA,GAC7C;AAEA,EAAA,MAAM,WAAA,GAAc,MAAA,iBAAO,IAAI,GAAA,EAAa,CAAA;AAC5C,EAAA,MAAM,iBAAA,GAAoB,OAAsB,IAAI,CAAA;AACpD,EAAA,MAAM,iBAAA,GAAoB,WAAA;AAAA,IACxB,CAAC,IAAA,KAAiB;AA7JtB,MAAA,IAAA,EAAA;AA8JM,MAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,OAAA,CAAQ,IAAA,KAAS,CAAA;AACpD,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,iBAAA,CAAkB,OAAA,GAAU,IAAA;AAC5B,QAAA;AAAA,MACF,CAAA,MAAA,IAAW,cAAA,CAAe,OAAA,KAAY,IAAA,EAAM;AAC1C,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,EAAA,GAAK,IAAA,IAAA,CAAQ,EAAA,GAAA,iBAAA,CAAkB,OAAA,KAAlB,IAAA,GAAA,EAAA,GAA6B,IAAA,CAAA;AAChD,MAAA,MAAM,KAAK,EAAA,GAAK,aAAA;AAChB,MAAA,IAAI,UAAA,GAAa,CAAA;AAEjB,MAAA,IAAI,cAAc,KAAA,EAAO;AACvB,QAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA,EAAG;AACxC,UAAA,UAAA,IAAc,EAAA;AAAA,QAChB;AACA,QAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,GAAA,CAAI,YAAY,CAAA,EAAG;AACzC,UAAA,UAAA,IAAc,EAAA;AAAA,QAChB;AAAA,MACF,CAAA,MAAO;AACL,QAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA,EAAG;AACtC,UAAA,UAAA,IAAc,EAAA;AAAA,QAChB;AACA,QAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA,EAAG;AACxC,UAAA,UAAA,IAAc,EAAA;AAAA,QAChB;AAAA,MACF;AAGA,MAAA,cAAA,CAAe,OAAA,GAAU,YAAA,CAAa,OAAA,CAAS,qBAAA,GAAwB,eAAe,CAAA;AACtF,MAAA,aAAA,CAAc,OAAA,GAAU,YAAA,CAAa,OAAA,CAAS,qBAAA,GAAwB,eAAe,CAAA;AAErF,MAAA,YAAA,CAAa,UAAU,CAAA;AAEvB,MAAA,iBAAA,CAAkB,OAAA,GAAU,IAAA;AAE5B,MAAA,MAAA,CAAO,sBAAsB,iBAAiB,CAAA;AAAA,IAChD,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,eAAA,EAAiB,YAAY;AAAA,GAC3C;AAEA,EAAA,MAAM,SAAA,GAAY,WAAA;AAAA,IAChB,CAAC,CAAA,KAA2C;AAC1C,MAAA,IAAI,CAAC,YAAA,CAAa,OAAA,IAAW,CAAC,aAAA,CAAc,OAAA,IAAW,CAAC,WAAA,CAAY,OAAA,IAAW,CAAC,YAAA,CAAa,OAAA,EAAS;AACpG,QAAA;AAAA,MACF;AAEA,MAAA,IACE,EACG,cAAc,QAAA,IAAY,aAAA,CAAc,IAAI,CAAA,CAAE,GAAG,KACjD,SAAA,KAAc,KAAA,IAAS,gBAAgB,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA,CAAA,IAEnD,WAAA,CAAY,QAAQ,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA,EAC7B;AACA,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,OAAA,GAAU,KAAA,CAAA;AACnB,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,CAAA,CAAE,eAAA,EAAgB;AAElB,MAAA,cAAA,CAAe,OAAA,GAAU,YAAA,CAAa,OAAA,CAAQ,qBAAA,GAAwB,eAAe,CAAA;AACrF,MAAA,aAAA,CAAc,OAAA,GAAU,YAAA,CAAa,OAAA,CAAS,qBAAA,GAAwB,eAAe,CAAA;AAErF,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,iBAAA,CAAkB,OAAA,GAAU,cAAA,CAAe,aAAA,CAAc,OAAQ,CAAA;AAAA,MACnE,CAAA,MAAO;AACL,QAAA,iBAAA,CAAkB,OAAA,GAAU,cAAA,CAAe,YAAA,CAAa,OAAQ,CAAA;AAAA,MAClE;AAEA,MAAA,MAAM,SAAS,CAAC,WAAA,CAAY,OAAA,CAAQ,GAAA,CAAI,EAAE,GAAG,CAAA;AAE7C,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAM,qBAAA,GAAwB,WAAA,CAAY,OAAA,CAAQ,IAAA,KAAS,CAAA;AAC3D,QAAA,WAAA,CAAY,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA;AAE7B,QAAA,IAAI,qBAAA,EAAuB;AACzB,UAAA,MAAA,CAAO,sBAAsB,iBAAiB,CAAA;AAAA,QAChD;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,iBAAA,IAAqB,iBAAiB,SAAS;AAAA,GAC7D;AAEA,EAAA,MAAM,OAAA,GAAU,WAAA;AAAA,IACd,CAAC,CAAA,KAA2C;AAC1C,MAAA,IACG,SAAA,KAAc,KAAA,IAAS,CAAC,eAAA,CAAgB,IAAI,CAAA,CAAE,GAAG,CAAA,IACjD,SAAA,KAAc,YAAY,CAAC,aAAA,CAAc,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA,EACnD;AACA,QAAA;AAAA,MACF;AAEA,MAAA,WAAA,CAAY,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAE,GAAG,CAAA;AAEhC,MAAA,IAAI,cAAA,CAAe,YAAY,IAAA,EAAM;AACnC,QAAA,MAAM,gBAAA,GAAmB,aAAA,CAAc,OAAA,GAAW,cAAA,CAAe,OAAA,GAAU,UAAA;AAC3E,QAAA,aAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,aAAA,CAAgB,WAAW,YAAA,CAAa,OAAA,CAAS,MAAM,QAAQ,CAAA,EAAG,eAAe,OAAA,EAAS,gBAAA,CAAA;AAAA,MAC5F;AAAA,IACF,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,aAAA,EAAe,UAAU;AAAA,GACvC;AAEA,EAAA,MAAM,aAAA,GAAgB,YAAY,MAAM;AACtC,IAAA,IAAI,CAAC,YAAA,CAAa,OAAA,IAAW,CAAC,cAAc,OAAA,EAAS;AACnD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,aAAA,CAAc,OAAA,CAAQ,KAAA,CAAM,SAAA,GAAY,CAAA,EAAG,WAAW,CAAA,EAAA,CAAA;AAAA,IACxD,CAAA,MAAO;AACL,MAAA,YAAA,CAAa,OAAA,CAAQ,MAAM,QAAA,GAAW,KAAA;AACtC,MAAA,aAAA,CAAc,OAAA,CAAQ,MAAM,QAAA,GAAW,KAAA;AACvC,MAAA,cAAA,CAAe,OAAA,GAAU,YAAA,CAAa,OAAA,CAAS,qBAAA,GAAwB,eAAe,CAAA;AACtF,MAAA,WAAA,CAAY,QAAS,YAAA,GAAe,CAAA,EAAA,CAAA;AAAA,IACtC;AAAA,EACF,CAAA,EAAG,CAAC,eAAA,EAAiB,SAAA,EAAW,WAAW,CAAC,CAAA;AAE5C,EAAA,MAAM,MAAA,GAAS,YAAY,MAAM;AAE/B,IAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,IAAA,GAAO,CAAA,EAAG;AAChC,MAAA,WAAA,CAAY,QAAQ,KAAA,EAAM;AAC1B,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAEpB,MAAA,IAAI,OAAO,cAAA,CAAe,OAAA,KAAY,QAAA,EAAU;AAC9C,QAAA,MAAM,gBAAA,GAAmB,aAAA,CAAc,OAAA,GAAW,cAAA,CAAe,OAAA,GAAU,UAAA;AAC3E,QAAA,aAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,aAAA,CAAgB,WAAW,YAAA,CAAa,OAAA,CAAS,MAAM,QAAQ,CAAA,EAAG,eAAe,OAAA,EAAS,gBAAA,CAAA;AAAA,MAC5F;AAAA,IACF;AAAA,EACF,CAAA,EAAG,CAAC,aAAA,EAAe,UAAU,CAAC,CAAA;AAE9B,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,SAAA,EAAW,SAAS,CAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,UAAA,CAAW,aAAA,EAAe,YAAY,CAAA;AACzD,EAAA,MAAM,eAAA,GAAkB,SAAA,KAAc,QAAA,GAAW,UAAA,CAAW,uBAAuB,UAAA,CAAW,kBAAA;AAC9F,EAAA,MAAM,KAAK,KAAA,EAAM;AAEjB,EAAA,MAAM,aAAA,GAAqC;AAAA,IACzC,QAAA,EAAU,KAAA,CAAM,WAAA,EAAa,CAAA,EAAG,CAAC,CAAA;AAAA,IACjC,CAAC,UAAU,GAAG;AAAA,GAChB;AAEA,EAAA,MAAM,eAAA,GAAuC;AAAA,IAC3C,QAAA,EAAU,KAAA,CAAM,CAAA,GAAI,WAAA,EAAa,GAAG,CAAC,CAAA;AAAA,IACrC,CAAC,UAAU,GAAG;AAAA,GAChB;AAEA,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,aAAA,CAAc,QAAA,GAAW,CAAA;AACzB,IAAA,eAAA,CAAgB,QAAA,GAAW,OAAA;AAC3B,IAAA,eAAA,CAAgB,SAAA,GAAY,GAAG,WAAW,CAAA,EAAA,CAAA;AAAA,EAC5C;AAEA,EAAA,MAAM,SAAA,GAAY,eAAe,EAAE,CAAA,CAAA;AAEnC,EAAA,OAAO;AAAA,IACL,cAAA,EAAgB;AAAA,MACd,GAAA,EAAK,YAAA;AAAA,MACL,WAAW,MAAA,CAAO;AAAA,KACpB;AAAA,IACA,YAAA,EAAc;AAAA,MACZ,GAAA,EAAK,YAAA;AAAA,MACL,WAAW,MAAA,CAAO,KAAA;AAAA,MAClB,KAAA,EAAO,aAAA;AAAA,MACP,EAAA,EAAI;AAAA,KACN;AAAA,IACA,cAAA,EAAgB;AAAA,MACd,GAAA,EAAK,aAAA;AAAA,MACL,WAAW,MAAA,CAAO,KAAA;AAAA,MAClB,KAAA,EAAO;AAAA,KACT;AAAA,IACA,aAAA,EAAe;AAAA,MACb,WAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,aAAA;AAAA,MACA,MAAA;AAAA,MACA,GAAA,EAAK,WAAA;AAAA,MACL,OAAO,EAAE,CAAC,eAAe,GAAG,CAAA,EAAG,UAAU,CAAA,EAAA,CAAA,EAAK;AAAA,MAC9C,IAAA,EAAM,WAAA;AAAA,MACN,eAAA,EAAiB,CAAA;AAAA,MACjB,eAAA,EAAiB,GAAA;AAAA,MACjB,iBAAiB,WAAA,GAAc,GAAA;AAAA,MAC/B,eAAA,EAAiB,SAAA;AAAA,MACjB,YAAA,EAAc,oBAAA;AAAA,MACd,QAAA,EAAU,CAAA;AAAA,MACV,SAAA,EAAW;AAAA;AACb,GACF;AACF;AAEA,SAAS,SAAA,CAAU,KAAA,EAAe,GAAA,EAAa,GAAA,EAAa;AAC1D,EAAA,OAAO,CAAA,EAAG,OAAQ,KAAA,GAAQ,GAAA,KAAQ,MAAM,GAAA,CAAA,GAAQ,GAAA,EAAK,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAC9D;AASA,SAAS,cAAA,CAAsC,KAAQ,SAAA,EAAoC;AACzF,EAAA,MAAM,iBAAA,GAAoB,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,QAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,IAAI,KAAA,CAAM,KAAA;AAC7B,EAAA,MAAM,WAAA,GAAc,IAAI,KAAA,CAAM,MAAA;AAC9B,EAAA,MAAM,SAAA,GAAY,IAAI,KAAA,CAAM,QAAA;AAC5B,EAAA,MAAM,cAAA,GAAiB,IAAI,KAAA,CAAM,SAAA;AAEjC,EAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,QAAA;AAE/B,EAAA,GAAA,CAAI,MAAM,QAAA,GAAW,GAAA;AACrB,EAAA,GAAA,CAAI,MAAM,SAAA,GAAY,GAAA;AAEtB,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAU,QAAQ,SAAA,EAAU,GAAI,IAAI,qBAAA,EAAsB;AAEzE,EAAA,GAAA,CAAI,MAAM,QAAA,GAAW,KAAA;AAErB,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAU,QAAQ,SAAA,EAAU,GAAI,IAAI,qBAAA,EAAsB;AAEzE,EAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,iBAAA;AAE/B,EAAA,GAAA,CAAI,MAAM,KAAA,GAAQ,UAAA;AAClB,EAAA,GAAA,CAAI,MAAM,MAAA,GAAS,WAAA;AACnB,EAAA,GAAA,CAAI,MAAM,QAAA,GAAW,SAAA;AACrB,EAAA,GAAA,CAAI,MAAM,SAAA,GAAY,cAAA;AAEtB,EAAA,OAAO,EAAE,QAAA,EAAU,QAAA,EAAU,SAAA,EAAW,SAAA,EAAU;AACpD;AAEA,SAAS,SAAA,CAAU,OAAsB,SAAA,EAA4C;AACnF,EAAA,OAAO;AAAA,IACL,WAAW,GAAA,CAAI;AAAA,MACb,OAAA,EAAS,MAAA;AAAA,MACT,aAAA,EAAe,SAAA,KAAc,KAAA,GAAQ,KAAA,GAAQ,QAAA;AAAA,MAC7C,KAAA,EAAO,MAAA;AAAA,MACP,QAAA,EAAU,CAAA;AAAA,MACV,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACD,KAAA,EAAO,IAAI,EAAE,OAAA,EAAS,QAAQ,QAAA,EAAU,UAAA,EAAY,SAAA,EAAW,CAAA,EAAG;AAAA,GACpE;AACF;AAEA,SAAS,YAAA,CAAa,OAAsB,IAAA,EAAM;AAChD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,CAAA;AAAA,IACJ,EAAA,EAAI,CAAA;AAAA,IACJ,EAAA,EAAI,EAAA;AAAA,IACJ,EAAA,EAAI;AAAA,IACJ,IAAI,CAAA;AACR;;;;"}