From 07a2c927ebef1cbaae5b034d6a30444b654e3408 Mon Sep 17 00:00:00 2001 From: toshusai Date: Sun, 25 Feb 2024 20:17:55 +0900 Subject: [PATCH] feat: first public commit --- .github/workflows/publish.yaml | 26 + .github/workflows/storybook.yaml | 25 + .github/workflows/test.yaml | 20 + .gitignore | 7 + .node-version | 1 + .storybook/@types/declarations.d.ts | 5 + .storybook/DocumentationTemplate.mdx | 22 + .storybook/main.ts | 21 + .storybook/preview.tsx | 55 + .storybook/storybook.css | 27 + .storybook/test-runner.ts | 11 + biome.json | 29 + package.json | 68 + pnpm-lock.yaml | 10925 ++++++++++++++++ src/README.mdx | 40 + src/__stories__/Icon.tsx | 25 + src/__stories__/Panel.tsx | 46 + src/__stories__/Root.tsx | 15 + src/__stories__/ShortcutListItem.tsx | 33 + src/__stories__/stories.css | 11 + .../__snapshots__/index.stories.tsx.snap | 587 + src/components/AngleInput/index.css | 18 + src/components/AngleInput/index.stories.tsx | 39 + src/components/AngleInput/index.tsx | 156 + .../__snapshots__/index.stories.tsx.snap | 42 + src/components/Button/index.css | 80 + src/components/Button/index.stories.tsx | 34 + src/components/Button/index.tsx | 37 + src/components/CanvasView/View.ts | 5 + src/components/CanvasView/ViewMode.ts | 1 + .../__snapshots__/index.stories.tsx.snap | 55 + src/components/CanvasView/index.css | 10 + src/components/CanvasView/index.stories.tsx | 165 + src/components/CanvasView/index.tsx | 206 + src/components/Checkbox/CheckSVG.tsx | 13 + .../__snapshots__/index.stories.tsx.snap | 129 + src/components/Checkbox/index.css | 71 + src/components/Checkbox/index.stories.tsx | 71 + src/components/Checkbox/index.tsx | 43 + src/components/Circle/index.css | 17 + src/components/Circle/index.tsx | 40 + .../__snapshots__/index.stories.tsx.snap | 37 + src/components/ColorInput/index.css | 45 + src/components/ColorInput/index.stories.tsx | 32 + src/components/ColorInput/index.tsx | 164 + .../__snapshots__/index.stories.tsx.snap | 32 + src/components/ColorLoupe/index.stories.tsx | 26 + src/components/ColorLoupe/index.tsx | 49 + .../__snapshots__/index.stories.tsx.snap | 66 + src/components/ColorPickerCircle/index.css | 18 + .../ColorPickerCircle/index.stories.tsx | 40 + src/components/ColorPickerCircle/index.tsx | 127 + .../__snapshots__/index.stories.tsx.snap | 69 + src/components/ColorPickerRect/index.css | 8 + .../ColorPickerRect/index.stories.tsx | 35 + src/components/ColorPickerRect/index.tsx | 117 + .../__snapshots__/index.stories.tsx.snap | 82 + src/components/ColorSlider/index.css | 25 + src/components/ColorSlider/index.stories.tsx | 99 + src/components/ColorSlider/index.tsx | 202 + .../ContextMenu/ContextMenuItem.tsx | 16 + .../ContextMenu/ContextMenuSeparator.tsx | 5 + .../__snapshots__/index.stories.tsx.snap | 9 + src/components/ContextMenu/index.css | 7 + src/components/ContextMenu/index.stories.tsx | 72 + src/components/ContextMenu/index.tsx | 27 + src/components/CubicControls/CubicCommand.ts | 35 + .../__snapshots__/index.stories.tsx.snap | 66 + src/components/CubicControls/index.css | 15 + .../CubicControls/index.stories.tsx | 48 + src/components/CubicControls/index.tsx | 122 + .../DropdownMenu/DropdownMenuItem.tsx | 19 + .../__snapshots__/index.stories.tsx.snap | 17 + src/components/DropdownMenu/index.stories.tsx | 40 + src/components/DropdownMenu/index.tsx | 29 + .../__snapshots__/index.stories.tsx.snap | 63 + src/components/FloatBox/index.css | 19 + src/components/FloatBox/index.stories.tsx | 39 + src/components/FloatBox/index.tsx | 16 + .../Grid/__snapshots__/index.stories.tsx.snap | 10 + src/components/Grid/index.css | 21 + src/components/Grid/index.stories.tsx | 28 + src/components/Grid/index.tsx | 42 + .../__snapshots__/index.stories.tsx.snap | 61 + src/components/HueCircle/index.css | 55 + src/components/HueCircle/index.stories.tsx | 37 + src/components/HueCircle/index.tsx | 221 + src/components/IconButton/IconButtonGroup.tsx | 19 + .../__snapshots__/index.stories.tsx.snap | 131 + src/components/IconButton/index.css | 97 + src/components/IconButton/index.stories.tsx | 99 + src/components/IconButton/index.tsx | 29 + .../Line/__snapshots__/index.stories.tsx.snap | 20 + src/components/Line/index.stories.tsx | 33 + src/components/Line/index.tsx | 38 + .../__snapshots__/index.stories.tsx.snap | 120 + src/components/ListItem/index.css | 60 + src/components/ListItem/index.stories.tsx | 95 + src/components/ListItem/index.tsx | 58 + src/components/MenuBarButton/MenuBar.tsx | 15 + src/components/MenuBarButton/MenuBarItem.tsx | 24 + .../MenuBarButton/MenuBarSeparator.tsx | 5 + .../MenuBarButton/MenuBarSubButton.tsx | 43 + .../__snapshots__/index.stories.tsx.snap | 63 + src/components/MenuBarButton/index.css | 68 + .../MenuBarButton/index.stories.tsx | 158 + src/components/MenuBarButton/index.tsx | 40 + .../__snapshots__/index.stories.tsx.snap | 11 + src/components/Modal/index.css | 73 + src/components/Modal/index.stories.tsx | 103 + src/components/Modal/index.tsx | 69 + .../Path/__snapshots__/index.stories.tsx.snap | 21 + src/components/Path/index.stories.tsx | 23 + src/components/Path/index.tsx | 84 + .../__snapshots__/index.stories.tsx.snap | 11 + src/components/Popover/index.css | 63 + src/components/Popover/index.stories.tsx | 107 + src/components/Popover/index.tsx | 29 + src/components/RectGizmo/AngleNob.tsx | 94 + src/components/RectGizmo/MovableRect.tsx | 76 + .../__snapshots__/index.stories.tsx.snap | 371 + src/components/RectGizmo/index.css | 7 + src/components/RectGizmo/index.stories.tsx | 153 + src/components/RectGizmo/index.tsx | 260 + .../lib/createCursorStyleBase64SVGUrl.ts | 8 + .../lib/createHorizontalResizeSVGString.ts | 6 + .../RectGizmo/lib/createResizeHandler.ts | 163 + .../lib/createRotateHorizontalResize.ts | 12 + .../RectGizmo/lib/positionSignMap.ts | 8 + .../RectGizmo/lib/proportionalResize.ts | 28 + src/components/Ruler/TimeText.tsx | 28 + .../__snapshots__/index.stories.tsx.snap | 1474 +++ src/components/Ruler/defaultRenderText.ts | 12 + src/components/Ruler/defaultSteps.ts | 1 + src/components/Ruler/getStepPixel.ts | 16 + src/components/Ruler/index.css | 82 + src/components/Ruler/index.stories.tsx | 91 + src/components/Ruler/index.tsx | 105 + .../__snapshots__/index.stories.tsx.snap | 19 + src/components/SVPicker/index.css | 23 + src/components/SVPicker/index.stories.tsx | 30 + src/components/SVPicker/index.tsx | 146 + src/components/SVPicker/lib/SVCanvas.tsx | 93 + src/components/SVPicker/lib/drawSV.tsx | 21 + src/components/Select/SelectItem.tsx | 44 + .../__snapshots__/index.stories.tsx.snap | 121 + src/components/Select/index.css | 55 + src/components/Select/index.stories.tsx | 155 + src/components/Select/index.tsx | 62 + .../__snapshots__/index.stories.tsx.snap | 13 + src/components/SelectRect/index.stories.tsx | 48 + src/components/SelectRect/index.tsx | 94 + .../__snapshots__/index.stories.tsx.snap | 120 + src/components/Slider/index.css | 108 + src/components/Slider/index.stories.tsx | 82 + src/components/Slider/index.tsx | 178 + .../__snapshots__/index.stories.tsx.snap | 53 + src/components/SliderNumberField/index.css | 9 + .../SliderNumberField/index.stories.tsx | 68 + src/components/SliderNumberField/index.tsx | 283 + .../SliderNumberField/lib/inputEval.test.ts | 14 + .../SliderNumberField/lib/inputEval.ts | 20 + .../SliderNumberField/lib/isEvalSafe.test.ts | 24 + .../SliderNumberField/lib/isEvalSafe.ts | 9 + .../SliderNumberField/lib/parseCursorStyle.ts | 12 + .../__snapshots__/index.stories.tsx.snap | 237 + src/components/SplitPane/index.css | 62 + src/components/SplitPane/index.stories.tsx | 88 + src/components/SplitPane/index.tsx | 79 + src/components/SplitPane/useSplitPane.ts | 144 + .../__snapshots__/index.stories.tsx.snap | 94 + src/components/Switch/index.css | 73 + src/components/Switch/index.stories.tsx | 80 + src/components/Switch/index.tsx | 40 + .../__snapshots__/index.stories.tsx.snap | 54 + src/components/TextArea/index.css | 60 + src/components/TextArea/index.stories.tsx | 62 + src/components/TextArea/index.tsx | 37 + .../__snapshots__/index.stories.tsx.snap | 99 + src/components/TextInput/index.css | 80 + src/components/TextInput/index.stories.tsx | 112 + src/components/TextInput/index.tsx | 65 + .../__snapshots__/index.stories.tsx.snap | 23 + src/components/Toast/index.css | 58 + src/components/Toast/index.stories.tsx | 45 + src/components/Toast/index.tsx | 38 + src/components/Tooltip/TooltipProvider.tsx | 5 + .../__snapshots__/index.stories.tsx.snap | 44 + src/components/Tooltip/index.css | 13 + src/components/Tooltip/index.stories.tsx | 55 + src/components/Tooltip/index.tsx | 65 + src/components/TreeView/TreeViewItem.tsx | 136 + .../__snapshots__/index.stories.tsx.snap | 206 + src/components/TreeView/index.css | 71 + src/components/TreeView/index.stories.tsx | 416 + src/components/TreeView/index.tsx | 108 + src/components/TreeView/lib/DragContext.ts | 9 + src/components/TreeView/lib/TreeContext.ts | 8 + .../TreeView/lib/createWindowDragHandler.ts | 31 + .../TreeView/lib/defaultIndicatorUpdate.ts | 31 + src/components/TreeView/lib/inChildren.ts | 11 + .../TreeView/lib/useOverlayDragHandler.tsx | 60 + .../TreeView/types/IHandleIndicatorUpdate.ts | 8 + src/components/TreeView/types/OrderType.ts | 5 + src/components/TreeView/types/RenderProps.ts | 8 + src/docs/Colors/Colors.mdx | 5 + src/docs/Colors/Colors.tsx | 134 + src/docs/README.css | 30 + src/docs/README.tsx | 278 + src/global.css | 74 + src/index.ts | 50 + src/styles/alpha-checker-board.css | 14 + src/types/CustomJSXElement.ts | 6 + src/types/ITree.ts | 4 + src/types/Pos.ts | 5 + src/types/index.ts | 2 + src/utils/classNames.ts | 3 + src/utils/colors/blendColors.ts | 13 + src/utils/colors/chooseHigherContrast.ts | 16 + src/utils/colors/componentToHex.ts | 4 + src/utils/colors/const.ts | 5 + src/utils/colors/getContrast.ts | 10 + src/utils/colors/getHighContrast.ts | 7 + src/utils/colors/getLuminance.ts | 12 + src/utils/colors/hexToHsv.test.ts | 15 + src/utils/colors/hexToHsv.ts | 8 + src/utils/colors/hexToRgba.test.ts | 15 + src/utils/colors/hexToRgba.ts | 35 + src/utils/colors/hsvToHex.ts | 8 + src/utils/colors/hsvToRgb.ts | 60 + src/utils/colors/hsvaToRgba.ts | 6 + src/utils/colors/index.ts | 25 + src/utils/colors/isValidColor.ts | 5 + src/utils/colors/isValidHex.ts | 8 + src/utils/colors/isValidHex6.ts | 3 + src/utils/colors/rgbToCss.ts | 5 + src/utils/colors/rgbToHex.ts | 6 + src/utils/colors/rgbToHsv.test.ts | 18 + src/utils/colors/rgbToHsv.ts | 44 + src/utils/colors/rgbaArrayToRgba.ts | 11 + src/utils/colors/rgbaToCss.ts | 5 + src/utils/colors/srgbToLinear.ts | 7 + src/utils/colors/types/HSV.ts | 5 + src/utils/colors/types/HSVA.ts | 6 + src/utils/colors/types/RGB.ts | 5 + src/utils/colors/types/RGBA.ts | 5 + src/utils/colors/types/RGBAArray.ts | 1 + src/utils/colors/types/index.ts | 5 + src/utils/colors/useHighContrastColor.ts | 15 + src/utils/index.ts | 6 + src/utils/interactions/createDragHandler.ts | 73 + .../interactions/createKeyDownUpHandler.ts | 24 + src/utils/interactions/index.ts | 7 + src/utils/interactions/useAddEventListener.ts | 18 + src/utils/interactions/useKeyDownStartEnd.ts | 26 + src/utils/interactions/useNativeOnChange.ts | 19 + .../interactions/useRectResizeObserver.ts | 24 + .../interactions/useTouchStartPrevent.ts | 32 + src/utils/math/clamp.ts | 3 + src/utils/math/degToRad.ts | 3 + src/utils/math/index.ts | 6 + src/utils/math/radToDeg.ts | 3 + src/utils/math/rotateVector.ts | 12 + src/utils/math/scaleVector.ts | 8 + src/utils/math/types/Sign.ts | 1 + src/utils/math/types/Vector2.ts | 8 + src/utils/math/types/index.ts | 2 + src/utils/mergeRefs.ts | 15 + src/utils/px.ts | 3 + tsconfig.ci.json | 7 + tsconfig.json | 25 + tsup.config.ts | 10 + 272 files changed, 26604 insertions(+) create mode 100644 .github/workflows/publish.yaml create mode 100644 .github/workflows/storybook.yaml create mode 100644 .github/workflows/test.yaml create mode 100644 .gitignore create mode 100644 .node-version create mode 100644 .storybook/@types/declarations.d.ts create mode 100644 .storybook/DocumentationTemplate.mdx create mode 100644 .storybook/main.ts create mode 100644 .storybook/preview.tsx create mode 100644 .storybook/storybook.css create mode 100644 .storybook/test-runner.ts create mode 100644 biome.json create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/README.mdx create mode 100644 src/__stories__/Icon.tsx create mode 100644 src/__stories__/Panel.tsx create mode 100644 src/__stories__/Root.tsx create mode 100644 src/__stories__/ShortcutListItem.tsx create mode 100644 src/__stories__/stories.css create mode 100644 src/components/AngleInput/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/AngleInput/index.css create mode 100644 src/components/AngleInput/index.stories.tsx create mode 100644 src/components/AngleInput/index.tsx create mode 100644 src/components/Button/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Button/index.css create mode 100644 src/components/Button/index.stories.tsx create mode 100644 src/components/Button/index.tsx create mode 100644 src/components/CanvasView/View.ts create mode 100644 src/components/CanvasView/ViewMode.ts create mode 100644 src/components/CanvasView/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/CanvasView/index.css create mode 100644 src/components/CanvasView/index.stories.tsx create mode 100644 src/components/CanvasView/index.tsx create mode 100644 src/components/Checkbox/CheckSVG.tsx create mode 100644 src/components/Checkbox/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Checkbox/index.css create mode 100644 src/components/Checkbox/index.stories.tsx create mode 100644 src/components/Checkbox/index.tsx create mode 100644 src/components/Circle/index.css create mode 100644 src/components/Circle/index.tsx create mode 100644 src/components/ColorInput/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/ColorInput/index.css create mode 100644 src/components/ColorInput/index.stories.tsx create mode 100644 src/components/ColorInput/index.tsx create mode 100644 src/components/ColorLoupe/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/ColorLoupe/index.stories.tsx create mode 100644 src/components/ColorLoupe/index.tsx create mode 100644 src/components/ColorPickerCircle/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/ColorPickerCircle/index.css create mode 100644 src/components/ColorPickerCircle/index.stories.tsx create mode 100644 src/components/ColorPickerCircle/index.tsx create mode 100644 src/components/ColorPickerRect/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/ColorPickerRect/index.css create mode 100644 src/components/ColorPickerRect/index.stories.tsx create mode 100644 src/components/ColorPickerRect/index.tsx create mode 100644 src/components/ColorSlider/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/ColorSlider/index.css create mode 100644 src/components/ColorSlider/index.stories.tsx create mode 100644 src/components/ColorSlider/index.tsx create mode 100644 src/components/ContextMenu/ContextMenuItem.tsx create mode 100644 src/components/ContextMenu/ContextMenuSeparator.tsx create mode 100644 src/components/ContextMenu/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/ContextMenu/index.css create mode 100644 src/components/ContextMenu/index.stories.tsx create mode 100644 src/components/ContextMenu/index.tsx create mode 100644 src/components/CubicControls/CubicCommand.ts create mode 100644 src/components/CubicControls/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/CubicControls/index.css create mode 100644 src/components/CubicControls/index.stories.tsx create mode 100644 src/components/CubicControls/index.tsx create mode 100644 src/components/DropdownMenu/DropdownMenuItem.tsx create mode 100644 src/components/DropdownMenu/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/DropdownMenu/index.stories.tsx create mode 100644 src/components/DropdownMenu/index.tsx create mode 100644 src/components/FloatBox/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/FloatBox/index.css create mode 100644 src/components/FloatBox/index.stories.tsx create mode 100644 src/components/FloatBox/index.tsx create mode 100644 src/components/Grid/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Grid/index.css create mode 100644 src/components/Grid/index.stories.tsx create mode 100644 src/components/Grid/index.tsx create mode 100644 src/components/HueCircle/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/HueCircle/index.css create mode 100644 src/components/HueCircle/index.stories.tsx create mode 100644 src/components/HueCircle/index.tsx create mode 100644 src/components/IconButton/IconButtonGroup.tsx create mode 100644 src/components/IconButton/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/IconButton/index.css create mode 100644 src/components/IconButton/index.stories.tsx create mode 100644 src/components/IconButton/index.tsx create mode 100644 src/components/Line/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Line/index.stories.tsx create mode 100644 src/components/Line/index.tsx create mode 100644 src/components/ListItem/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/ListItem/index.css create mode 100644 src/components/ListItem/index.stories.tsx create mode 100644 src/components/ListItem/index.tsx create mode 100644 src/components/MenuBarButton/MenuBar.tsx create mode 100644 src/components/MenuBarButton/MenuBarItem.tsx create mode 100644 src/components/MenuBarButton/MenuBarSeparator.tsx create mode 100644 src/components/MenuBarButton/MenuBarSubButton.tsx create mode 100644 src/components/MenuBarButton/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/MenuBarButton/index.css create mode 100644 src/components/MenuBarButton/index.stories.tsx create mode 100644 src/components/MenuBarButton/index.tsx create mode 100644 src/components/Modal/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Modal/index.css create mode 100644 src/components/Modal/index.stories.tsx create mode 100644 src/components/Modal/index.tsx create mode 100644 src/components/Path/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Path/index.stories.tsx create mode 100644 src/components/Path/index.tsx create mode 100644 src/components/Popover/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Popover/index.css create mode 100644 src/components/Popover/index.stories.tsx create mode 100644 src/components/Popover/index.tsx create mode 100644 src/components/RectGizmo/AngleNob.tsx create mode 100644 src/components/RectGizmo/MovableRect.tsx create mode 100644 src/components/RectGizmo/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/RectGizmo/index.css create mode 100644 src/components/RectGizmo/index.stories.tsx create mode 100644 src/components/RectGizmo/index.tsx create mode 100644 src/components/RectGizmo/lib/createCursorStyleBase64SVGUrl.ts create mode 100644 src/components/RectGizmo/lib/createHorizontalResizeSVGString.ts create mode 100644 src/components/RectGizmo/lib/createResizeHandler.ts create mode 100644 src/components/RectGizmo/lib/createRotateHorizontalResize.ts create mode 100644 src/components/RectGizmo/lib/positionSignMap.ts create mode 100644 src/components/RectGizmo/lib/proportionalResize.ts create mode 100644 src/components/Ruler/TimeText.tsx create mode 100644 src/components/Ruler/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Ruler/defaultRenderText.ts create mode 100644 src/components/Ruler/defaultSteps.ts create mode 100644 src/components/Ruler/getStepPixel.ts create mode 100644 src/components/Ruler/index.css create mode 100644 src/components/Ruler/index.stories.tsx create mode 100644 src/components/Ruler/index.tsx create mode 100644 src/components/SVPicker/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/SVPicker/index.css create mode 100644 src/components/SVPicker/index.stories.tsx create mode 100644 src/components/SVPicker/index.tsx create mode 100644 src/components/SVPicker/lib/SVCanvas.tsx create mode 100644 src/components/SVPicker/lib/drawSV.tsx create mode 100644 src/components/Select/SelectItem.tsx create mode 100644 src/components/Select/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Select/index.css create mode 100644 src/components/Select/index.stories.tsx create mode 100644 src/components/Select/index.tsx create mode 100644 src/components/SelectRect/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/SelectRect/index.stories.tsx create mode 100644 src/components/SelectRect/index.tsx create mode 100644 src/components/Slider/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Slider/index.css create mode 100644 src/components/Slider/index.stories.tsx create mode 100644 src/components/Slider/index.tsx create mode 100644 src/components/SliderNumberField/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/SliderNumberField/index.css create mode 100644 src/components/SliderNumberField/index.stories.tsx create mode 100644 src/components/SliderNumberField/index.tsx create mode 100644 src/components/SliderNumberField/lib/inputEval.test.ts create mode 100644 src/components/SliderNumberField/lib/inputEval.ts create mode 100644 src/components/SliderNumberField/lib/isEvalSafe.test.ts create mode 100644 src/components/SliderNumberField/lib/isEvalSafe.ts create mode 100644 src/components/SliderNumberField/lib/parseCursorStyle.ts create mode 100644 src/components/SplitPane/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/SplitPane/index.css create mode 100644 src/components/SplitPane/index.stories.tsx create mode 100644 src/components/SplitPane/index.tsx create mode 100644 src/components/SplitPane/useSplitPane.ts create mode 100644 src/components/Switch/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Switch/index.css create mode 100644 src/components/Switch/index.stories.tsx create mode 100644 src/components/Switch/index.tsx create mode 100644 src/components/TextArea/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/TextArea/index.css create mode 100644 src/components/TextArea/index.stories.tsx create mode 100644 src/components/TextArea/index.tsx create mode 100644 src/components/TextInput/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/TextInput/index.css create mode 100644 src/components/TextInput/index.stories.tsx create mode 100644 src/components/TextInput/index.tsx create mode 100644 src/components/Toast/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Toast/index.css create mode 100644 src/components/Toast/index.stories.tsx create mode 100644 src/components/Toast/index.tsx create mode 100644 src/components/Tooltip/TooltipProvider.tsx create mode 100644 src/components/Tooltip/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/Tooltip/index.css create mode 100644 src/components/Tooltip/index.stories.tsx create mode 100644 src/components/Tooltip/index.tsx create mode 100644 src/components/TreeView/TreeViewItem.tsx create mode 100644 src/components/TreeView/__snapshots__/index.stories.tsx.snap create mode 100644 src/components/TreeView/index.css create mode 100644 src/components/TreeView/index.stories.tsx create mode 100644 src/components/TreeView/index.tsx create mode 100644 src/components/TreeView/lib/DragContext.ts create mode 100644 src/components/TreeView/lib/TreeContext.ts create mode 100644 src/components/TreeView/lib/createWindowDragHandler.ts create mode 100644 src/components/TreeView/lib/defaultIndicatorUpdate.ts create mode 100644 src/components/TreeView/lib/inChildren.ts create mode 100644 src/components/TreeView/lib/useOverlayDragHandler.tsx create mode 100644 src/components/TreeView/types/IHandleIndicatorUpdate.ts create mode 100644 src/components/TreeView/types/OrderType.ts create mode 100644 src/components/TreeView/types/RenderProps.ts create mode 100644 src/docs/Colors/Colors.mdx create mode 100644 src/docs/Colors/Colors.tsx create mode 100644 src/docs/README.css create mode 100644 src/docs/README.tsx create mode 100644 src/global.css create mode 100644 src/index.ts create mode 100644 src/styles/alpha-checker-board.css create mode 100644 src/types/CustomJSXElement.ts create mode 100644 src/types/ITree.ts create mode 100644 src/types/Pos.ts create mode 100644 src/types/index.ts create mode 100644 src/utils/classNames.ts create mode 100644 src/utils/colors/blendColors.ts create mode 100644 src/utils/colors/chooseHigherContrast.ts create mode 100644 src/utils/colors/componentToHex.ts create mode 100644 src/utils/colors/const.ts create mode 100644 src/utils/colors/getContrast.ts create mode 100644 src/utils/colors/getHighContrast.ts create mode 100644 src/utils/colors/getLuminance.ts create mode 100644 src/utils/colors/hexToHsv.test.ts create mode 100644 src/utils/colors/hexToHsv.ts create mode 100644 src/utils/colors/hexToRgba.test.ts create mode 100644 src/utils/colors/hexToRgba.ts create mode 100644 src/utils/colors/hsvToHex.ts create mode 100644 src/utils/colors/hsvToRgb.ts create mode 100644 src/utils/colors/hsvaToRgba.ts create mode 100644 src/utils/colors/index.ts create mode 100644 src/utils/colors/isValidColor.ts create mode 100644 src/utils/colors/isValidHex.ts create mode 100644 src/utils/colors/isValidHex6.ts create mode 100644 src/utils/colors/rgbToCss.ts create mode 100644 src/utils/colors/rgbToHex.ts create mode 100644 src/utils/colors/rgbToHsv.test.ts create mode 100644 src/utils/colors/rgbToHsv.ts create mode 100644 src/utils/colors/rgbaArrayToRgba.ts create mode 100644 src/utils/colors/rgbaToCss.ts create mode 100644 src/utils/colors/srgbToLinear.ts create mode 100644 src/utils/colors/types/HSV.ts create mode 100644 src/utils/colors/types/HSVA.ts create mode 100644 src/utils/colors/types/RGB.ts create mode 100644 src/utils/colors/types/RGBA.ts create mode 100644 src/utils/colors/types/RGBAArray.ts create mode 100644 src/utils/colors/types/index.ts create mode 100644 src/utils/colors/useHighContrastColor.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/interactions/createDragHandler.ts create mode 100644 src/utils/interactions/createKeyDownUpHandler.ts create mode 100644 src/utils/interactions/index.ts create mode 100644 src/utils/interactions/useAddEventListener.ts create mode 100644 src/utils/interactions/useKeyDownStartEnd.ts create mode 100644 src/utils/interactions/useNativeOnChange.ts create mode 100644 src/utils/interactions/useRectResizeObserver.ts create mode 100644 src/utils/interactions/useTouchStartPrevent.ts create mode 100644 src/utils/math/clamp.ts create mode 100644 src/utils/math/degToRad.ts create mode 100644 src/utils/math/index.ts create mode 100644 src/utils/math/radToDeg.ts create mode 100644 src/utils/math/rotateVector.ts create mode 100644 src/utils/math/scaleVector.ts create mode 100644 src/utils/math/types/Sign.ts create mode 100644 src/utils/math/types/Vector2.ts create mode 100644 src/utils/math/types/index.ts create mode 100644 src/utils/mergeRefs.ts create mode 100644 src/utils/px.ts create mode 100644 tsconfig.ci.json create mode 100644 tsconfig.json create mode 100644 tsup.config.ts diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..40411e0 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,26 @@ +name: Publish +on: + release: + types: [published] +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 + with: + version: 8 + - uses: actions/setup-node@v3 + with: + node-version: "20.11.1" + registry-url: "https://registry.npmjs.org" + - run: pnpm install + - run: pnpm typecheck + - run: pnpm biome:check + - run: pnpm test + - run: npx playwright install --with-deps + - run: pnpm storybook:test:ci + - run: pnpm run build + - run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/storybook.yaml b/.github/workflows/storybook.yaml new file mode 100644 index 0000000..0974992 --- /dev/null +++ b/.github/workflows/storybook.yaml @@ -0,0 +1,25 @@ +name: Storybook +on: + push: + branches: + - main +env: + cache-version: v1 +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v3 + with: + version: 8 + - uses: actions/setup-node@v3 + with: + node-version: "20.11.1" + registry-url: "https://registry.npmjs.org" + - run: pnpm install + - run: npm run storybook:build + - uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./storybook-static diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..8ca98ad --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,20 @@ +name: Test +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 + with: + version: 8 + - uses: actions/setup-node@v3 + with: + node-version: "20.11.1" + registry-url: "https://registry.npmjs.org" + - run: pnpm install + - run: pnpm typecheck + - run: pnpm biome:check + - run: pnpm test + - run: npx playwright install --with-deps + - run: pnpm storybook:test:ci diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3be9c32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.vscode/* +*.local +*.log +dist +node_modules +storybook-static \ No newline at end of file diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..726a201 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20.11.1 \ No newline at end of file diff --git a/.storybook/@types/declarations.d.ts b/.storybook/@types/declarations.d.ts new file mode 100644 index 0000000..aa32d84 --- /dev/null +++ b/.storybook/@types/declarations.d.ts @@ -0,0 +1,5 @@ +declare module "*.mdx" { + let MDXComponent: (props) => JSX.Element; + export default MDXComponent; + } + \ No newline at end of file diff --git a/.storybook/DocumentationTemplate.mdx b/.storybook/DocumentationTemplate.mdx new file mode 100644 index 0000000..86ef999 --- /dev/null +++ b/.storybook/DocumentationTemplate.mdx @@ -0,0 +1,22 @@ + +import { Meta } from "@storybook/blocks"; + +import { + Title, + Primary, + Stories, + Description, + ArgTypes, +} from "@storybook/blocks"; + + + + + +<Description /> + +<Primary /> + +<ArgTypes /> + +<Stories includePrimary={false} /> diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000..dbafd24 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,21 @@ +import type { StorybookConfig } from "@storybook/react-vite"; + +const config: StorybookConfig = { + stories: ["../src/**/*.mdx", "../src/**/*.stories.tsx"], + addons: [ + "@storybook/addon-links", + "@storybook/addon-essentials", + "@storybook/addon-onboarding", + "@storybook/addon-interactions", + "@storybook/addon-mdx-gfm", + ], + framework: { + name: "@storybook/react-vite", + options: {}, + }, + docs: { + autodocs: true, + defaultName: "Documentation", + }, +}; +export default config; diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 0000000..858cba4 --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,55 @@ +import type { Decorator, Preview } from "@storybook/react"; +import DocumentationTemplate from "./DocumentationTemplate.mdx"; +import { useEffect } from "react"; +import React from "react"; +import { themes } from "@storybook/theming"; + +import "../src/global.css"; +import "./storybook.css"; + +const preview: Preview = { + parameters: { + actions: { argTypesRegex: "^on[A-Z].*" }, + layout: "centered", + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + docs: { + page: DocumentationTemplate, + theme: themes.dark, + }, + }, +}; + +export const withTheme: Decorator = (StoryFn, context) => { + const theme = context.globals.theme; + + useEffect(() => { + document.body.dataset.theme = theme; + }, [theme]); + + return <StoryFn />; +}; + +export const decorators = [withTheme]; + +export const globalTypes = { + theme: { + name: "Theme", + description: "Global theme for components", + defaultValue: "light", + toolbar: { + icon: "sun", + items: [ + { value: "light", icon: "sun", title: "light" }, + { value: "dark", icon: "moon", title: "dark" }, + ], + showName: true, + }, + }, +}; + +export default preview; diff --git a/.storybook/storybook.css b/.storybook/storybook.css new file mode 100644 index 0000000..a8a7e76 --- /dev/null +++ b/.storybook/storybook.css @@ -0,0 +1,27 @@ +@import url("https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"); +@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap"); + +html { + font-family: "Noto Sans JP", ui-sans-serif, system-ui, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} + +.material-symbols-outlined { + font-variation-settings: + "FILL" 0, + "wght" 400, + "GRAD" 0, + "opsz" 24; +} + +.material-symbols-outlined[data-filled] { + font-variation-settings: + "FILL" 1, + "wght" 400, + "GRAD" 0, + "opsz" 24; +} + +.docs-story { + background-color: var(--cmpui-bg-color); +} diff --git a/.storybook/test-runner.ts b/.storybook/test-runner.ts new file mode 100644 index 0000000..bc2dbb0 --- /dev/null +++ b/.storybook/test-runner.ts @@ -0,0 +1,11 @@ +import type { TestRunnerConfig } from "@storybook/test-runner"; + +const config: TestRunnerConfig = { + async postVisit(page) { + const elementHandler = await page.$("#storybook-root"); + const innerHTML = await elementHandler?.innerHTML(); + expect(innerHTML).toMatchSnapshot(); + }, +}; + +export default config; diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..0e97fc1 --- /dev/null +++ b/biome.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.4.1/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + + "complexity": { + "noForEach": "off" + }, + "suspicious": { + "noArrayIndexKey": "off" + }, + "a11y": { + "noNoninteractiveTabindex": "off", + "noSvgWithoutTitle": "off", + "useKeyWithClickEvents": "off", + "useKeyWithMouseEvents": "off" + } + } + }, + "formatter": { + "indentWidth": 2, + "indentStyle": "space" + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..bc2c3ad --- /dev/null +++ b/package.json @@ -0,0 +1,68 @@ +{ + "name": "cmpui", + "version": "1.0.0-alpha.0", + "description": "CmpUI is a component library designed for creating complex GUI applications in web browsers.", + "main": "dist/index.mjs", + "types": "dist/index.d.mts", + "scripts": { + "typecheck": "tsc -p tsconfig.ci.json", + "test:watch": "vitest", + "test": "vitest run", + "biome:check": "biome check src", + "build": "tsup", + "storybook": "storybook dev -p 6006", + "storybook:build": "storybook build", + "storybook:test": "test-storybook", + "storybook:test:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"pnpm storybook:build && npx http-server storybook-static --port 6006 --silent\" \"wait-on http://127.0.0.1:6006 && pnpm storybook:test\"" + }, + "dependencies": { + "@radix-ui/react-context-menu": "^2.1.5", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-menubar": "^1.0.4", + "@radix-ui/react-popover": "^1.0.7", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-tooltip": "^1.0.7" + }, + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@biomejs/biome": "1.4.1", + "@playwright/test": "^1.41.2", + "@storybook/addon-essentials": "^8.0.0-beta.3", + "@storybook/addon-interactions": "^8.0.0-beta.3", + "@storybook/addon-links": "^8.0.0-beta.3", + "@storybook/addon-mdx-gfm": "^8.0.0-beta.3", + "@storybook/addon-onboarding": "^1.0.8", + "@storybook/addon-themes": "^8.0.0-beta.3", + "@storybook/blocks": "^8.0.0-beta.3", + "@storybook/react": "^8.0.0-beta.3", + "@storybook/react-vite": "^8.0.0-beta.3", + "@storybook/test": "^8.0.0-beta.3", + "@storybook/test-runner": "^0.16.0", + "@storybook/theming": "^8.0.0-beta.3", + "@types/jest": "^29.5.11", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "concurrently": "^8.2.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "storybook": "^8.0.0-beta.3", + "tsup": "^8.0.1", + "typescript": "^5.2.2", + "vitest": "^1.1.0", + "wait-on": "^7.2.0" + }, + "keywords": [ + "react", + "typescript", + "components", + "ui", + "gui" + ], + "author": "toshusai", + "license": "MIT" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..e694919 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,10925 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@radix-ui/react-context-menu': + specifier: ^2.1.5 + version: 2.1.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-dialog': + specifier: ^1.0.5 + version: 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-dropdown-menu': + specifier: ^2.0.6 + version: 2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-menubar': + specifier: ^1.0.4 + version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-popover': + specifier: ^1.0.7 + version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-select': + specifier: ^2.0.0 + version: 2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-toast': + specifier: ^1.1.5 + version: 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-tooltip': + specifier: ^1.0.7 + version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + +devDependencies: + '@biomejs/biome': + specifier: 1.4.1 + version: 1.4.1 + '@playwright/test': + specifier: ^1.41.2 + version: 1.41.2 + '@storybook/addon-essentials': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-interactions': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3 + '@storybook/addon-links': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3(react@18.2.0) + '@storybook/addon-mdx-gfm': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3 + '@storybook/addon-onboarding': + specifier: ^1.0.8 + version: 1.0.10(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-themes': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3 + '@storybook/blocks': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@storybook/react': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) + '@storybook/react-vite': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)(vite@5.0.10) + '@storybook/test': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3(@types/jest@29.5.11)(jest@29.7.0)(vitest@1.1.0) + '@storybook/test-runner': + specifier: ^0.16.0 + version: 0.16.0 + '@storybook/theming': + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@types/jest': + specifier: ^29.5.11 + version: 29.5.11 + '@types/react': + specifier: ^18.2.37 + version: 18.2.46 + '@types/react-dom': + specifier: ^18.2.15 + version: 18.2.18 + concurrently: + specifier: ^8.2.2 + version: 8.2.2 + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + storybook: + specifier: ^8.0.0-beta.3 + version: 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + tsup: + specifier: ^8.0.1 + version: 8.0.1(@swc/core@1.3.102)(typescript@5.3.3) + typescript: + specifier: ^5.2.2 + version: 5.3.3 + vitest: + specifier: ^1.1.0 + version: 1.1.0 + wait-on: + specifier: ^7.2.0 + version: 7.2.0 + +packages: + + /@adobe/css-tools@4.3.2: + resolution: {integrity: sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==} + dev: true + + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.20 + dev: true + + /@aw-web-design/x-default-browser@1.4.126: + resolution: {integrity: sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug==} + hasBin: true + dependencies: + default-browser-id: 3.0.0 + dev: true + + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + dev: true + + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.23.7: + resolution: {integrity: sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) + '@babel/helpers': 7.23.7 + '@babel/parser': 7.23.6 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.23.6: + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.20 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: + resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.22.2 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-create-class-features-plugin@7.23.7(@babel/core@7.23.7): + resolution: {integrity: sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.7): + resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + semver: 6.3.1 + dev: true + + /@babel/helper-define-polyfill-provider@0.4.4(@babel/core@7.23.7): + resolution: {integrity: sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-member-expression-to-functions@7.23.0: + resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/helper-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.7): + resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-wrap-function': 7.22.20 + dev: true + + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.7): + resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + dev: true + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function@7.22.20: + resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.23.0 + '@babel/template': 7.22.15 + '@babel/types': 7.23.6 + dev: true + + /@babel/helpers@7.23.7: + resolution: {integrity: sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.7) + dev: true + + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7(@babel/core@7.23.7): + resolution: {integrity: sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.7): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.7): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.7): + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.7): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.7): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.7): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.7): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-flow@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.7): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.7): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.7): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.7): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.7): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.7): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.7): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.7): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.7): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.7): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.7): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-async-generator-functions@7.23.7(@babel/core@7.23.7): + resolution: {integrity: sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.7) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-classes@7.23.5(@babel/core@7.23.7): + resolution: {integrity: sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.7) + '@babel/helper-split-export-declaration': 7.22.6 + globals: 11.12.0 + dev: true + + /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.15 + dev: true + + /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-for-of@7.23.6(@babel/core@7.23.7): + resolution: {integrity: sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + dev: true + + /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-literals@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-systemjs@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.7): + resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.7 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.23.7): + resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + regenerator-transform: 0.15.2 + dev: true + + /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-spread@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + dev: true + + /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.23.7): + resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.7) + dev: true + + /@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/preset-env@7.23.7(@babel/core@7.23.7): + resolution: {integrity: sha512-SY27X/GtTz/L4UryMNJ6p4fH4nsgWbz84y9FE0bQeWJP6O5BhgVCt53CotQKHCOeXJel8VyhlhujhlltKms/CA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.7 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.7(@babel/core@7.23.7) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.7) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.7) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.7) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.7) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.7) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.7) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.7) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.7) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.7) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.7) + '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-async-generator-functions': 7.23.7(@babel/core@7.23.7) + '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.23.7) + '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.23.7) + '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-modules-systemjs': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.7) + '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.23.7) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.7) + babel-plugin-polyfill-corejs2: 0.4.7(@babel/core@7.23.7) + babel-plugin-polyfill-corejs3: 0.8.7(@babel/core@7.23.7) + babel-plugin-polyfill-regenerator: 0.5.4(@babel/core@7.23.7) + core-js-compat: 3.35.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-flow@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.23.7) + dev: true + + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.7): + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/types': 7.23.6 + esutils: 2.0.3 + dev: true + + /@babel/preset-typescript@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.23.7) + dev: true + + /@babel/register@7.23.7(@babel/core@7.23.7): + resolution: {integrity: sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + clone-deep: 4.0.1 + find-cache-dir: 2.1.0 + make-dir: 2.1.0 + pirates: 4.0.6 + source-map-support: 0.5.21 + dev: true + + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: true + + /@babel/runtime@7.23.7: + resolution: {integrity: sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + dev: true + + /@babel/traverse@7.23.7: + resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.23.6: + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + + /@base2/pretty-print-object@1.0.1: + resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==} + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@biomejs/biome@1.4.1: + resolution: {integrity: sha512-JccVAwPbhi37pdxbAGmaOBjUTKEwEjWAhl7rKkVVuXHo4MLASXJ5HR8BTgrImi4/7rTBsGz1tgVD1Kwv1CHGRg==} + engines: {node: '>=14.*'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.4.1 + '@biomejs/cli-darwin-x64': 1.4.1 + '@biomejs/cli-linux-arm64': 1.4.1 + '@biomejs/cli-linux-x64': 1.4.1 + '@biomejs/cli-win32-arm64': 1.4.1 + '@biomejs/cli-win32-x64': 1.4.1 + dev: true + + /@biomejs/cli-darwin-arm64@1.4.1: + resolution: {integrity: sha512-PZWy2Idndqux38p6AXSDQM2ldRAWi32bvb7bMbTN0ALzpWYMYnxd71ornatumSSJYoNhKmxzDLq+jct7nZJ79w==} + engines: {node: '>=14.*'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-darwin-x64@1.4.1: + resolution: {integrity: sha512-soj3BWhnsM1M2JlzR09cibUzG1owJqetwj/Oo7yg0foijo9lNH9XWXZfJBYDKgW/6Fomn+CC2EcUS+hisQzt9g==} + engines: {node: '>=14.*'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-linux-arm64@1.4.1: + resolution: {integrity: sha512-YIZqfJUg4F+fPsBTXxgD7EU2E5OAYbmYSl/snf4PevwfQCWE/omOFZv+NnIQmjYj9I7ParDgcJvanoA3/kO0JQ==} + engines: {node: '>=14.*'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-linux-x64@1.4.1: + resolution: {integrity: sha512-9YOZw3qBd/KUj63A6Hn2zZgzGb2nbESM0qNmeMXgmqinVKM//uc4OgY5TuKITuGjMSvcVxxd4dX1IzYjV9qvNQ==} + engines: {node: '>=14.*'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-win32-arm64@1.4.1: + resolution: {integrity: sha512-nWQbvkNKxYn/kCQ0yVF8kCaS3VzaGvtFSmItXiMknU4521LDjJ7tNWH12Gol+pIslrCbd4E1LhJa0a3ThRsBVg==} + engines: {node: '>=14.*'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@biomejs/cli-win32-x64@1.4.1: + resolution: {integrity: sha512-88fR2CQxQ4YLs2BUDuywWYQpUKgU3A3sTezANFc/4LGKQFFLV2yX+F7QAdZVkMHfA+RD9Xg178HomM/6mnTNPA==} + engines: {node: '>=14.*'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@colors/colors@1.5.0: + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + requiresBuild: true + dev: true + optional: true + + /@discoveryjs/json-ext@0.5.7: + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + dev: true + + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0): + resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: true + + /@esbuild/aix-ppc64@0.19.11: + resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.19.11: + resolution: {integrity: sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.19.11: + resolution: {integrity: sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.19.11: + resolution: {integrity: sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.19.11: + resolution: {integrity: sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.19.11: + resolution: {integrity: sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.19.11: + resolution: {integrity: sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.19.11: + resolution: {integrity: sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.19.11: + resolution: {integrity: sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.19.11: + resolution: {integrity: sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.19.11: + resolution: {integrity: sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.19.11: + resolution: {integrity: sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.19.11: + resolution: {integrity: sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.19.11: + resolution: {integrity: sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.19.11: + resolution: {integrity: sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.19.11: + resolution: {integrity: sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.19.11: + resolution: {integrity: sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.19.11: + resolution: {integrity: sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.19.11: + resolution: {integrity: sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.19.11: + resolution: {integrity: sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.19.11: + resolution: {integrity: sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.19.11: + resolution: {integrity: sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.19.11: + resolution: {integrity: sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@fal-works/esbuild-plugin-global-externals@2.1.2: + resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} + dev: true + + /@floating-ui/core@1.5.2: + resolution: {integrity: sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A==} + dependencies: + '@floating-ui/utils': 0.1.6 + dev: false + + /@floating-ui/dom@1.5.3: + resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==} + dependencies: + '@floating-ui/core': 1.5.2 + '@floating-ui/utils': 0.1.6 + dev: false + + /@floating-ui/react-dom@2.0.4(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.5.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@floating-ui/utils@0.1.6: + resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==} + dev: false + + /@hapi/hoek@9.3.0: + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + dev: true + + /@hapi/topo@5.1.0: + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + dependencies: + '@hapi/hoek': 9.3.0 + dev: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console@29.7.0: + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + dev: true + + /@jest/core@29.7.0: + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.10.6) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /@jest/create-cache-key-function@27.5.1: + resolution: {integrity: sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + dev: true + + /@jest/environment@29.7.0: + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + jest-mock: 29.7.0 + dev: true + + /@jest/expect-utils@29.7.0: + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + dev: true + + /@jest/expect@29.7.0: + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/fake-timers@29.7.0: + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.10.6 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + + /@jest/globals@29.7.0: + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/reporters@29.7.0: + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.20 + '@types/node': 20.10.6 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.1 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + dev: true + + /@jest/source-map@29.6.3: + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.20 + callsites: 3.1.0 + graceful-fs: 4.2.11 + dev: true + + /@jest/test-result@29.7.0: + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + dev: true + + /@jest/test-sequencer@29.7.0: + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + dev: true + + /@jest/transform@29.7.0: + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.23.7 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.20 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.5 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types@27.5.1: + resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.10.6 + '@types/yargs': 16.0.9 + chalk: 4.1.2 + dev: true + + /@jest/types@29.6.3: + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.10.6 + '@types/yargs': 17.0.32 + chalk: 4.1.2 + dev: true + + /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.3.3)(vite@5.0.10): + resolution: {integrity: sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==} + peerDependencies: + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + glob: 7.2.3 + glob-promise: 4.2.2(glob@7.2.3) + magic-string: 0.27.0 + react-docgen-typescript: 2.2.2(typescript@5.3.3) + typescript: 5.3.3 + vite: 5.0.10 + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.20 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.20: + resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@mdx-js/react@3.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + dependencies: + '@types/mdx': 2.0.10 + '@types/react': 18.2.46 + react: 18.2.0 + dev: true + + /@ndelangen/get-tarball@3.0.9: + resolution: {integrity: sha512-9JKTEik4vq+yGosHYhZ1tiH/3WpUS0Nh0kej4Agndhox8pAdWhEx5knFVRcb/ya9knCRCs1rPxNrSXTDdfVqpA==} + dependencies: + gunzip-maybe: 1.4.2 + pump: 3.0.0 + tar-fs: 2.1.1 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.16.0 + dev: true + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + + /@playwright/test@1.41.2: + resolution: {integrity: sha512-qQB9h7KbibJzrDpkXkYvsmiDJK14FULCCZgEcoe2AvFAS64oCirWTwzTlAYEbKaRxWs5TFesE1Na6izMv3HfGg==} + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright: 1.41.2 + dev: true + + /@radix-ui/number@1.0.1: + resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} + dependencies: + '@babel/runtime': 7.23.7 + dev: false + + /@radix-ui/primitive@1.0.1: + resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + dependencies: + '@babel/runtime': 7.23.7 + dev: false + + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@types/react': 18.2.46 + react: 18.2.0 + + /@radix-ui/react-context-menu@2.1.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-R5XaDj06Xul1KGb+WP8qiOh7tKJNz2durpLBXAGZjSVtctcRFCuEvy2gtMwRJGePwQQE5nV77gs4FwRi8T+r2g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-menu': 2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-context@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.46)(react@18.2.0) + dev: false + + /@radix-ui/react-direction@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-dropdown-menu@2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-menu': 2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-id@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-menu@2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.46)(react@18.2.0) + dev: false + + /@radix-ui/react-menubar@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-bHgUo9gayKZfaQcWSSLr++LyS0rgh+MvD89DE4fJ6TkGHvjHgPaBZf44hdka7ogOxIOdj9163J+5xL2Dn4qzzg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-menu': 2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.46)(react@18.2.0) + dev: false + + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@floating-ui/react-dom': 2.0.4(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/number': 1.0.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.46)(react@18.2.0) + dev: false + + /@radix-ui/react-slot@1.0.2(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + react: 18.2.0 + + /@radix-ui/react-toast@1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.46)(react@18.2.0) + '@types/react': 18.2.46 + react: 18.2.0 + dev: false + + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.7 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.46 + '@types/react-dom': 18.2.18 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/rect@1.0.1: + resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==} + dependencies: + '@babel/runtime': 7.23.7 + dev: false + + /@rollup/pluginutils@5.1.0: + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: true + + /@rollup/rollup-android-arm-eabi@4.9.2: + resolution: {integrity: sha512-RKzxFxBHq9ysZ83fn8Iduv3A283K7zPPYuhL/z9CQuyFrjwpErJx0h4aeb/bnJ+q29GRLgJpY66ceQ/Wcsn3wA==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.9.2: + resolution: {integrity: sha512-yZ+MUbnwf3SHNWQKJyWh88ii2HbuHCFQnAYTeeO1Nb8SyEiWASEi5dQUygt3ClHWtA9My9RQAYkjvrsZ0WK8Xg==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.9.2: + resolution: {integrity: sha512-vqJ/pAUh95FLc/G/3+xPqlSBgilPnauVf2EXOQCZzhZJCXDXt/5A8mH/OzU6iWhb3CNk5hPJrh8pqJUPldN5zw==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-x64@4.9.2: + resolution: {integrity: sha512-otPHsN5LlvedOprd3SdfrRNhOahhVBwJpepVKUN58L0RnC29vOAej1vMEaVU6DadnpjivVsNTM5eNt0CcwTahw==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.9.2: + resolution: {integrity: sha512-ewG5yJSp+zYKBYQLbd1CUA7b1lSfIdo9zJShNTyc2ZP1rcPrqyZcNlsHgs7v1zhgfdS+kW0p5frc0aVqhZCiYQ==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.9.2: + resolution: {integrity: sha512-pL6QtV26W52aCWTG1IuFV3FMPL1m4wbsRG+qijIvgFO/VBsiXJjDPE/uiMdHBAO6YcpV4KvpKtd0v3WFbaxBtg==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.9.2: + resolution: {integrity: sha512-On+cc5EpOaTwPSNetHXBuqylDW+765G/oqB9xGmWU3npEhCh8xu0xqHGUA+4xwZLqBbIZNcBlKSIYfkBm6ko7g==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.9.2: + resolution: {integrity: sha512-Wnx/IVMSZ31D/cO9HSsU46FjrPWHqtdF8+0eyZ1zIB5a6hXaZXghUKpRrC4D5DcRTZOjml2oBhXoqfGYyXKipw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.9.2: + resolution: {integrity: sha512-ym5x1cj4mUAMBummxxRkI4pG5Vht1QMsJexwGP8547TZ0sox9fCLDHw9KCH9c1FO5d9GopvkaJsBIOkTKxksdw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.9.2: + resolution: {integrity: sha512-m0hYELHGXdYx64D6IDDg/1vOJEaiV8f1G/iO+tejvRCJNSwK4jJ15e38JQy5Q6dGkn1M/9KcyEOwqmlZ2kqaZg==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.9.2: + resolution: {integrity: sha512-x1CWburlbN5JjG+juenuNa4KdedBdXLjZMp56nHFSHTOsb/MI2DYiGzLtRGHNMyydPGffGId+VgjOMrcltOksA==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.9.2: + resolution: {integrity: sha512-VVzCB5yXR1QlfsH1Xw1zdzQ4Pxuzv+CPr5qpElpKhVxlxD3CRdfubAG9mJROl6/dmj5gVYDDWk8sC+j9BI9/kQ==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.9.2: + resolution: {integrity: sha512-SYRedJi+mweatroB+6TTnJYLts0L0bosg531xnQWtklOI6dezEagx4Q0qDyvRdK+qgdA3YZpjjGuPFtxBmddBA==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@sideway/address@4.1.4: + resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==} + dependencies: + '@hapi/hoek': 9.3.0 + dev: true + + /@sideway/formula@3.0.1: + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + dev: true + + /@sideway/pinpoint@2.0.0: + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + dev: true + + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true + + /@sinonjs/commons@3.0.0: + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + dependencies: + '@sinonjs/commons': 3.0.0 + dev: true + + /@storybook/addon-actions@8.0.0-beta.3: + resolution: {integrity: sha512-PAEKJ1aI0SB3zsOb4W6Fo9ePZv5iwNkRm+EFestmiB6QYzMw8GIStkQSyv1X4YAGnMZrAMzNm9BlTcaMAoQQcQ==} + dependencies: + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/global': 5.0.0 + '@types/uuid': 9.0.7 + dequal: 2.0.3 + polished: 4.2.2 + uuid: 9.0.1 + dev: true + + /@storybook/addon-backgrounds@8.0.0-beta.3: + resolution: {integrity: sha512-kyBSowM5ZfL0WPRgWWwSEC6JhKqTIlAbHi4nD5W1f9wUCUVxk4R79RtDVAD4h7gz7Z3oDA8/4jbfD9z7g/Eh5g==} + dependencies: + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-controls@8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-6yPNI0b11SGcbp9qU6T/GTN0U+jBAFZJnWiKrTjd127TVVN4S1HPIugb4mSu8e11BzXcQ75Pwh1pq96WA5TzKg==} + dependencies: + '@storybook/blocks': 8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + lodash: 4.17.21 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + - encoding + - react + - react-dom + - supports-color + dev: true + + /@storybook/addon-docs@8.0.0-beta.3: + resolution: {integrity: sha512-RL7h7Sg0BJAddwMaj+keseBJRlOQY+OyMKQUEOgvZG7NeN5LOcwesWXI2jBsZE9a06G2CTTE00hDJ3Me0gbPkQ==} + dependencies: + '@babel/core': 7.23.7 + '@mdx-js/react': 3.0.1(@types/react@18.2.46)(react@18.2.0) + '@storybook/blocks': 8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/components': 8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@storybook/csf-plugin': 8.0.0-beta.3 + '@storybook/csf-tools': 8.0.0-beta.3 + '@storybook/global': 5.0.0 + '@storybook/node-logger': 8.0.0-beta.3 + '@storybook/preview-api': 8.0.0-beta.3 + '@storybook/react-dom-shim': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 8.0.0-beta.3 + '@types/react': 18.2.46 + fs-extra: 11.2.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + rehype-external-links: 3.0.0 + rehype-slug: 6.0.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/addon-essentials@8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-eB5b8e24EHrjv8ovO+0CPs4hTtaLwJVXB1QxtbmPX0ERmYRDLQShSABbXVD0MzeM2LHPtTNEO1O9dZsvtiDXMw==} + dependencies: + '@storybook/addon-actions': 8.0.0-beta.3 + '@storybook/addon-backgrounds': 8.0.0-beta.3 + '@storybook/addon-controls': 8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-docs': 8.0.0-beta.3 + '@storybook/addon-highlight': 8.0.0-beta.3 + '@storybook/addon-measure': 8.0.0-beta.3 + '@storybook/addon-outline': 8.0.0-beta.3 + '@storybook/addon-toolbars': 8.0.0-beta.3 + '@storybook/addon-viewport': 8.0.0-beta.3 + '@storybook/core-common': 8.0.0-beta.3 + '@storybook/manager-api': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/node-logger': 8.0.0-beta.3 + '@storybook/preview-api': 8.0.0-beta.3 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + - encoding + - react + - react-dom + - supports-color + dev: true + + /@storybook/addon-highlight@8.0.0-beta.3: + resolution: {integrity: sha512-RiOjHfa8RW3787r7Pm3yxAEhmzWfFxvbTEucWdprnsvoXQa8og8vrA9M1GbF0S+MiePzxxO/k+/cwXYooj+9fg==} + dependencies: + '@storybook/global': 5.0.0 + dev: true + + /@storybook/addon-interactions@8.0.0-beta.3: + resolution: {integrity: sha512-yVhgW1STzY6p83nwO+35RI48MCwwSSAoZrYMxov91VHnou3Z53TXof2HiUvxrLS2M0IBjrGHtP27om4DHqK6KQ==} + dependencies: + '@storybook/global': 5.0.0 + '@storybook/types': 8.0.0-beta.3 + jest-mock: 27.5.1 + polished: 4.2.2 + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-links@8.0.0-beta.3(react@18.2.0): + resolution: {integrity: sha512-q4K0Uc3JDgoMQvQrIuf9l1w2q4g1C6zypvOTlHvD+rUgol7iPqypM/Nto5Vwzf/Yp28GPOf00QeLEA1Jngsong==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + dependencies: + '@storybook/csf': 0.1.2 + '@storybook/global': 5.0.0 + react: 18.2.0 + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-mdx-gfm@8.0.0-beta.3: + resolution: {integrity: sha512-qtC72sitiHvjZU+6jjXo1z2vraaFkP//dmmoKZ5FmRq9pC92mpx2x6oPNCPrRjk2jh7yotKnOJftDo0Od18BCQ==} + dependencies: + '@storybook/node-logger': 8.0.0-beta.3 + remark-gfm: 4.0.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/addon-measure@8.0.0-beta.3: + resolution: {integrity: sha512-JoW3M8da4WeEr8c57n/djVGxndnu5ZBq3rgaLpbJ1ZUjQ9oBKFcKvEBdBj/qXUgw7HKDrvxJpwcGAalLoz5m1w==} + dependencies: + '@storybook/global': 5.0.0 + tiny-invariant: 1.3.1 + dev: true + + /@storybook/addon-onboarding@1.0.10(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-tK7JjJYIpOM4LowBoIM/8ymYQ70qVRmu7pGqSOQ82AW15ob5u36HJ753y0hVH/KPj6k7J1aSgAEgVGXLmgwvKw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/telemetry': 7.6.6 + react: 18.2.0 + react-confetti: 6.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/addon-outline@8.0.0-beta.3: + resolution: {integrity: sha512-cZyCXPAxNkjvEXVzNhN9shS+LLseyjiyHv/jBk8brCoSrts5LxSvxv/YLS7CgtLU1qvc66Lr9U2L95Zd8F7x9A==} + dependencies: + '@storybook/global': 5.0.0 + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-themes@8.0.0-beta.3: + resolution: {integrity: sha512-m/2Wu4KTadNCD29RBE7+zmN0ShjzID8geht0jGYU/lO0TtlDkghZSEOA78GpG2O+LQDVkrF2/ryEJFlmzt+Q2Q==} + dependencies: + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-toolbars@8.0.0-beta.3: + resolution: {integrity: sha512-1NZDvyNGm2w6olISRPaOP6A6hbrAmAZ79AJ4Ssdg03L42UhQoHIR+4PxVXlKb9gP2fjKzNDYO4H8iHTkB9B6eA==} + dev: true + + /@storybook/addon-viewport@8.0.0-beta.3: + resolution: {integrity: sha512-R+kWKcKrG84CP7wxKuMIlo6VFLPOhJwYaIIoPzG2pVo0H4iz8SO4XeN/WR0LQ07ysaIFtsDWcBvGwokqrkwhug==} + dependencies: + memoizerific: 1.11.3 + dev: true + + /@storybook/blocks@8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-WctU1BCR8mhsDAdD+FVH99PWAh9dQ4GKAR2U640Z0iLhSlrbfOO3HtY5KLJM90s+zeeVsCCn5QTZ68F/NwexOg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/channels': 8.0.0-beta.3 + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/components': 8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/csf': 0.1.2 + '@storybook/docs-tools': 8.0.0-beta.3 + '@storybook/global': 5.0.0 + '@storybook/icons': 1.2.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 8.0.0-beta.3 + '@storybook/theming': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 8.0.0-beta.3 + '@types/lodash': 4.14.202 + color-convert: 2.0.1 + dequal: 2.0.3 + lodash: 4.17.21 + markdown-to-jsx: 7.3.2(react@18.2.0) + memoizerific: 1.11.3 + polished: 4.2.2 + react: 18.2.0 + react-colorful: 5.6.1(react-dom@18.2.0)(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + telejson: 7.2.0 + tocbot: 4.25.0 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + transitivePeerDependencies: + - '@types/react' + - encoding + - supports-color + dev: true + + /@storybook/builder-manager@8.0.0-beta.3: + resolution: {integrity: sha512-zQ0uGPhmO29TbQ4PE6vXjctqfqZVUN5yzpiwxyKNJV+0tbsGIKC0C76wa7yRvNqVsi4H/SkVx/h8NXQPn9yhyg==} + dependencies: + '@fal-works/esbuild-plugin-global-externals': 2.1.2 + '@storybook/core-common': 8.0.0-beta.3 + '@storybook/manager': 8.0.0-beta.3 + '@storybook/node-logger': 8.0.0-beta.3 + '@types/ejs': 3.1.5 + '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.18.20) + browser-assert: 1.2.1 + ejs: 3.1.9 + esbuild: 0.18.20 + esbuild-plugin-alias: 0.2.1 + express: 4.18.2 + fs-extra: 11.2.0 + process: 0.11.10 + util: 0.12.5 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/builder-vite@8.0.0-beta.3(typescript@5.3.3)(vite@5.0.10): + resolution: {integrity: sha512-2e2XIOmkW2W9R0xk1hHfs1RHyMqCvedVF8TAeCvQ8aLYhcpyhe8qd/VysDtZXF9sriq3vk2+apGmAM3dY1oGUQ==} + peerDependencies: + '@preact/preset-vite': '*' + typescript: '>= 4.3.x' + vite: ^4.0.0 || ^5.0.0 + vite-plugin-glimmerx: '*' + peerDependenciesMeta: + '@preact/preset-vite': + optional: true + typescript: + optional: true + vite-plugin-glimmerx: + optional: true + dependencies: + '@storybook/channels': 8.0.0-beta.3 + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/core-common': 8.0.0-beta.3 + '@storybook/csf-plugin': 8.0.0-beta.3 + '@storybook/node-logger': 8.0.0-beta.3 + '@storybook/preview': 8.0.0-beta.3 + '@storybook/preview-api': 8.0.0-beta.3 + '@storybook/types': 8.0.0-beta.3 + '@types/find-cache-dir': 3.2.1 + browser-assert: 1.2.1 + es-module-lexer: 0.9.3 + express: 4.18.2 + find-cache-dir: 3.3.2 + fs-extra: 11.2.0 + magic-string: 0.30.5 + ts-dedent: 2.2.0 + typescript: 5.3.3 + vite: 5.0.10 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/channels@7.6.12: + resolution: {integrity: sha512-TaPl5Y3lOoVi5kTLgKNRX8xh2sUPekH0Id1l4Ymw+lpgriEY6r60bmkZLysLG1GhlskpQ/da2+S2ap2ht8P2TQ==} + dependencies: + '@storybook/client-logger': 7.6.12 + '@storybook/core-events': 7.6.12 + '@storybook/global': 5.0.0 + qs: 6.11.2 + telejson: 7.2.0 + tiny-invariant: 1.3.1 + dev: true + + /@storybook/channels@7.6.6: + resolution: {integrity: sha512-vvo7fBe2WffPonNNOA7Xx7jcHAto8qJYlq+VMysfheXrsRRbhHl3WQOA18Vm8hV9txtqdqk0hwQiXOWvhYVpeQ==} + dependencies: + '@storybook/client-logger': 7.6.6 + '@storybook/core-events': 7.6.6 + '@storybook/global': 5.0.0 + qs: 6.11.2 + telejson: 7.2.0 + tiny-invariant: 1.3.1 + dev: true + + /@storybook/channels@8.0.0-beta.3: + resolution: {integrity: sha512-UxofXCtM/Bol8tJY98OPp74tALUd/YiGV5u+2nVyv4Q7iXc1K9eZycQsb9JYprH4Z8fNG4Qa3qpf7SHPoK5czA==} + dependencies: + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/global': 5.0.0 + qs: 6.11.2 + telejson: 7.2.0 + tiny-invariant: 1.3.1 + dev: true + + /@storybook/cli@8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-G9nXnaF+877e8eceO/7aABtUVd5hfGwcdMbPVAq1lXe0hZyp3m2l5YmldYiEYm4Bj814DL1+S1pEHmRm4nQbGw==} + hasBin: true + dependencies: + '@babel/types': 7.23.6 + '@ndelangen/get-tarball': 3.0.9 + '@storybook/codemod': 8.0.0-beta.3 + '@storybook/core-common': 8.0.0-beta.3 + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/core-server': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/csf-tools': 8.0.0-beta.3 + '@storybook/node-logger': 8.0.0-beta.3 + '@storybook/telemetry': 8.0.0-beta.3 + '@storybook/types': 8.0.0-beta.3 + '@types/semver': 7.5.6 + '@yarnpkg/fslib': 2.10.3 + '@yarnpkg/libzip': 2.3.0 + chalk: 4.1.2 + commander: 6.2.1 + cross-spawn: 7.0.3 + detect-indent: 6.1.0 + envinfo: 7.11.0 + execa: 5.1.1 + find-up: 5.0.0 + fs-extra: 11.2.0 + get-npm-tarball-url: 2.1.0 + giget: 1.2.1 + globby: 11.1.0 + jscodeshift: 0.15.1(@babel/preset-env@7.23.7) + leven: 3.1.0 + ora: 5.4.1 + prettier: 3.2.5 + prompts: 2.4.2 + read-pkg-up: 7.0.1 + semver: 7.5.4 + strip-json-comments: 3.1.1 + tempy: 1.0.1 + tiny-invariant: 1.3.1 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@babel/preset-env' + - bufferutil + - encoding + - react + - react-dom + - supports-color + - utf-8-validate + dev: true + + /@storybook/client-logger@7.6.12: + resolution: {integrity: sha512-hiRv6dXsOttMPqm9SxEuFoAtDe9rs7TUS8XcO5rmJ9BgfwBJsYlHzAxXkazxmvlyZtKL7gMx6m8OYbCdZgUqtA==} + dependencies: + '@storybook/global': 5.0.0 + dev: true + + /@storybook/client-logger@7.6.6: + resolution: {integrity: sha512-WEvVyuQR5oNF8jcMmGA13zDjxP/l46kOBBvB6JSc8toUdtLZ/kZWSnU0ioNM8+ECpFqXHjBcF2K6uSJOEb6YEg==} + dependencies: + '@storybook/global': 5.0.0 + dev: true + + /@storybook/client-logger@8.0.0-beta.3: + resolution: {integrity: sha512-vqwNwArucD1ChQv6+m310UiYl4F635CXxdf3p7x7xaSmANyVFSBNs8OgqRcl7bmSHMRtZLLwmQgsk4gj6YAj4g==} + dependencies: + '@storybook/global': 5.0.0 + dev: true + + /@storybook/codemod@8.0.0-beta.3: + resolution: {integrity: sha512-RjSyux7MUiGjC7EEjznKRa2ZDZZupDn0vI7TEr+36hroYSj0YpGOZfV769qAPQOzVRcs6ehA3J7zA9imaUY2LQ==} + dependencies: + '@babel/core': 7.23.7 + '@babel/preset-env': 7.23.7(@babel/core@7.23.7) + '@babel/types': 7.23.6 + '@storybook/csf': 0.1.2 + '@storybook/csf-tools': 8.0.0-beta.3 + '@storybook/node-logger': 8.0.0-beta.3 + '@storybook/types': 8.0.0-beta.3 + '@types/cross-spawn': 6.0.6 + cross-spawn: 7.0.3 + globby: 11.1.0 + jscodeshift: 0.15.1(@babel/preset-env@7.23.7) + lodash: 4.17.21 + prettier: 3.2.5 + recast: 0.23.4 + tiny-invariant: 1.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/components@8.0.0-beta.3(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Lr0JDXLd6mN+Zgm92LavrM55k87gLvBANR8xgWRxCBdrwdZCtlqNDEt1ezPHJ8z4s/CX0KwUe3eO9K40fy2vOg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.46)(react@18.2.0) + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/csf': 0.1.2 + '@storybook/global': 5.0.0 + '@storybook/icons': 1.2.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 8.0.0-beta.3 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + util-deprecate: 1.0.2 + transitivePeerDependencies: + - '@types/react' + dev: true + + /@storybook/core-common@7.6.6: + resolution: {integrity: sha512-DpbFSYw8LHuwpeU2ec5uWryxrSqslFJnWTfNA7AvpzCviWXkz4kq+YYrDee9XExF6OozNwILmG6m52SnraysBA==} + dependencies: + '@storybook/core-events': 7.6.6 + '@storybook/node-logger': 7.6.6 + '@storybook/types': 7.6.6 + '@types/find-cache-dir': 3.2.1 + '@types/node': 18.19.4 + '@types/node-fetch': 2.6.10 + '@types/pretty-hrtime': 1.0.3 + chalk: 4.1.2 + esbuild: 0.18.20 + esbuild-register: 3.5.0(esbuild@0.18.20) + file-system-cache: 2.3.0 + find-cache-dir: 3.3.2 + find-up: 5.0.0 + fs-extra: 11.2.0 + glob: 10.3.10 + handlebars: 4.7.8 + lazy-universal-dotenv: 4.0.0 + node-fetch: 2.7.0 + picomatch: 2.3.1 + pkg-dir: 5.0.0 + pretty-hrtime: 1.0.3 + resolve-from: 5.0.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/core-common@8.0.0-beta.3: + resolution: {integrity: sha512-WLVBa+K1HP6P0nUQV/c9l8FtYiyfSJBbSwC225eCgEa0kYMiGMLnIFDUZECqpULOYitwhO7YWRjn1m2PqJp3/Q==} + dependencies: + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/csf-tools': 8.0.0-beta.3 + '@storybook/node-logger': 8.0.0-beta.3 + '@storybook/types': 8.0.0-beta.3 + '@yarnpkg/fslib': 2.10.3 + '@yarnpkg/libzip': 2.3.0 + chalk: 4.1.2 + cross-spawn: 7.0.3 + esbuild: 0.18.20 + esbuild-register: 3.5.0(esbuild@0.18.20) + execa: 5.1.1 + file-system-cache: 2.3.0 + find-cache-dir: 3.3.2 + find-up: 5.0.0 + fs-extra: 11.2.0 + glob: 10.3.10 + handlebars: 4.7.8 + lazy-universal-dotenv: 4.0.0 + node-fetch: 2.7.0 + picomatch: 2.3.1 + pkg-dir: 5.0.0 + pretty-hrtime: 1.0.3 + resolve-from: 5.0.0 + semver: 7.5.4 + tempy: 1.0.1 + tiny-invariant: 1.3.1 + ts-dedent: 2.2.0 + util: 0.12.5 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/core-events@7.6.12: + resolution: {integrity: sha512-IO4cwk7bBCKH6lLnnIlHO9FwQXt/9CzLUAoZSY9msWsdPppCdKlw8ynJI5YarSNKDBUn8ArIfnRf0Mve0KQr9Q==} + dependencies: + ts-dedent: 2.2.0 + dev: true + + /@storybook/core-events@7.6.6: + resolution: {integrity: sha512-7+q9HiZiLxaQcwpaSLQrLdjHNHBoOoUY9ZcZXI9iNFSopOgb/ItDnzzlpv08NC7CbKae1hVKJM/t5aSTl7tCMw==} + dependencies: + ts-dedent: 2.2.0 + dev: true + + /@storybook/core-events@8.0.0-beta.3: + resolution: {integrity: sha512-5rkauI9piCnn1pLcBzQMRik906POpiyArt8Ub8MJWjVdHetDwryjErUxY7fnNCNvBebFQhtnTBqUEgMB+CMMAw==} + dependencies: + ts-dedent: 2.2.0 + dev: true + + /@storybook/core-server@8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-BZU5kVtvl+AAG5hzQab1TY9LVWAGoHo9ufZ0dPTNpCIGlg3zOi0hZtyMLBfFCsxoL2WC9MqqsN3idFWgNBoYTQ==} + dependencies: + '@aw-web-design/x-default-browser': 1.4.126 + '@discoveryjs/json-ext': 0.5.7 + '@storybook/builder-manager': 8.0.0-beta.3 + '@storybook/channels': 8.0.0-beta.3 + '@storybook/core-common': 8.0.0-beta.3 + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/csf': 0.1.2 + '@storybook/csf-tools': 8.0.0-beta.3 + '@storybook/docs-mdx': 3.0.0 + '@storybook/global': 5.0.0 + '@storybook/manager': 8.0.0-beta.3 + '@storybook/manager-api': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/node-logger': 8.0.0-beta.3 + '@storybook/preview-api': 8.0.0-beta.3 + '@storybook/telemetry': 8.0.0-beta.3 + '@storybook/types': 8.0.0-beta.3 + '@types/detect-port': 1.3.5 + '@types/node': 18.19.4 + '@types/pretty-hrtime': 1.0.3 + '@types/semver': 7.5.6 + better-opn: 3.0.2 + chalk: 4.1.2 + cli-table3: 0.6.3 + compression: 1.7.4 + detect-port: 1.5.1 + express: 4.18.2 + fs-extra: 11.2.0 + globby: 11.1.0 + ip: 2.0.0 + lodash: 4.17.21 + open: 8.4.2 + pretty-hrtime: 1.0.3 + prompts: 2.4.2 + read-pkg-up: 7.0.1 + semver: 7.5.4 + telejson: 7.2.0 + tiny-invariant: 1.3.1 + ts-dedent: 2.2.0 + util: 0.12.5 + util-deprecate: 1.0.2 + watchpack: 2.4.0 + ws: 8.16.0 + transitivePeerDependencies: + - bufferutil + - encoding + - react + - react-dom + - supports-color + - utf-8-validate + dev: true + + /@storybook/csf-plugin@8.0.0-beta.3: + resolution: {integrity: sha512-ndhNly2s7iBuzXJSaph4V6viz/7Q9u7ivadlbkVbsXQuHHYOOTCUadqfRfUKUMYwbMNPKD9Gw0tX7CfzjNo7zA==} + dependencies: + '@storybook/csf-tools': 8.0.0-beta.3 + unplugin: 1.6.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/csf-tools@7.6.6: + resolution: {integrity: sha512-VXOZCzfSVJL832u17pPhFu1x3PPaAN9d8VXNFX+t/2raga7tK3T7Qhe7lWfP7EZcrVvSCEEp0aMRz2EzzDGVtw==} + dependencies: + '@babel/generator': 7.23.6 + '@babel/parser': 7.23.6 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + '@storybook/csf': 0.1.2 + '@storybook/types': 7.6.6 + fs-extra: 11.2.0 + recast: 0.23.4 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/csf-tools@8.0.0-beta.3: + resolution: {integrity: sha512-zsAWnOBB+i0bSdmeOtg7bFvIvvPfYhWgvXgZTLfXoxyr8PN7qbMB3251u9f3IAL3Alcm/7Zea5kQ8TYhUFCSkQ==} + dependencies: + '@babel/generator': 7.23.6 + '@babel/parser': 7.23.6 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + '@storybook/csf': 0.1.2 + '@storybook/types': 8.0.0-beta.3 + fs-extra: 11.2.0 + recast: 0.23.4 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/csf@0.1.2: + resolution: {integrity: sha512-ePrvE/pS1vsKR9Xr+o+YwdqNgHUyXvg+1Xjx0h9LrVx7Zq4zNe06pd63F5EvzTbCbJsHj7GHr9tkiaqm7U8WRA==} + dependencies: + type-fest: 2.19.0 + dev: true + + /@storybook/docs-mdx@3.0.0: + resolution: {integrity: sha512-NmiGXl2HU33zpwTv1XORe9XG9H+dRUC1Jl11u92L4xr062pZtrShLmD4VKIsOQujxhhOrbxpwhNOt+6TdhyIdQ==} + dev: true + + /@storybook/docs-tools@8.0.0-beta.3: + resolution: {integrity: sha512-mcHS+gIS5gj+Z2yk6ZbRYMi9ICjGULPn+m59ddmqKrdId159v1DyexDvSuYFrLqu3x4+g3V4RM+KyC8DaE6unA==} + dependencies: + '@storybook/core-common': 8.0.0-beta.3 + '@storybook/preview-api': 8.0.0-beta.3 + '@storybook/types': 8.0.0-beta.3 + '@types/doctrine': 0.0.3 + assert: 2.1.0 + doctrine: 3.0.0 + lodash: 4.17.21 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/global@5.0.0: + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + dev: true + + /@storybook/icons@1.2.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-m3jnuE+zmkZy6K+cdUDzAoUuCJyl0fWCAXPCji7VZCH1TzFohyvnPqhc9JMkQpanej2TOW3wWXaplPzHghcBSg==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/instrumenter@8.0.0-beta.3: + resolution: {integrity: sha512-/yqsZ06GANyvkNc1lFiws4hMVClK1JPLHnLeS44tXp208yUlEssKlcwmDMG8K4ARqtvonzvNiRWH0dXYsVmojw==} + dependencies: + '@storybook/channels': 8.0.0-beta.3 + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/global': 5.0.0 + '@storybook/preview-api': 8.0.0-beta.3 + '@vitest/utils': 0.34.7 + util: 0.12.5 + dev: true + + /@storybook/manager-api@8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-tXIFAsRh1eEj6ewK0aYrj6QGHANOIjeIhDwUnNh4hgVSio1B7Wr6zM5bM5hMvc8C9jSlc2rh3xP96PC3mc1rAA==} + dependencies: + '@storybook/channels': 8.0.0-beta.3 + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/csf': 0.1.2 + '@storybook/global': 5.0.0 + '@storybook/router': 8.0.0-beta.3 + '@storybook/theming': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 8.0.0-beta.3 + dequal: 2.0.3 + lodash: 4.17.21 + memoizerific: 1.11.3 + store2: 2.14.2 + telejson: 7.2.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - react + - react-dom + dev: true + + /@storybook/manager@8.0.0-beta.3: + resolution: {integrity: sha512-aXK057FA3m9C6upC2oNldfeJ8jEUMCCqjfA9VPShh5ILOY3la24tjVz+OVPVYif3W6cvZZ3cSBBPDiBwqZ9Bjw==} + dev: true + + /@storybook/node-logger@7.6.6: + resolution: {integrity: sha512-b2OF9GRNI01MlBlnDGS8S6/yOpBNl8eH/0ONafuMPzFEZs5PouHGsFflJvQwwcdVTknMjF5uVS2eSmnLZ8spvA==} + dev: true + + /@storybook/node-logger@8.0.0-beta.3: + resolution: {integrity: sha512-4Hg7EWJ6IPVdOTA55eK+l4bfOlv9TGC/OIj9IC96zvkqUEPchw319DWDwSfagikbtQ6B+2ae0mPSxhrRQa9iyg==} + dev: true + + /@storybook/preview-api@7.6.12: + resolution: {integrity: sha512-uSzeMSLnCRROjiofJP0F0niLWL+sboQ5ktHW6BAYoPwprumXduPxKBUVEZNxMbVYoAz9v/kEZmaLauh8LRP2Hg==} + dependencies: + '@storybook/channels': 7.6.12 + '@storybook/client-logger': 7.6.12 + '@storybook/core-events': 7.6.12 + '@storybook/csf': 0.1.2 + '@storybook/global': 5.0.0 + '@storybook/types': 7.6.12 + '@types/qs': 6.9.11 + dequal: 2.0.3 + lodash: 4.17.21 + memoizerific: 1.11.3 + qs: 6.11.2 + synchronous-promise: 2.0.17 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + dev: true + + /@storybook/preview-api@8.0.0-beta.3: + resolution: {integrity: sha512-75+J0QnT1J1SvCtV4dOexv+28Yw1u2y37oC4drhYV5qAgs7R1Eowx7CjMcO0Mrm6rH/n796phCguiFtWWypPGQ==} + dependencies: + '@storybook/channels': 8.0.0-beta.3 + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/csf': 0.1.2 + '@storybook/global': 5.0.0 + '@storybook/types': 8.0.0-beta.3 + '@types/qs': 6.9.11 + dequal: 2.0.3 + lodash: 4.17.21 + memoizerific: 1.11.3 + qs: 6.11.2 + tiny-invariant: 1.3.1 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + dev: true + + /@storybook/preview@8.0.0-beta.3: + resolution: {integrity: sha512-jTFgermGPHWOhy4c6lowbWEqOV2lsOy1/g2ZnrV0NHzRbUDs5NRNxaaYwjKnti9mpI8pHNIQZ+UgLjbbNrh3Xg==} + dev: true + + /@storybook/react-dom-shim@8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-IfC1P7nsVv4CZzMx2VXccer/2UWV0UAA+tnCeLkRrjRa+ysnyoUTTZ2Y7slQxPNXv82MMI5uOart+2J1MPH9Pw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/react-vite@8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)(vite@5.0.10): + resolution: {integrity: sha512-y1Vgxef8B3BS+EDosvRVejZ8qE6dO5BgfwunEUKPWVViULIRXl1d+8mtruGqvYNZXmzHzcRqhCe2rYZMA+Hl9A==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + vite: ^4.0.0 || ^5.0.0 + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.3.3)(vite@5.0.10) + '@rollup/pluginutils': 5.1.0 + '@storybook/builder-vite': 8.0.0-beta.3(typescript@5.3.3)(vite@5.0.10) + '@storybook/react': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) + magic-string: 0.30.5 + react: 18.2.0 + react-docgen: 7.0.1 + react-dom: 18.2.0(react@18.2.0) + vite: 5.0.10 + transitivePeerDependencies: + - '@preact/preset-vite' + - encoding + - rollup + - supports-color + - typescript + - vite-plugin-glimmerx + dev: true + + /@storybook/react@8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3): + resolution: {integrity: sha512-RxIW1yuZhER97m2wjuhvroUu3yXoT2DQjGEtS0XhR1SgoUN7RS9/ZjeWjp1n0r0DlNNrD3rx73sBh7FujurLwQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '>= 4.2.x' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/docs-tools': 8.0.0-beta.3 + '@storybook/global': 5.0.0 + '@storybook/preview-api': 8.0.0-beta.3 + '@storybook/react-dom-shim': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 8.0.0-beta.3 + '@types/escodegen': 0.0.6 + '@types/estree': 0.0.51 + '@types/node': 18.19.4 + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + acorn-walk: 7.2.0 + escodegen: 2.1.0 + html-tags: 3.3.1 + lodash: 4.17.21 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-element-to-jsx-string: 15.0.0(react-dom@18.2.0)(react@18.2.0) + semver: 7.5.4 + ts-dedent: 2.2.0 + type-fest: 2.19.0 + typescript: 5.3.3 + util-deprecate: 1.0.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/router@8.0.0-beta.3: + resolution: {integrity: sha512-6mZmdRbV9VdJV6azQe9kA9+YvEgd9Mr+UIq96c8I6eufTJXdixZ+bXEO0Vpebk1PbIUtovSHQl6trYsEh6K5KQ==} + dependencies: + '@storybook/client-logger': 8.0.0-beta.3 + memoizerific: 1.11.3 + qs: 6.11.2 + dev: true + + /@storybook/telemetry@7.6.6: + resolution: {integrity: sha512-2WdDcrMrt1bPVgdMVO0tFmVxT6YIjiPRfKbH/7wwYMOGmV75m4mJ9Ha2gzZc/oXTSK1M4/fiK12IgW+S3ErcMg==} + dependencies: + '@storybook/client-logger': 7.6.6 + '@storybook/core-common': 7.6.6 + '@storybook/csf-tools': 7.6.6 + chalk: 4.1.2 + detect-package-manager: 2.0.1 + fetch-retry: 5.0.6 + fs-extra: 11.2.0 + read-pkg-up: 7.0.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/telemetry@8.0.0-beta.3: + resolution: {integrity: sha512-jnHTkII8LJCsj7/a57VYefI3AHiLKpaMAtnTRY1MuOswmWvgEOl1CYqR7F7ST4UxffDl1dHHgMRi7goI3t1mWA==} + dependencies: + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/core-common': 8.0.0-beta.3 + '@storybook/csf-tools': 8.0.0-beta.3 + chalk: 4.1.2 + detect-package-manager: 2.0.1 + fetch-retry: 5.0.6 + fs-extra: 11.2.0 + read-pkg-up: 7.0.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/test-runner@0.16.0: + resolution: {integrity: sha512-LDmNbKFoEDW/VS9o6KR8e1r5MnbCc5ZojUfi5yqLdq80gFD7BvilgKgV0lUh/xWHryzoy+Ids5LYgrPJZmU2dQ==} + engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + '@babel/core': 7.23.7 + '@babel/generator': 7.23.6 + '@babel/template': 7.22.15 + '@babel/types': 7.23.6 + '@jest/types': 29.6.3 + '@storybook/core-common': 7.6.6 + '@storybook/csf': 0.1.2 + '@storybook/csf-tools': 7.6.6 + '@storybook/preview-api': 7.6.12 + '@swc/core': 1.3.102 + '@swc/jest': 0.2.29(@swc/core@1.3.102) + can-bind-to-host: 1.1.2 + commander: 9.5.0 + expect-playwright: 0.8.0 + glob: 10.3.10 + jest: 29.7.0 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-junit: 16.0.0 + jest-playwright-preset: 4.0.0(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0) + jest-runner: 29.7.0 + jest-serializer-html: 7.1.0 + jest-watch-typeahead: 2.2.2(jest@29.7.0) + node-fetch: 2.7.0 + playwright: 1.40.1 + read-pkg-up: 7.0.1 + tempy: 1.0.1 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@swc/helpers' + - '@types/node' + - babel-plugin-macros + - debug + - encoding + - node-notifier + - supports-color + - ts-node + dev: true + + /@storybook/test@8.0.0-beta.3(@types/jest@29.5.11)(jest@29.7.0)(vitest@1.1.0): + resolution: {integrity: sha512-pmp9DREL/QiXywbrWiztz7Z1HLJxOSjY6sBVj2ZWh22ykbMAlRsS79num4W29e0I2pqgRgrf6MOXAyOgCajNhw==} + dependencies: + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/core-events': 8.0.0-beta.3 + '@storybook/instrumenter': 8.0.0-beta.3 + '@storybook/preview-api': 8.0.0-beta.3 + '@testing-library/dom': 9.3.3 + '@testing-library/jest-dom': 6.4.2(@types/jest@29.5.11)(jest@29.7.0)(vitest@1.1.0) + '@testing-library/user-event': 14.5.2(@testing-library/dom@9.3.3) + '@vitest/expect': 1.1.3 + '@vitest/spy': 1.3.0 + chai: 4.3.10 + util: 0.12.5 + transitivePeerDependencies: + - '@jest/globals' + - '@types/bun' + - '@types/jest' + - jest + - vitest + dev: true + + /@storybook/theming@8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-DCvErL9C77Dph65NHz+YVxddGOqVPhKaXr5u7NVPAJTi5qLiHUAeMyQcmwMQ2MVWhEI2iUS253bilzOnsCTebQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@storybook/client-logger': 8.0.0-beta.3 + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/types@7.6.12: + resolution: {integrity: sha512-Wsbd+NS10/2yMHQ/26rXHflXam0hm2qufTFiHOX6VXZWxij3slRU88Fnwzp+1QSyjXb0qkEr8dOx7aG00+ItVw==} + dependencies: + '@storybook/channels': 7.6.12 + '@types/babel__core': 7.20.5 + '@types/express': 4.17.21 + file-system-cache: 2.3.0 + dev: true + + /@storybook/types@7.6.6: + resolution: {integrity: sha512-77vbQp3GX93OD8UzFkY4a0fAmkZrqLe61XVo6yABrwbVDY0EcAwaCF5gcXRhOHldlH7KYbLfEQkDkkKTBjX7ow==} + dependencies: + '@storybook/channels': 7.6.6 + '@types/babel__core': 7.20.5 + '@types/express': 4.17.21 + file-system-cache: 2.3.0 + dev: true + + /@storybook/types@8.0.0-beta.3: + resolution: {integrity: sha512-c32ut13RrLlsxyqwy3BC64Vptke0hHrvK9Q4dL+OodvRyWB96Aj51kWGyjKoN8D0Dv8X+Ud8GYdm5B2mg+zhpw==} + dependencies: + '@storybook/channels': 8.0.0-beta.3 + '@types/express': 4.17.21 + file-system-cache: 2.3.0 + dev: true + + /@swc/core-darwin-arm64@1.3.102: + resolution: {integrity: sha512-CJDxA5Wd2cUMULj3bjx4GEoiYyyiyL8oIOu4Nhrs9X+tlg8DnkCm4nI57RJGP8Mf6BaXPIJkHX8yjcefK2RlDA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@swc/core-darwin-x64@1.3.102: + resolution: {integrity: sha512-X5akDkHwk6oAer49oER0qZMjNMkLH3IOZaV1m98uXIasAGyjo5WH1MKPeMLY1sY6V6TrufzwiSwD4ds571ytcg==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm-gnueabihf@1.3.102: + resolution: {integrity: sha512-kJH3XtZP9YQdjq/wYVBeFuiVQl4HaC4WwRrIxAHwe2OyvrwUI43dpW3LpxSggBnxXcVCXYWf36sTnv8S75o2Gw==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm64-gnu@1.3.102: + resolution: {integrity: sha512-flQP2WDyCgO24WmKA1wjjTx+xfCmavUete2Kp6yrM+631IHLGnr17eu7rYJ/d4EnDBId/ytMyrnWbTVkaVrpbQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm64-musl@1.3.102: + resolution: {integrity: sha512-bQEQSnC44DyoIGLw1+fNXKVGoCHi7eJOHr8BdH0y1ooy9ArskMjwobBFae3GX4T1AfnrTaejyr0FvLYIb0Zkog==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-x64-gnu@1.3.102: + resolution: {integrity: sha512-dFvnhpI478svQSxqISMt00MKTDS0e4YtIr+ioZDG/uJ/q+RpcNy3QI2KMm05Fsc8Y0d4krVtvCKWgfUMsJZXAg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-x64-musl@1.3.102: + resolution: {integrity: sha512-+a0M3CvjeIRNA/jTCzWEDh2V+mhKGvLreHOL7J97oULZy5yg4gf7h8lQX9J8t9QLbf6fsk+0F8bVH1Ie/PbXjA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-arm64-msvc@1.3.102: + resolution: {integrity: sha512-w76JWLjkZNOfkB25nqdWUNCbt0zJ41CnWrJPZ+LxEai3zAnb2YtgB/cCIrwxDebRuMgE9EJXRj7gDDaTEAMOOQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-ia32-msvc@1.3.102: + resolution: {integrity: sha512-vlDb09HiGqKwz+2cxDS9T5/461ipUQBplvuhW+cCbzzGuPq8lll2xeyZU0N1E4Sz3MVdSPx1tJREuRvlQjrwNg==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-x64-msvc@1.3.102: + resolution: {integrity: sha512-E/jfSD7sShllxBwwgDPeXp1UxvIqehj/ShSUqq1pjR/IDRXngcRSXKJK92mJkNFY7suH6BcCWwzrxZgkO7sWmw==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core@1.3.102: + resolution: {integrity: sha512-OAjNLY/f6QWKSDzaM3bk31A+OYHu6cPa9P/rFIx8X5d24tHXUpRiiq6/PYI6SQRjUPlB72GjsjoEU8F+ALadHg==} + engines: {node: '>=10'} + requiresBuild: true + peerDependencies: + '@swc/helpers': ^0.5.0 + peerDependenciesMeta: + '@swc/helpers': + optional: true + dependencies: + '@swc/counter': 0.1.2 + '@swc/types': 0.1.5 + optionalDependencies: + '@swc/core-darwin-arm64': 1.3.102 + '@swc/core-darwin-x64': 1.3.102 + '@swc/core-linux-arm-gnueabihf': 1.3.102 + '@swc/core-linux-arm64-gnu': 1.3.102 + '@swc/core-linux-arm64-musl': 1.3.102 + '@swc/core-linux-x64-gnu': 1.3.102 + '@swc/core-linux-x64-musl': 1.3.102 + '@swc/core-win32-arm64-msvc': 1.3.102 + '@swc/core-win32-ia32-msvc': 1.3.102 + '@swc/core-win32-x64-msvc': 1.3.102 + dev: true + + /@swc/counter@0.1.2: + resolution: {integrity: sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==} + dev: true + + /@swc/jest@0.2.29(@swc/core@1.3.102): + resolution: {integrity: sha512-8reh5RvHBsSikDC3WGCd5ZTd2BXKkyOdK7QwynrCH58jk2cQFhhHhFBg/jvnWZehUQe/EoOImLENc9/DwbBFow==} + engines: {npm: '>= 7.0.0'} + peerDependencies: + '@swc/core': '*' + dependencies: + '@jest/create-cache-key-function': 27.5.1 + '@swc/core': 1.3.102 + jsonc-parser: 3.2.0 + dev: true + + /@swc/types@0.1.5: + resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} + dev: true + + /@testing-library/dom@9.3.3: + resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} + engines: {node: '>=14'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/runtime': 7.23.7 + '@types/aria-query': 5.0.4 + aria-query: 5.1.3 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + dev: true + + /@testing-library/jest-dom@6.4.2(@types/jest@29.5.11)(jest@29.7.0)(vitest@1.1.0): + resolution: {integrity: sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + peerDependencies: + '@jest/globals': '>= 28' + '@types/bun': latest + '@types/jest': '>= 28' + jest: '>= 28' + vitest: '>= 0.32' + peerDependenciesMeta: + '@jest/globals': + optional: true + '@types/bun': + optional: true + '@types/jest': + optional: true + jest: + optional: true + vitest: + optional: true + dependencies: + '@adobe/css-tools': 4.3.2 + '@babel/runtime': 7.23.7 + '@types/jest': 29.5.11 + aria-query: 5.3.0 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + jest: 29.7.0 + lodash: 4.17.21 + redent: 3.0.0 + vitest: 1.1.0 + dev: true + + /@testing-library/user-event@14.5.2(@testing-library/dom@9.3.3): + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + dependencies: + '@testing-library/dom': 9.3.3 + dev: true + + /@types/aria-query@5.0.4: + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + dev: true + + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.5 + dev: true + + /@types/babel__generator@7.6.8: + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + dev: true + + /@types/babel__traverse@7.20.5: + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@types/body-parser@1.19.5: + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.10.6 + dev: true + + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + dependencies: + '@types/node': 20.10.6 + dev: true + + /@types/cross-spawn@6.0.6: + resolution: {integrity: sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==} + dependencies: + '@types/node': 20.10.6 + dev: true + + /@types/debug@4.1.12: + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + dependencies: + '@types/ms': 0.7.34 + dev: true + + /@types/detect-port@1.3.5: + resolution: {integrity: sha512-Rf3/lB9WkDfIL9eEKaSYKc+1L/rNVYBjThk22JTqQw0YozXarX8YljFAz+HCoC6h4B4KwCMsBPZHaFezwT4BNA==} + dev: true + + /@types/doctrine@0.0.3: + resolution: {integrity: sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA==} + dev: true + + /@types/doctrine@0.0.9: + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + dev: true + + /@types/ejs@3.1.5: + resolution: {integrity: sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==} + dev: true + + /@types/emscripten@1.39.10: + resolution: {integrity: sha512-TB/6hBkYQJxsZHSqyeuO1Jt0AB/bW6G7rHt9g7lML7SOF6lbgcHvw/Lr+69iqN0qxgXLhWKScAon73JNnptuDw==} + dev: true + + /@types/escodegen@0.0.6: + resolution: {integrity: sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==} + dev: true + + /@types/estree@0.0.51: + resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} + dev: true + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: true + + /@types/express-serve-static-core@4.17.41: + resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==} + dependencies: + '@types/node': 20.10.6 + '@types/qs': 6.9.11 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + dev: true + + /@types/express@4.17.21: + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.17.41 + '@types/qs': 6.9.11 + '@types/serve-static': 1.15.5 + dev: true + + /@types/find-cache-dir@3.2.1: + resolution: {integrity: sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==} + dev: true + + /@types/glob@7.2.0: + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 20.10.6 + dev: true + + /@types/graceful-fs@4.1.9: + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + dependencies: + '@types/node': 20.10.6 + dev: true + + /@types/hast@3.0.4: + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + dependencies: + '@types/unist': 2.0.10 + dev: true + + /@types/http-errors@2.0.4: + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + dev: true + + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + dev: true + + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + dev: true + + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + dependencies: + '@types/istanbul-lib-report': 3.0.3 + dev: true + + /@types/jest@29.5.11: + resolution: {integrity: sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==} + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + dev: true + + /@types/lodash@4.14.202: + resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} + dev: true + + /@types/mdast@4.0.3: + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + dependencies: + '@types/unist': 2.0.10 + dev: true + + /@types/mdx@2.0.10: + resolution: {integrity: sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==} + dev: true + + /@types/mime@1.3.5: + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + dev: true + + /@types/mime@3.0.4: + resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} + dev: true + + /@types/minimatch@5.1.2: + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + dev: true + + /@types/ms@0.7.34: + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + dev: true + + /@types/node-fetch@2.6.10: + resolution: {integrity: sha512-PPpPK6F9ALFTn59Ka3BaL+qGuipRfxNE8qVgkp0bVixeiR2c2/L+IVOiBdu9JhhT22sWnQEp6YyHGI2b2+CMcA==} + dependencies: + '@types/node': 20.10.6 + form-data: 4.0.0 + dev: true + + /@types/node@18.19.4: + resolution: {integrity: sha512-xNzlUhzoHotIsnFoXmJB+yWmBvFZgKCI9TtPIEdYIMM1KWfwuY8zh7wvc1u1OAXlC7dlf6mZVx/s+Y5KfFz19A==} + dependencies: + undici-types: 5.26.5 + dev: true + + /@types/node@20.10.6: + resolution: {integrity: sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==} + dependencies: + undici-types: 5.26.5 + dev: true + + /@types/normalize-package-data@2.4.4: + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + dev: true + + /@types/pretty-hrtime@1.0.3: + resolution: {integrity: sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA==} + dev: true + + /@types/prop-types@15.7.11: + resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} + + /@types/qs@6.9.11: + resolution: {integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==} + dev: true + + /@types/range-parser@1.2.7: + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + dev: true + + /@types/react-dom@18.2.18: + resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==} + dependencies: + '@types/react': 18.2.46 + + /@types/react@18.2.46: + resolution: {integrity: sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w==} + dependencies: + '@types/prop-types': 15.7.11 + '@types/scheduler': 0.16.8 + csstype: 3.1.3 + + /@types/resolve@1.20.6: + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + dev: true + + /@types/scheduler@0.16.8: + resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} + + /@types/semver@7.5.6: + resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + dev: true + + /@types/send@0.17.4: + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.10.6 + dev: true + + /@types/serve-static@1.15.5: + resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} + dependencies: + '@types/http-errors': 2.0.4 + '@types/mime': 3.0.4 + '@types/node': 20.10.6 + dev: true + + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + dev: true + + /@types/unist@2.0.10: + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + dev: true + + /@types/unist@3.0.2: + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + dev: true + + /@types/uuid@9.0.7: + resolution: {integrity: sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==} + dev: true + + /@types/wait-on@5.3.4: + resolution: {integrity: sha512-EBsPjFMrFlMbbUFf9D1Fp+PAB2TwmUn7a3YtHyD9RLuTIk1jDd8SxXVAoez2Ciy+8Jsceo2MYEYZzJ/DvorOKw==} + dependencies: + '@types/node': 20.10.6 + dev: true + + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + dev: true + + /@types/yargs@16.0.9: + resolution: {integrity: sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: true + + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + dependencies: + '@types/yargs-parser': 21.0.3 + dev: true + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + + /@vitest/expect@1.1.0: + resolution: {integrity: sha512-9IE2WWkcJo2BR9eqtY5MIo3TPmS50Pnwpm66A6neb2hvk/QSLfPXBz2qdiwUOQkwyFuuXEUj5380CbwfzW4+/w==} + dependencies: + '@vitest/spy': 1.1.0 + '@vitest/utils': 1.1.0 + chai: 4.3.10 + dev: true + + /@vitest/expect@1.1.3: + resolution: {integrity: sha512-MnJqsKc1Ko04lksF9XoRJza0bGGwTtqfbyrsYv5on4rcEkdo+QgUdITenBQBUltKzdxW7K3rWh+nXRULwsdaVg==} + dependencies: + '@vitest/spy': 1.1.3 + '@vitest/utils': 1.1.3 + chai: 4.3.10 + dev: true + + /@vitest/runner@1.1.0: + resolution: {integrity: sha512-zdNLJ00pm5z/uhbWF6aeIJCGMSyTyWImy3Fcp9piRGvueERFlQFbUwCpzVce79OLm2UHk9iwaMSOaU9jVHgNVw==} + dependencies: + '@vitest/utils': 1.1.0 + p-limit: 5.0.0 + pathe: 1.1.1 + dev: true + + /@vitest/snapshot@1.1.0: + resolution: {integrity: sha512-5O/wyZg09V5qmNmAlUgCBqflvn2ylgsWJRRuPrnHEfDNT6tQpQ8O1isNGgo+VxofISHqz961SG3iVvt3SPK/QQ==} + dependencies: + magic-string: 0.30.5 + pathe: 1.1.1 + pretty-format: 29.7.0 + dev: true + + /@vitest/spy@1.1.0: + resolution: {integrity: sha512-sNOVSU/GE+7+P76qYo+VXdXhXffzWZcYIPQfmkiRxaNCSPiLANvQx5Mx6ZURJ/ndtEkUJEpvKLXqAYTKEY+lTg==} + dependencies: + tinyspy: 2.2.0 + dev: true + + /@vitest/spy@1.1.3: + resolution: {integrity: sha512-Ec0qWyGS5LhATFQtldvChPTAHv08yHIOZfiNcjwRQbFPHpkih0md9KAbs7TfeIfL7OFKoe7B/6ukBTqByubXkQ==} + dependencies: + tinyspy: 2.2.0 + dev: true + + /@vitest/spy@1.3.0: + resolution: {integrity: sha512-AkCU0ThZunMvblDpPKgjIi025UxR8V7MZ/g/EwmAGpjIujLVV2X6rGYGmxE2D4FJbAy0/ijdROHMWa2M/6JVMw==} + dependencies: + tinyspy: 2.2.0 + dev: true + + /@vitest/utils@0.34.7: + resolution: {integrity: sha512-ziAavQLpCYS9sLOorGrFFKmy2gnfiNU0ZJ15TsMz/K92NAPS/rp9K4z6AJQQk5Y8adCy4Iwpxy7pQumQ/psnRg==} + dependencies: + diff-sequences: 29.6.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + dev: true + + /@vitest/utils@1.1.0: + resolution: {integrity: sha512-z+s510fKmYz4Y41XhNs3vcuFTFhcij2YF7F8VQfMEYAAUfqQh0Zfg7+w9xdgFGhPf3tX3TicAe+8BDITk6ampQ==} + dependencies: + diff-sequences: 29.6.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + dev: true + + /@vitest/utils@1.1.3: + resolution: {integrity: sha512-Dyt3UMcdElTll2H75vhxfpZu03uFpXRCHxWnzcrFjZxT1kTbq8ALUYIeBgGolo1gldVdI0YSlQRacsqxTwNqwg==} + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + dev: true + + /@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.18.20): + resolution: {integrity: sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==} + engines: {node: '>=14.15.0'} + peerDependencies: + esbuild: '>=0.10.0' + dependencies: + esbuild: 0.18.20 + tslib: 2.6.2 + dev: true + + /@yarnpkg/fslib@2.10.3: + resolution: {integrity: sha512-41H+Ga78xT9sHvWLlFOZLIhtU6mTGZ20pZ29EiZa97vnxdohJD2AF42rCoAoWfqUz486xY6fhjMH+DYEM9r14A==} + engines: {node: '>=12 <14 || 14.2 - 14.9 || >14.10.0'} + dependencies: + '@yarnpkg/libzip': 2.3.0 + tslib: 1.14.1 + dev: true + + /@yarnpkg/libzip@2.3.0: + resolution: {integrity: sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==} + engines: {node: '>=12 <14 || 14.2 - 14.9 || >14.10.0'} + dependencies: + '@types/emscripten': 1.39.10 + tslib: 1.14.1 + dev: true + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: true + + /acorn-jsx@5.3.2(acorn@7.4.1): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 7.4.1 + dev: true + + /acorn-walk@7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn-walk@8.3.1: + resolution: {integrity: sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + dev: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-escapes@6.2.0: + resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==} + engines: {node: '>=14.16'} + dependencies: + type-fest: 3.13.1 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /app-root-dir@1.0.2: + resolution: {integrity: sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==} + dev: true + + /append-transform@2.0.0: + resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} + engines: {node: '>=8'} + dependencies: + default-require-extensions: 3.0.1 + dev: true + + /archy@1.0.0: + resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /aria-hidden@1.2.3: + resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==} + engines: {node: '>=10'} + dependencies: + tslib: 2.6.2 + dev: false + + /aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + dependencies: + deep-equal: 2.2.3 + dev: true + + /aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + dependencies: + dequal: 2.0.3 + dev: true + + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.5 + is-array-buffer: 3.0.2 + dev: true + + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /assert@2.1.0: + resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} + dependencies: + call-bind: 1.0.5 + is-nan: 1.3.2 + object-is: 1.1.5 + object.assign: 4.1.5 + util: 0.12.5 + dev: true + + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + + /ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.2 + dev: true + + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /axios@1.6.4: + resolution: {integrity: sha512-heJnIs6N4aa1eSthhN9M5ioILu8Wi8vmQW9iHQ9NUvfkJb0lEEDUiIdQNAuBtfUt3FxReaKdpQA5DbmMOqzF/A==} + dependencies: + follow-redirects: 1.15.4 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: true + + /babel-core@7.0.0-bridge.0(@babel/core@7.23.7): + resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + dev: true + + /babel-jest@29.7.0(@babel/core@7.23.7): + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.23.7 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.23.7) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.22.5 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.6 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.5 + dev: true + + /babel-plugin-polyfill-corejs2@0.4.7(@babel/core@7.23.7): + resolution: {integrity: sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.7 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.7) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3@0.8.7(@babel/core@7.23.7): + resolution: {integrity: sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.7) + core-js-compat: 3.35.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator@0.5.4(@babel/core@7.23.7): + resolution: {integrity: sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-define-polyfill-provider': 0.4.4(@babel/core@7.23.7) + transitivePeerDependencies: + - supports-color + dev: true + + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.7): + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.7) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.7) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.7) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.7) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.7) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.7) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.7) + dev: true + + /babel-preset-jest@29.6.3(@babel/core@7.23.7): + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.7) + dev: true + + /bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + dependencies: + open: 8.4.2 + dev: true + + /big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + dev: true + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /bplist-parser@0.2.0: + resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} + engines: {node: '>= 5.10.0'} + dependencies: + big-integer: 1.6.52 + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browser-assert@1.2.1: + resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + dev: true + + /browserify-zlib@0.1.4: + resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} + dependencies: + pako: 0.2.9 + dev: true + + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001572 + electron-to-chromium: 1.4.616 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) + dev: true + + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /bundle-require@4.0.2(esbuild@0.19.11): + resolution: {integrity: sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.17' + dependencies: + esbuild: 0.19.11 + load-tsconfig: 0.2.5 + dev: true + + /bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + dev: true + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: true + + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + + /caching-transform@4.0.0: + resolution: {integrity: sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==} + engines: {node: '>=8'} + dependencies: + hasha: 5.2.2 + make-dir: 3.1.0 + package-hash: 4.0.0 + write-file-atomic: 3.0.3 + dev: true + + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + dependencies: + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /can-bind-to-host@1.1.2: + resolution: {integrity: sha512-CqsgmaqiyFRNtP17Ihqa/uHbZxRirntNVNl/kJz31DLKuNRfzvzionkLoUSkElQ6Cz+cpXKA3mhHq4tjbieujA==} + hasBin: true + dev: true + + /caniuse-lite@1.0.30001572: + resolution: {integrity: sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==} + dev: true + + /ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + dev: true + + /chai@4.3.10: + resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /char-regex@2.0.1: + resolution: {integrity: sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==} + engines: {node: '>=12.20'} + dev: true + + /character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + dev: true + + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: true + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: true + + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: true + + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + dev: true + + /citty@0.1.5: + resolution: {integrity: sha512-AS7n5NSc0OQVMV9v6wt3ByujNIrne0/cTjiC2MYqhvao57VNfiuVksTSr2p17nVOhEr2KtqiAkGwHcgMC/qUuQ==} + dependencies: + consola: 3.2.3 + dev: true + + /cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + dev: true + + /cli-table3@0.6.3: + resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + engines: {node: 10.* || >= 12.*} + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + dev: true + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + dev: true + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: true + + /co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /commander@3.0.2: + resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} + dev: true + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + dev: true + + /commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + dev: true + + /commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + dev: true + + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + + /compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /compression@1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /concurrently@8.2.2: + resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==} + engines: {node: ^14.13.0 || >=16.0.0} + hasBin: true + dependencies: + chalk: 4.1.2 + date-fns: 2.30.0 + lodash: 4.17.21 + rxjs: 7.8.1 + shell-quote: 1.8.1 + spawn-command: 0.0.2 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + dev: true + + /consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + dev: true + + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: true + + /cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: true + + /core-js-compat@3.35.0: + resolution: {integrity: sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==} + dependencies: + browserslist: 4.22.2 + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@20.10.6) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + dev: true + + /css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + dev: true + + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + /cwd@0.10.0: + resolution: {integrity: sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==} + engines: {node: '>=0.8'} + dependencies: + find-pkg: 0.1.2 + fs-exists-sync: 0.1.0 + dev: true + + /date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + dependencies: + '@babel/runtime': 7.23.7 + dev: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + dependencies: + character-entities: 2.0.2 + dev: true + + /dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + dev: true + + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + + /deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.5 + es-get-iterator: 1.1.3 + get-intrinsic: 1.2.2 + is-arguments: 1.1.1 + is-array-buffer: 3.0.2 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + isarray: 2.0.5 + object-is: 1.1.5 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.1 + side-channel: 1.0.4 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.13 + dev: true + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + + /default-browser-id@3.0.0: + resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} + engines: {node: '>=12'} + dependencies: + bplist-parser: 0.2.0 + untildify: 4.0.0 + dev: true + + /default-require-extensions@3.0.1: + resolution: {integrity: sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==} + engines: {node: '>=8'} + dependencies: + strip-bom: 4.0.0 + dev: true + + /defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + dependencies: + clone: 1.0.4 + dev: true + + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 + object-keys: 1.1.1 + dev: true + + /defu@6.1.3: + resolution: {integrity: sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ==} + dev: true + + /del@6.1.1: + resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} + engines: {node: '>=10'} + dependencies: + globby: 11.1.0 + graceful-fs: 4.2.11 + is-glob: 4.0.3 + is-path-cwd: 2.2.0 + is-path-inside: 3.0.3 + p-map: 4.0.0 + rimraf: 3.0.2 + slash: 3.0.0 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: true + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: true + + /detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + + /detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dev: false + + /detect-package-manager@2.0.1: + resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} + engines: {node: '>=12'} + dependencies: + execa: 5.1.1 + dev: true + + /detect-port@1.5.1: + resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==} + hasBin: true + dependencies: + address: 1.2.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dependencies: + dequal: 2.0.3 + dev: true + + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /diffable-html@4.1.0: + resolution: {integrity: sha512-++kyNek+YBLH8cLXS+iTj/Hiy2s5qkRJEJ8kgu/WHbFrVY2vz9xPFUT+fii2zGF0m1CaojDlQJjkfrCt7YWM1g==} + dependencies: + htmlparser2: 3.10.1 + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dev: true + + /dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dev: true + + /dom-serializer@0.2.2: + resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} + dependencies: + domelementtype: 2.3.0 + entities: 2.2.0 + dev: true + + /domelementtype@1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} + dev: true + + /domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true + + /domhandler@2.4.2: + resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} + dependencies: + domelementtype: 1.3.1 + dev: true + + /domutils@1.7.0: + resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} + dependencies: + dom-serializer: 0.2.2 + domelementtype: 1.3.1 + dev: true + + /dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + dev: true + + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: true + + /duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.1 + dev: true + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: true + + /ejs@3.1.9: + resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.8.7 + dev: true + + /electron-to-chromium@1.4.616: + resolution: {integrity: sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==} + dev: true + + /emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: true + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: true + + /entities@1.1.2: + resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} + dev: true + + /entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + dev: true + + /envinfo@7.11.0: + resolution: {integrity: sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.2 + is-set: 2.0.2 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + dev: true + + /es-module-lexer@0.9.3: + resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} + dev: true + + /es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + requiresBuild: true + dev: true + + /esbuild-plugin-alias@0.2.1: + resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} + dev: true + + /esbuild-register@3.5.0(esbuild@0.18.20): + resolution: {integrity: sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.3.4 + esbuild: 0.18.20 + transitivePeerDependencies: + - supports-color + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + + /esbuild@0.19.11: + resolution: {integrity: sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.11 + '@esbuild/android-arm': 0.19.11 + '@esbuild/android-arm64': 0.19.11 + '@esbuild/android-x64': 0.19.11 + '@esbuild/darwin-arm64': 0.19.11 + '@esbuild/darwin-x64': 0.19.11 + '@esbuild/freebsd-arm64': 0.19.11 + '@esbuild/freebsd-x64': 0.19.11 + '@esbuild/linux-arm': 0.19.11 + '@esbuild/linux-arm64': 0.19.11 + '@esbuild/linux-ia32': 0.19.11 + '@esbuild/linux-loong64': 0.19.11 + '@esbuild/linux-mips64el': 0.19.11 + '@esbuild/linux-ppc64': 0.19.11 + '@esbuild/linux-riscv64': 0.19.11 + '@esbuild/linux-s390x': 0.19.11 + '@esbuild/linux-x64': 0.19.11 + '@esbuild/netbsd-x64': 0.19.11 + '@esbuild/openbsd-x64': 0.19.11 + '@esbuild/sunos-x64': 0.19.11 + '@esbuild/win32-arm64': 0.19.11 + '@esbuild/win32-ia32': 0.19.11 + '@esbuild/win32-x64': 0.19.11 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: true + + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.5 + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.2.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + + /exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /expand-tilde@1.2.2: + resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==} + engines: {node: '>=0.10.0'} + dependencies: + os-homedir: 1.0.2 + dev: true + + /expect-playwright@0.8.0: + resolution: {integrity: sha512-+kn8561vHAY+dt+0gMqqj1oY+g5xWrsuGMk4QGxotT2WS545nVqqjs37z6hrYfIuucwqthzwJfCJUEYqixyljg==} + dev: true + + /expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + dev: true + + /express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fastq@1.16.0: + resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==} + dependencies: + reusify: 1.0.4 + dev: true + + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + dev: true + + /fetch-retry@5.0.6: + resolution: {integrity: sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==} + dev: true + + /file-system-cache@2.3.0: + resolution: {integrity: sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ==} + dependencies: + fs-extra: 11.1.1 + ramda: 0.29.0 + dev: true + + /filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + dependencies: + minimatch: 5.1.6 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /find-cache-dir@2.1.0: + resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} + engines: {node: '>=6'} + dependencies: + commondir: 1.0.1 + make-dir: 2.1.0 + pkg-dir: 3.0.0 + dev: true + + /find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + dev: true + + /find-file-up@0.1.3: + resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==} + engines: {node: '>=0.10.0'} + dependencies: + fs-exists-sync: 0.1.0 + resolve-dir: 0.1.1 + dev: true + + /find-pkg@0.1.2: + resolution: {integrity: sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==} + engines: {node: '>=0.10.0'} + dependencies: + find-file-up: 0.1.3 + dev: true + + /find-process@1.4.7: + resolution: {integrity: sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==} + hasBin: true + dependencies: + chalk: 4.1.2 + commander: 5.1.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flow-parser@0.225.1: + resolution: {integrity: sha512-50fjR6zbLQcpq5IFNkheUSY/AFPxVeeLiBM5B3NQBSKId2G0cUuExOlDDOguxc49dl9lnh8hI1xcYlPJWNp4KQ==} + engines: {node: '>=0.4.0'} + dev: true + + /follow-redirects@1.15.4: + resolution: {integrity: sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@2.0.0: + resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} + engines: {node: '>=8.0.0'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 3.0.7 + dev: true + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: true + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: true + + /fromentries@1.3.2: + resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} + dev: true + + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: true + + /fs-exists-sync@0.1.0: + resolution: {integrity: sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==} + engines: {node: '>=0.10.0'} + dev: true + + /fs-extra@11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + dev: true + + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + dependencies: + function-bind: 1.1.2 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + dev: true + + /get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: false + + /get-npm-tarball-url@2.1.0: + resolution: {integrity: sha512-ro+DiMu5DXgRBabqXupW38h7WPZ9+Ad8UjwhvsmmN8w1sU7ab0nzAXvVZ4kqYg57OrqomRtJvepX5/xvFKNtjA==} + engines: {node: '>=12.17'} + dev: true + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + + /giget@1.2.1: + resolution: {integrity: sha512-4VG22mopWtIeHwogGSy1FViXVo0YT+m6BrqZfz0JJFwbSsePsCdOzdLIIli5BtMp7Xe8f/o2OmBpQX2NBOC24g==} + hasBin: true + dependencies: + citty: 0.1.5 + consola: 3.2.3 + defu: 6.1.3 + node-fetch-native: 1.6.1 + nypm: 0.3.4 + ohash: 1.1.3 + pathe: 1.1.1 + tar: 6.2.0 + dev: true + + /github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-promise@4.2.2(glob@7.2.3): + resolution: {integrity: sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==} + engines: {node: '>=12'} + peerDependencies: + glob: ^7.1.6 + dependencies: + '@types/glob': 7.2.0 + glob: 7.2.3 + dev: true + + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.3 + minipass: 7.0.4 + path-scurry: 1.10.1 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /global-modules@0.2.3: + resolution: {integrity: sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==} + engines: {node: '>=0.10.0'} + dependencies: + global-prefix: 0.1.5 + is-windows: 0.2.0 + dev: true + + /global-prefix@0.1.5: + resolution: {integrity: sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==} + engines: {node: '>=0.10.0'} + dependencies: + homedir-polyfill: 1.0.3 + ini: 1.3.8 + is-windows: 0.2.0 + which: 1.3.1 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.0 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /gunzip-maybe@1.4.2: + resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} + hasBin: true + dependencies: + browserify-zlib: 0.1.4 + is-deflate: 1.0.0 + is-gzip: 1.0.0 + peek-stream: 1.1.3 + pumpify: 1.5.1 + through2: 2.0.5 + dev: true + + /handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.17.4 + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + requiresBuild: true + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /hasha@5.2.2: + resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} + engines: {node: '>=8'} + dependencies: + is-stream: 2.0.1 + type-fest: 0.8.1 + dev: true + + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} + dependencies: + '@types/hast': 3.0.4 + dev: true + + /hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + dependencies: + '@types/hast': 3.0.4 + dev: true + + /hast-util-to-string@3.0.0: + resolution: {integrity: sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==} + dependencies: + '@types/hast': 3.0.4 + dev: true + + /homedir-polyfill@1.0.3: + resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} + engines: {node: '>=0.10.0'} + dependencies: + parse-passwd: 1.0.0 + dev: true + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + dev: true + + /htmlparser2@3.10.1: + resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} + dependencies: + domelementtype: 1.3.1 + domhandler: 2.4.2 + domutils: 1.7.0 + entities: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} + engines: {node: '>= 4'} + dev: true + + /import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + + /internal-slot@1.0.6: + resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + hasown: 2.0.0 + side-channel: 1.0.4 + dev: true + + /invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /ip@2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + dev: true + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: true + + /is-absolute-url@4.0.1: + resolution: {integrity: sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-typed-array: 1.1.12 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.0 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-deflate@1.0.0: + resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} + dev: true + + /is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-gzip@1.0.0: + resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + dev: true + + /is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + + /is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-path-cwd@2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + dev: true + + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + + /is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.5 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.13 + dev: true + + /is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + dev: true + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + + /is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + + /is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + dev: true + + /is-windows@0.2.0: + resolution: {integrity: sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==} + engines: {node: '>=0.10.0'} + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-hook@3.0.0: + resolution: {integrity: sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==} + engines: {node: '>=8'} + dependencies: + append-transform: 2.0.0 + dev: true + + /istanbul-lib-instrument@4.0.3: + resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.23.7 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.23.7 + '@babel/parser': 7.23.6 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-instrument@6.0.1: + resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} + engines: {node: '>=10'} + dependencies: + '@babel/core': 7.23.7 + '@babel/parser': 7.23.6 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-processinfo@2.0.3: + resolution: {integrity: sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==} + engines: {node: '>=8'} + dependencies: + archy: 1.0.0 + cross-spawn: 7.0.3 + istanbul-lib-coverage: 3.2.2 + p-map: 3.0.0 + rimraf: 3.0.2 + uuid: 8.3.2 + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + + /jake@10.8.7: + resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} + engines: {node: '>=10'} + hasBin: true + dependencies: + async: 3.2.5 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + dev: true + + /jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + dev: true + + /jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.1 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.0.4 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0 + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@20.10.6) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /jest-config@29.7.0(@types/node@20.10.6): + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.23.7 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + babel-jest: 29.7.0(@babel/core@7.23.7) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + dev: true + + /jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + + /jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 20.10.6 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /jest-junit@16.0.0: + resolution: {integrity: sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==} + engines: {node: '>=10.12.0'} + dependencies: + mkdirp: 1.0.4 + strip-ansi: 6.0.1 + uuid: 8.3.2 + xml: 1.0.1 + dev: true + + /jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + dev: true + + /jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.23.5 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + dev: true + + /jest-mock@27.5.1: + resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + '@types/node': 20.10.6 + dev: true + + /jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + jest-util: 29.7.0 + dev: true + + /jest-playwright-preset@4.0.0(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0): + resolution: {integrity: sha512-+dGZ1X2KqtwXaabVjTGxy0a3VzYfvYsWaRcuO8vMhyclHSOpGSI1+5cmlqzzCwQ3+fv0EjkTc7I5aV9lo08dYw==} + peerDependencies: + jest: ^29.3.1 + jest-circus: ^29.3.1 + jest-environment-node: ^29.3.1 + jest-runner: ^29.3.1 + dependencies: + expect-playwright: 0.8.0 + jest: 29.7.0 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-process-manager: 0.4.0 + jest-runner: 29.7.0 + nyc: 15.1.0 + playwright-core: 1.40.1 + rimraf: 3.0.2 + uuid: 8.3.2 + transitivePeerDependencies: + - debug + - supports-color + dev: true + + /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.7.0 + dev: true + + /jest-process-manager@0.4.0: + resolution: {integrity: sha512-80Y6snDyb0p8GG83pDxGI/kQzwVTkCxc7ep5FPe/F6JYdvRDhwr6RzRmPSP7SEwuLhxo80lBS/NqOdUIbHIfhw==} + dependencies: + '@types/wait-on': 5.3.4 + chalk: 4.1.2 + cwd: 0.10.0 + exit: 0.1.2 + find-process: 1.4.7 + prompts: 2.4.2 + signal-exit: 3.0.7 + spawnd: 5.0.0 + tree-kill: 1.2.2 + wait-on: 7.2.0 + transitivePeerDependencies: + - debug + - supports-color + dev: true + + /jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.8 + resolve.exports: 2.0.2 + slash: 3.0.0 + dev: true + + /jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + chalk: 4.1.2 + cjs-module-lexer: 1.2.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-serializer-html@7.1.0: + resolution: {integrity: sha512-xYL2qC7kmoYHJo8MYqJkzrl/Fdlx+fat4U1AqYg+kafqwcKPiMkOcjWHPKhueuNEgr+uemhGc+jqXYiwCyRyLA==} + dependencies: + diffable-html: 4.1.0 + dev: true + + /jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.23.7 + '@babel/generator': 7.23.6 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.7) + '@babel/types': 7.23.6 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.7) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + + /jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + dev: true + + /jest-watch-typeahead@2.2.2(jest@29.7.0): + resolution: {integrity: sha512-+QgOFW4o5Xlgd6jGS5X37i08tuuXNW8X0CV9WNFi+3n8ExCIP+E1melYhvYLjv5fE6D0yyzk74vsSO8I6GqtvQ==} + engines: {node: ^14.17.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + jest: ^27.0.0 || ^28.0.0 || ^29.0.0 + dependencies: + ansi-escapes: 6.2.0 + chalk: 5.3.0 + jest: 29.7.0 + jest-regex-util: 29.6.3 + jest-watcher: 29.7.0 + slash: 5.1.0 + string-length: 5.0.1 + strip-ansi: 7.1.0 + dev: true + + /jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.10.6 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + dev: true + + /jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 20.10.6 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.7.0 + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + dev: true + + /joi@17.11.0: + resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.4 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + dev: true + + /joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /jscodeshift@0.15.1(@babel/preset-env@7.23.7): + resolution: {integrity: sha512-hIJfxUy8Rt4HkJn/zZPU9ChKfKZM1342waJ1QC2e2YsPcWhM+3BJ4dcfQCzArTrk1jJeNLB341H+qOcEHRxJZg==} + hasBin: true + peerDependencies: + '@babel/preset-env': ^7.1.6 + peerDependenciesMeta: + '@babel/preset-env': + optional: true + dependencies: + '@babel/core': 7.23.7 + '@babel/parser': 7.23.6 + '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.23.7) + '@babel/preset-env': 7.23.7(@babel/core@7.23.7) + '@babel/preset-flow': 7.23.3(@babel/core@7.23.7) + '@babel/preset-typescript': 7.23.3(@babel/core@7.23.7) + '@babel/register': 7.23.7(@babel/core@7.23.7) + babel-core: 7.0.0-bridge.0(@babel/core@7.23.7) + chalk: 4.1.2 + flow-parser: 0.225.1 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + neo-async: 2.6.2 + node-dir: 0.1.17 + recast: 0.23.4 + temp: 0.8.4 + write-file-atomic: 2.4.3 + transitivePeerDependencies: + - supports-color + dev: true + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /lazy-universal-dotenv@4.0.0: + resolution: {integrity: sha512-aXpZJRnTkpK6gQ/z4nk+ZBLd/Qdp118cvPruLSIQzQNRhKwEcdXCOzXuF55VDqIiuAaY3UGZ10DJtvZzDcvsxg==} + engines: {node: '>=14.0.0'} + dependencies: + app-root-dir: 1.0.2 + dotenv: 16.3.1 + dotenv-expand: 10.0.0 + dev: true + + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + dependencies: + mlly: 1.4.2 + pkg-types: 1.0.3 + dev: true + + /locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.flattendeep@4.4.0: + resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} + dev: true + + /lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: true + + /longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + dev: true + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + dependencies: + get-func-name: 2.0.2 + dev: true + + /lru-cache@10.1.0: + resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} + engines: {node: 14 || >=16.14} + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + dev: true + + /magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /magic-string@0.30.5: + resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + dependencies: + pify: 4.0.1 + semver: 5.7.2 + dev: true + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.1 + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + + /map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + dev: true + + /markdown-table@3.0.3: + resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} + dev: true + + /markdown-to-jsx@7.3.2(react@18.2.0): + resolution: {integrity: sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q==} + engines: {node: '>= 10'} + peerDependencies: + react: '>= 0.14.0' + dependencies: + react: 18.2.0 + dev: true + + /mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + dependencies: + '@types/mdast': 4.0.3 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + dev: true + + /mdast-util-from-markdown@2.0.0: + resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + dependencies: + '@types/mdast': 4.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.1.0 + dev: true + + /mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + markdown-table: 3.0.3 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + dependencies: + mdast-util-from-markdown: 2.0.0 + mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-gfm-footnote: 2.0.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + dependencies: + '@types/mdast': 4.0.3 + unist-util-is: 6.0.0 + dev: true + + /mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-decode-string: 2.0.0 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + dev: true + + /mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + dependencies: + '@types/mdast': 4.0.3 + dev: true + + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: true + + /memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + dependencies: + map-or-similar: 1.5.0 + dev: true + + /merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: true + + /micromark-core-commonmark@2.0.0: + resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} + dependencies: + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-extension-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} + dependencies: + micromark-util-character: 2.1.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-extension-gfm-footnote@2.0.0: + resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-extension-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-extension-gfm-table@2.0.0: + resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + dependencies: + micromark-util-types: 2.0.0 + dev: true + + /micromark-extension-gfm-task-list-item@2.0.1: + resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + dependencies: + micromark-extension-gfm-autolink-literal: 2.0.0 + micromark-extension-gfm-footnote: 2.0.0 + micromark-extension-gfm-strikethrough: 2.0.0 + micromark-extension-gfm-table: 2.0.0 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.0.1 + micromark-util-combine-extensions: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + dependencies: + micromark-util-character: 2.1.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: true + + /micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + dependencies: + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: true + + /micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.1.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 + dev: true + + /micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + dev: true + + /micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + dev: true + + /micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: true + + /micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + dependencies: + micromark-util-types: 2.0.0 + dev: true + + /micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + dependencies: + micromark-util-character: 2.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + dev: true + + /micromark-util-subtokenize@2.0.0: + resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: true + + /micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + dev: true + + /micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + dev: true + + /micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.4 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + + /minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + dev: true + + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: true + + /mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /mlly@1.4.2: + resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.1 + pkg-types: 1.0.3 + ufo: 1.3.2 + dev: true + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: true + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /node-dir@0.1.17: + resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} + engines: {node: '>= 0.10.5'} + dependencies: + minimatch: 3.1.2 + dev: true + + /node-fetch-native@1.6.1: + resolution: {integrity: sha512-bW9T/uJDPAJB2YNYEpWzE54U5O3MQidXsOyTfnbKYtTtFexRvGzb1waphBN4ZwP6EcIvYYEOwW0b72BpAqydTw==} + dev: true + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + + /node-preload@0.2.1: + resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} + engines: {node: '>=8'} + dependencies: + process-on-spawn: 1.0.0 + dev: true + + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: true + + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /npm-run-path@5.2.0: + resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + + /nyc@15.1.0: + resolution: {integrity: sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==} + engines: {node: '>=8.9'} + hasBin: true + dependencies: + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + caching-transform: 4.0.0 + convert-source-map: 1.9.0 + decamelize: 1.2.0 + find-cache-dir: 3.3.2 + find-up: 4.1.0 + foreground-child: 2.0.0 + get-package-type: 0.1.0 + glob: 7.2.3 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-hook: 3.0.0 + istanbul-lib-instrument: 4.0.3 + istanbul-lib-processinfo: 2.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + make-dir: 3.1.0 + node-preload: 0.2.1 + p-map: 3.0.0 + process-on-spawn: 1.0.0 + resolve-from: 5.0.0 + rimraf: 3.0.2 + signal-exit: 3.0.7 + spawn-wrap: 2.0.0 + test-exclude: 6.0.0 + yargs: 15.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /nypm@0.3.4: + resolution: {integrity: sha512-1JLkp/zHBrkS3pZ692IqOaIKSYHmQXgqfELk6YTOfVBnwealAmPA1q2kKK7PHJAHSMBozerThEFZXP3G6o7Ukg==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + dependencies: + citty: 0.1.5 + execa: 8.0.1 + pathe: 1.1.1 + ufo: 1.3.2 + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + + /object-is@1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /ohash@1.1.3: + resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + dev: true + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: true + + /on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + + /ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: true + + /os-homedir@1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + dependencies: + yocto-queue: 1.0.0 + dev: true + + /p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map@3.0.0: + resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} + engines: {node: '>=8'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /package-hash@4.0.0: + resolution: {integrity: sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==} + engines: {node: '>=8'} + dependencies: + graceful-fs: 4.2.11 + hasha: 5.2.2 + lodash.flattendeep: 4.4.0 + release-zalgo: 1.0.0 + dev: true + + /pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.23.5 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parse-passwd@1.0.0: + resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} + engines: {node: '>=0.10.0'} + dev: true + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: true + + /path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.1.0 + minipass: 7.0.4 + dev: true + + /path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /pathe@1.1.1: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + + /peek-stream@1.1.3: + resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} + dependencies: + buffer-from: 1.1.2 + duplexify: 3.7.1 + through2: 2.0.5 + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + dev: true + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /pkg-dir@3.0.0: + resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} + engines: {node: '>=6'} + dependencies: + find-up: 3.0.0 + dev: true + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /pkg-dir@5.0.0: + resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} + engines: {node: '>=10'} + dependencies: + find-up: 5.0.0 + dev: true + + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.4.2 + pathe: 1.1.1 + dev: true + + /playwright-core@1.40.1: + resolution: {integrity: sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ==} + engines: {node: '>=16'} + hasBin: true + dev: true + + /playwright-core@1.41.2: + resolution: {integrity: sha512-VaTvwCA4Y8kxEe+kfm2+uUUw5Lubf38RxF7FpBxLPmGe5sdNkSg5e3ChEigaGrX7qdqT3pt2m/98LiyvU2x6CA==} + engines: {node: '>=16'} + hasBin: true + dev: true + + /playwright@1.40.1: + resolution: {integrity: sha512-2eHI7IioIpQ0bS1Ovg/HszsN/XKNwEG1kbzSDDmADpclKc7CyqkHw7Mg2JCz/bbCxg25QUPcjksoMW7JcIFQmw==} + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright-core: 1.40.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /playwright@1.41.2: + resolution: {integrity: sha512-v0bOa6H2GJChDL8pAeLa/LZC4feoAMbSQm1/jF/ySsWWoaNItvrMP7GEkvEEFyCTUYKMxjQKaTSg5up7nR6/8A==} + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright-core: 1.41.2 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /polished@4.2.2: + resolution: {integrity: sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ==} + engines: {node: '>=10'} + dependencies: + '@babel/runtime': 7.23.7 + dev: true + + /postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 3.0.0 + yaml: 2.3.4 + dev: true + + /postcss@8.4.32: + resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + dev: true + + /pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + + /pretty-hrtime@1.0.3: + resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} + engines: {node: '>= 0.8'} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /process-on-spawn@1.0.0: + resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} + engines: {node: '>=8'} + dependencies: + fromentries: 1.3.2 + dev: true + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: true + + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: true + + /pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + dev: true + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /pure-rand@6.0.4: + resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==} + dev: true + + /qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /qs@6.11.2: + resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /ramda@0.29.0: + resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==} + dev: true + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: true + + /raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: true + + /react-colorful@5.6.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /react-confetti@6.1.0(react@18.2.0): + resolution: {integrity: sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==} + engines: {node: '>=10.18'} + peerDependencies: + react: ^16.3.0 || ^17.0.1 || ^18.0.0 + dependencies: + react: 18.2.0 + tween-functions: 1.2.0 + dev: true + + /react-docgen-typescript@2.2.2(typescript@5.3.3): + resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} + peerDependencies: + typescript: '>= 4.3.x' + dependencies: + typescript: 5.3.3 + dev: true + + /react-docgen@7.0.1: + resolution: {integrity: sha512-rCz0HBIT0LWbIM+///LfRrJoTKftIzzwsYDf0ns5KwaEjejMHQRtphcns+IXFHDNY9pnz6G8l/JbbI6pD4EAIA==} + engines: {node: '>=16.14.0'} + dependencies: + '@babel/core': 7.23.7 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.5 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.8 + strip-indent: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /react-dom@18.2.0(react@18.2.0): + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + + /react-element-to-jsx-string@15.0.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==} + peerDependencies: + react: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 + react-dom: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 + dependencies: + '@base2/pretty-print-object': 1.0.1 + is-plain-object: 5.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.1.0 + dev: true + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /react-is@18.1.0: + resolution: {integrity: sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==} + dev: true + + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + + /react-remove-scroll-bar@2.3.4(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.46 + react: 18.2.0 + react-style-singleton: 2.2.1(@types/react@18.2.46)(react@18.2.0) + tslib: 2.6.2 + dev: false + + /react-remove-scroll@2.5.5(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.46 + react: 18.2.0 + react-remove-scroll-bar: 2.3.4(@types/react@18.2.46)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.46)(react@18.2.0) + tslib: 2.6.2 + use-callback-ref: 1.3.1(@types/react@18.2.46)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.46)(react@18.2.0) + dev: false + + /react-style-singleton@2.2.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.46 + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /recast@0.23.4: + resolution: {integrity: sha512-qtEDqIZGVcSZCHniWwZWbRy79Dc6Wp3kT/UmDA2RJKBPg7+7k51aQBZirHmUGn5uvHf2rg8DkjizrN26k61ATw==} + engines: {node: '>= 4'} + dependencies: + assert: 2.1.0 + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tslib: 2.6.2 + dev: true + + /redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + + /regenerate-unicode-properties@10.1.1: + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + /regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + dependencies: + '@babel/runtime': 7.23.7 + dev: true + + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + set-function-name: 2.0.1 + dev: true + + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /rehype-external-links@3.0.0: + resolution: {integrity: sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==} + dependencies: + '@types/hast': 3.0.4 + '@ungap/structured-clone': 1.2.0 + hast-util-is-element: 3.0.0 + is-absolute-url: 4.0.1 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.0.0 + dev: true + + /rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} + dependencies: + '@types/hast': 3.0.4 + github-slugger: 2.0.0 + hast-util-heading-rank: 3.0.0 + hast-util-to-string: 3.0.0 + unist-util-visit: 5.0.0 + dev: true + + /release-zalgo@1.0.0: + resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} + engines: {node: '>=4'} + dependencies: + es6-error: 4.1.1 + dev: true + + /remark-gfm@4.0.0: + resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-gfm: 3.0.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + micromark-util-types: 2.0.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-to-markdown: 2.1.0 + unified: 11.0.4 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + + /resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-dir@0.1.1: + resolution: {integrity: sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==} + engines: {node: '>=0.10.0'} + dependencies: + expand-tilde: 1.2.2 + global-modules: 0.2.3 + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + dev: true + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@2.6.3: + resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup@4.9.2: + resolution: {integrity: sha512-66RB8OtFKUTozmVEh3qyNfH+b+z2RXBVloqO2KCC/pjFaGaHtxP9fVfOQKPSGXg2mElmjmxjW/fZ7iKrEpMH5Q==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.9.2 + '@rollup/rollup-android-arm64': 4.9.2 + '@rollup/rollup-darwin-arm64': 4.9.2 + '@rollup/rollup-darwin-x64': 4.9.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.9.2 + '@rollup/rollup-linux-arm64-gnu': 4.9.2 + '@rollup/rollup-linux-arm64-musl': 4.9.2 + '@rollup/rollup-linux-riscv64-gnu': 4.9.2 + '@rollup/rollup-linux-x64-gnu': 4.9.2 + '@rollup/rollup-linux-x64-musl': 4.9.2 + '@rollup/rollup-win32-arm64-msvc': 4.9.2 + '@rollup/rollup-win32-ia32-msvc': 4.9.2 + '@rollup/rollup-win32-x64-msvc': 4.9.2 + fsevents: 2.3.3 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.6.2 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + dependencies: + loose-envify: 1.4.0 + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.1 + dev: true + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: true + + /shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + dependencies: + kind-of: 6.0.3 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 + dev: true + + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + + /space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + dev: true + + /spawn-command@0.0.2: + resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} + dev: true + + /spawn-wrap@2.0.0: + resolution: {integrity: sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==} + engines: {node: '>=8'} + dependencies: + foreground-child: 2.0.0 + is-windows: 1.0.2 + make-dir: 3.1.0 + rimraf: 3.0.2 + signal-exit: 3.0.7 + which: 2.0.2 + dev: true + + /spawnd@5.0.0: + resolution: {integrity: sha512-28+AJr82moMVWolQvlAIv3JcYDkjkFTEmfDc503wxrF5l2rQ3dFz6DpbXp3kD4zmgGGldfM4xM4v1sFj/ZaIOA==} + dependencies: + exit: 0.1.2 + signal-exit: 3.0.7 + tree-kill: 1.2.2 + wait-port: 0.2.14 + transitivePeerDependencies: + - supports-color + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-license-ids@3.0.16: + resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: true + + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + dev: true + + /stop-iteration-iterator@1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + dependencies: + internal-slot: 1.0.6 + dev: true + + /store2@2.14.2: + resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==} + dev: true + + /storybook@8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-a4Z5U4lGYi6UmBpDvxqiRO5YwPnnYP/aC+YkhlXBIlM2J/+jfRhkKdoyNPBzbwfKEDhEdGasg3KmEtkUthBeLg==} + hasBin: true + dependencies: + '@storybook/cli': 8.0.0-beta.3(react-dom@18.2.0)(react@18.2.0) + transitivePeerDependencies: + - '@babel/preset-env' + - bufferutil + - encoding + - react + - react-dom + - supports-color + - utf-8-validate + dev: true + + /stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + dev: true + + /string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + + /string-length@5.0.1: + resolution: {integrity: sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==} + engines: {node: '>=12.20'} + dependencies: + char-regex: 2.0.1 + strip-ansi: 7.1.0 + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + dependencies: + acorn: 8.11.3 + dev: true + + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + commander: 4.1.1 + glob: 10.3.10 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /synchronous-promise@2.0.17: + resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} + dev: true + + /tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: true + + /tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /tar@6.2.0: + resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: true + + /telejson@7.2.0: + resolution: {integrity: sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==} + dependencies: + memoizerific: 1.11.3 + dev: true + + /temp-dir@2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + dev: true + + /temp@0.8.4: + resolution: {integrity: sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==} + engines: {node: '>=6.0.0'} + dependencies: + rimraf: 2.6.3 + dev: true + + /tempy@1.0.1: + resolution: {integrity: sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==} + engines: {node: '>=10'} + dependencies: + del: 6.1.1 + is-stream: 2.0.1 + temp-dir: 2.0.0 + type-fest: 0.16.0 + unique-string: 2.0.0 + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + dev: true + + /tiny-invariant@1.3.1: + resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} + dev: true + + /tinybench@2.5.1: + resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==} + dev: true + + /tinypool@0.8.1: + resolution: {integrity: sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@2.2.0: + resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} + engines: {node: '>=14.0.0'} + dev: true + + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tocbot@4.25.0: + resolution: {integrity: sha512-kE5wyCQJ40hqUaRVkyQ4z5+4juzYsv/eK+aqD97N62YH0TxFhzJvo22RUQQZdO3YnXAk42ZOfOpjVdy+Z0YokA==} + dev: true + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + + /tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.3.1 + dev: true + + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + + /trough@2.1.0: + resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} + dev: true + + /ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + dev: true + + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + /tsup@8.0.1(@swc/core@1.3.102)(typescript@5.3.3): + resolution: {integrity: sha512-hvW7gUSG96j53ZTSlT4j/KL0q1Q2l6TqGBFc6/mu/L46IoNWqLLUzLRLP1R8Q7xrJTmkDxxDoojV5uCVs1sVOg==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + dependencies: + '@swc/core': 1.3.102 + bundle-require: 4.0.2(esbuild@0.19.11) + cac: 6.7.14 + chokidar: 3.5.3 + debug: 4.3.4 + esbuild: 0.19.11 + execa: 5.1.1 + globby: 11.1.0 + joycon: 3.1.1 + postcss-load-config: 4.0.2 + resolve-from: 5.0.0 + rollup: 4.9.2 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tree-kill: 1.2.2 + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + + /tween-functions@1.2.0: + resolution: {integrity: sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==} + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.16.0: + resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: true + + /type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + dev: true + + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + dev: true + + /typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 + dev: true + + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} + dev: true + + /uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + engines: {node: '>=0.8.0'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /unified@11.0.4: + resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + dependencies: + '@types/unist': 3.0.2 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.1.0 + vfile: 6.0.1 + dev: true + + /unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + dependencies: + crypto-random-string: 2.0.0 + dev: true + + /unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + dependencies: + '@types/unist': 3.0.2 + dev: true + + /unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + dependencies: + '@types/unist': 3.0.2 + dev: true + + /unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + dev: true + + /unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + dev: true + + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: true + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: true + + /unplugin@1.6.0: + resolution: {integrity: sha512-BfJEpWBu3aE/AyHx8VaNE/WgouoQxgH9baAiH82JjX8cqVyi3uJQstqwD5J+SZxIK326SZIhsSZlALXVBCknTQ==} + dependencies: + acorn: 8.11.3 + chokidar: 3.5.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.6.1 + dev: true + + /untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + dev: true + + /update-browserslist-db@1.0.13(browserslist@4.22.2): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.22.2 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /use-callback-ref@1.3.1(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.46 + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /use-sidecar@1.1.2(@types/react@18.2.46)(react@18.2.0): + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.46 + detect-node-es: 1.1.0 + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.12 + which-typed-array: 1.1.13 + dev: true + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: true + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: true + + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: true + + /v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.20 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: true + + /vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + dev: true + + /vfile@6.0.1: + resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + dev: true + + /vite-node@1.1.0: + resolution: {integrity: sha512-jV48DDUxGLEBdHCQvxL1mEh7+naVy+nhUUUaPAZLd3FJgXuxQiewHcfeZebbJ6onDqNGkP4r3MhQ342PRlG81Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 5.0.10 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite@5.0.10: + resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.19.11 + postcss: 8.4.32 + rollup: 4.9.2 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vitest@1.1.0: + resolution: {integrity: sha512-oDFiCrw7dd3Jf06HoMtSRARivvyjHJaTxikFxuqJjO76U436PqlVw1uLn7a8OSPrhSfMGVaRakKpA2lePdw79A==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': ^1.0.0 + '@vitest/ui': ^1.0.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@vitest/expect': 1.1.0 + '@vitest/runner': 1.1.0 + '@vitest/snapshot': 1.1.0 + '@vitest/spy': 1.1.0 + '@vitest/utils': 1.1.0 + acorn-walk: 8.3.1 + cac: 6.7.14 + chai: 4.3.10 + debug: 4.3.4 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.5 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 1.3.0 + tinybench: 2.5.1 + tinypool: 0.8.1 + vite: 5.0.10 + vite-node: 1.1.0 + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /wait-on@7.2.0: + resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + axios: 1.6.4 + joi: 17.11.0 + lodash: 4.17.21 + minimist: 1.2.8 + rxjs: 7.8.1 + transitivePeerDependencies: + - debug + dev: true + + /wait-port@0.2.14: + resolution: {integrity: sha512-kIzjWcr6ykl7WFbZd0TMae8xovwqcqbx6FM9l+7agOgUByhzdjfzZBPK2CPufldTOMxbUivss//Sh9MFawmPRQ==} + engines: {node: '>=8'} + hasBin: true + dependencies: + chalk: 2.4.2 + commander: 3.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /watchpack@2.4.0: + resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + dev: true + + /wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.4 + dev: true + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + + /webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack-virtual-modules@0.6.1: + resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==} + dev: true + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + + /whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + + /wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + dev: true + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + dev: true + + /write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xml@1.0.1: + resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} + dev: true + + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + engines: {node: '>= 14'} + dev: true + + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + + /zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + dev: true diff --git a/src/README.mdx b/src/README.mdx new file mode 100644 index 0000000..240dc40 --- /dev/null +++ b/src/README.mdx @@ -0,0 +1,40 @@ +{/* http://localhost:6006/iframe.html?args=&id=readme--documentation&viewMode=docs */} + +import { README } from "./docs/README"; +import { Source } from "@storybook/blocks"; + + +<README > + +## Installation + +A quick tutorial on how to use the package + +### 1. Install the package + +Install the package using your package manager of choice + +<Source code={`pnpm add cmpui`} language="bash" dark /> + +### 2. Import the component and the styles + +Import the component and the styles in your project + +<Source code={` +import { Button } from 'cmpui' +import 'cmpui/dist/index.css' + +export default function App() { + return ( + <div> + <Button>Click me</Button> + </div> + ) +} +`} language="tsx" dark /> + +### 3. Enjoy + +You can now use the component in your project + +</README> diff --git a/src/__stories__/Icon.tsx b/src/__stories__/Icon.tsx new file mode 100644 index 0000000..1436f51 --- /dev/null +++ b/src/__stories__/Icon.tsx @@ -0,0 +1,25 @@ +export function Icon({ + name, + filled, + style, + size, + ...props +}: { + name: string; + filled?: boolean; + size?: number; +} & React.HTMLAttributes<HTMLSpanElement>) { + return ( + <span + className="material-symbols-outlined" + data-filled={filled} + {...props} + style={{ + fontSize: size, + ...style, + }} + > + {name} + </span> + ); +} diff --git a/src/__stories__/Panel.tsx b/src/__stories__/Panel.tsx new file mode 100644 index 0000000..efb3823 --- /dev/null +++ b/src/__stories__/Panel.tsx @@ -0,0 +1,46 @@ +export const Panel = ( + props: { + color: string; + name: string; + } & React.HTMLAttributes<HTMLDivElement>, +) => { + return ( + <div + style={{ + background: props.color, + width: "100%", + height: "100%", + display: "flex", + overflow: "auto", + position: "relative", + }} + {...props} + > + <div + style={{ + width: "100%", + pointerEvents: "none", + height: "100%", + display: "flex", + justifyContent: "center", + alignItems: "center", + color: "white", + fontSize: "32px", + position: "absolute", + }} + > + {props.name} + </div> + {/* <pre + style={{ + fontSize: "12px", + fontFamily: "monospace", + margin: 0, + padding: 8, + }} + > + <code>{JSON.stringify(node?.node.toJson(), null, 4)}</code> + </pre> */} + </div> + ); +}; diff --git a/src/__stories__/Root.tsx b/src/__stories__/Root.tsx new file mode 100644 index 0000000..97413c0 --- /dev/null +++ b/src/__stories__/Root.tsx @@ -0,0 +1,15 @@ +export const Root = (props: { children: React.ReactNode }) => { + return ( + <div + style={{ + height: "512px", + width: "100vw", + display: "flex", + padding: "4px", + boxSizing: "border-box", + }} + > + {props.children} + </div> + ); +}; diff --git a/src/__stories__/ShortcutListItem.tsx b/src/__stories__/ShortcutListItem.tsx new file mode 100644 index 0000000..5804562 --- /dev/null +++ b/src/__stories__/ShortcutListItem.tsx @@ -0,0 +1,33 @@ +import { ListItem } from ".."; +import "./stories.css"; + +export function ShortcutListItem({ + disabled, + shortcut, + as = ListItem, + children, + ...props +}: { + children: React.ReactNode; + shortcut?: string; + disabled?: boolean; + as?: React.ElementType; +} & React.ComponentProps<typeof ListItem>) { + const Component = as; + return ( + <Component disabled={disabled} className="shortcut-list-item" {...props}> + <div style={{ width: "100%" }}>{children}</div> + {shortcut && ( + <div + style={{ + fontSize: "10px", + marginLeft: 16, + whiteSpace: "nowrap", + }} + > + {shortcut} + </div> + )} + </Component> + ); +} diff --git a/src/__stories__/stories.css b/src/__stories__/stories.css new file mode 100644 index 0000000..0277e0d --- /dev/null +++ b/src/__stories__/stories.css @@ -0,0 +1,11 @@ +.shortcut-list-item:not([data-disabled]) > div + div { + color: var(--cmpui-text2-color); +} + +.shortcut-list-item:not([data-disabled]):hover > div + div { + color: var(--cmpui-text2-color); +} + +.shortcut-list-item:not([data-disabled])[data-highlighted] > div + div { + color: white; +} diff --git a/src/components/AngleInput/__snapshots__/index.stories.tsx.snap b/src/components/AngleInput/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..c86026a --- /dev/null +++ b/src/components/AngleInput/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,587 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Form/AngleInput Basic smoke-test 1`] = ` +<div class="cmpui_angle-input__root" + style="width: 64px; height: 64px;" +> + <svg width="64" + height="64" + viewbox="0 0 64 64" + > + <circle cx="32" + cy="32" + r="31" + stroke="var(--cmpui-border-color)" + fill="none" + stroke-width="1" + > + </circle> + </svg> + <svg width="5" + height="1" + viewbox="0 0 5 1" + style="position: absolute; overflow: visible; pointer-events: none; left: 55.5px; top: 31.5px;" + > + <line x1="0.5" + y1="0.5" + x2="4.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="4.464101615137757" + height="3" + viewbox="0 0 4.464101615137757 3" + style="position: absolute; overflow: visible; pointer-events: none; left: 52.2846px; top: 43.5px;" + > + <line x1="0.5" + y1="0.5" + x2="3.964101615137757" + y2="2.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3" + height="4.46410161513775" + viewbox="0 0 3 4.46410161513775" + style="position: absolute; overflow: visible; pointer-events: none; left: 43.5px; top: 52.2846px;" + > + <line x1="0.5" + y1="0.5" + x2="2.5" + y2="3.96410161513775" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="1" + height="5" + viewbox="0 0 1 5" + style="position: absolute; overflow: visible; pointer-events: none; left: 31.5px; top: 55.5px;" + > + <line x1="0.5" + y1="0.5" + x2="0.5" + y2="4.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3" + height="4.464101615137757" + viewbox="0 0 3 4.464101615137757" + style="position: absolute; overflow: visible; pointer-events: none; left: 17.5px; top: 52.2846px;" + > + <line x1="2.5" + y1="0.5" + x2="0.5" + y2="3.964101615137757" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="4.464101615137757" + height="3" + viewbox="0 0 4.464101615137757 3" + style="position: absolute; overflow: visible; pointer-events: none; left: 7.25129px; top: 43.5px;" + > + <line x1="3.964101615137757" + y1="0.5" + x2="0.5" + y2="2.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="5" + height="1" + viewbox="0 0 5 1" + style="position: absolute; overflow: visible; pointer-events: none; left: 3.5px; top: 31.5px;" + > + <line x1="4.5" + y1="0.5" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="4.4641016151377535" + height="3" + viewbox="0 0 4.4641016151377535 3" + style="position: absolute; overflow: visible; pointer-events: none; left: 7.25129px; top: 17.5px;" + > + <line x1="3.9641016151377535" + y1="2.5" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3.0000000000000036" + height="4.4641016151377535" + viewbox="0 0 3.0000000000000036 4.4641016151377535" + style="position: absolute; overflow: visible; pointer-events: none; left: 17.5px; top: 7.25129px;" + > + <line x1="2.5000000000000036" + y1="3.9641016151377535" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="1" + height="5" + viewbox="0 0 1 5" + style="position: absolute; overflow: visible; pointer-events: none; left: 31.5px; top: 3.5px;" + > + <line x1="0.5" + y1="4.5" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3" + height="4.4641016151377535" + viewbox="0 0 3 4.4641016151377535" + style="position: absolute; overflow: visible; pointer-events: none; left: 43.5px; top: 7.25129px;" + > + <line x1="0.5" + y1="3.9641016151377535" + x2="2.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="4.464101615137757" + height="3.0000000000000036" + viewbox="0 0 4.464101615137757 3.0000000000000036" + style="position: absolute; overflow: visible; pointer-events: none; left: 52.2846px; top: 17.5px;" + > + <line x1="0.5" + y1="2.5000000000000036" + x2="3.964101615137757" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="31" + height="1" + viewbox="0 0 31 1" + style="position: absolute; overflow: visible; pointer-events: none; left: 31.5px; top: 31.5px;" + > + <line x1="0.5" + y1="0.5" + x2="30.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-primary-color)" + > + </line> + </svg> + <div x="62" + y="32" + class="cmpui_circle__root cmpui_angle-input__nob" + style="--cmpui-circle-nob-radius: 8px; --cmpui-circle-nob-stroke-width: 0px; left: 54px; top: 24px;" + > + </div> + <div x="32" + y="32" + class="cmpui_circle__root" + style="--cmpui-circle-nob-fill: var(--cmpui-primary-color); --cmpui-circle-nob-radius: 2px; --cmpui-circle-nob-stroke-color: transparent; --cmpui-circle-nob-stroke-width: 0px; border: 0px solid transparent; left: 30px; top: 30px;" + > + </div> +</div> +`; + +exports[`Components/Form/AngleInput Size smoke-test 1`] = ` +<div class="cmpui_angle-input__root" + style="width: 128px; height: 128px;" +> + <svg width="128" + height="128" + viewbox="0 0 128 128" + > + <circle cx="64" + cy="64" + r="63" + stroke="var(--cmpui-border-color)" + fill="none" + stroke-width="1" + > + </circle> + </svg> + <svg width="5" + height="1" + viewbox="0 0 5 1" + style="position: absolute; overflow: visible; pointer-events: none; left: 119.5px; top: 63.5px;" + > + <line x1="0.5" + y1="0.5" + x2="4.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="4.46410161513775" + height="3" + viewbox="0 0 4.46410161513775 3" + style="position: absolute; overflow: visible; pointer-events: none; left: 111.997px; top: 91.5px;" + > + <line x1="0.5" + y1="0.5" + x2="3.96410161513775" + y2="2.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3" + height="4.464101615137764" + viewbox="0 0 3 4.464101615137764" + style="position: absolute; overflow: visible; pointer-events: none; left: 91.5px; top: 111.997px;" + > + <line x1="0.5" + y1="0.5" + x2="2.5" + y2="3.964101615137764" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="1" + height="5" + viewbox="0 0 1 5" + style="position: absolute; overflow: visible; pointer-events: none; left: 63.5px; top: 119.5px;" + > + <line x1="0.5" + y1="0.5" + x2="0.5" + y2="4.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3" + height="4.46410161513775" + viewbox="0 0 3 4.46410161513775" + style="position: absolute; overflow: visible; pointer-events: none; left: 33.5px; top: 111.997px;" + > + <line x1="2.5" + y1="0.5" + x2="0.5" + y2="3.96410161513775" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="4.46410161513775" + height="3" + viewbox="0 0 4.46410161513775 3" + style="position: absolute; overflow: visible; pointer-events: none; left: 11.5385px; top: 91.5px;" + > + <line x1="3.96410161513775" + y1="0.5" + x2="0.5" + y2="2.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="5" + height="1.0000000000000142" + viewbox="0 0 5 1.0000000000000142" + style="position: absolute; overflow: visible; pointer-events: none; left: 3.5px; top: 63.5px;" + > + <line x1="4.5" + y1="0.5" + x2="0.5" + y2="0.5000000000000142" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="4.464101615137757" + height="3" + viewbox="0 0 4.464101615137757 3" + style="position: absolute; overflow: visible; pointer-events: none; left: 11.5385px; top: 33.5px;" + > + <line x1="3.964101615137757" + y1="2.5" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3" + height="4.464101615137757" + viewbox="0 0 3 4.464101615137757" + style="position: absolute; overflow: visible; pointer-events: none; left: 33.5px; top: 11.5385px;" + > + <line x1="2.5" + y1="3.964101615137757" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="1.000000000000007" + height="5" + viewbox="0 0 1.000000000000007 5" + style="position: absolute; overflow: visible; pointer-events: none; left: 63.5px; top: 3.5px;" + > + <line x1="0.5000000000000071" + y1="4.5" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3" + height="4.46410161513775" + viewbox="0 0 3 4.46410161513775" + style="position: absolute; overflow: visible; pointer-events: none; left: 91.5px; top: 11.5385px;" + > + <line x1="0.5" + y1="3.96410161513775" + x2="2.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="4.46410161513775" + height="3" + viewbox="0 0 4.46410161513775 3" + style="position: absolute; overflow: visible; pointer-events: none; left: 111.997px; top: 33.5px;" + > + <line x1="0.5" + y1="2.5" + x2="3.96410161513775" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="63" + height="1" + viewbox="0 0 63 1" + style="position: absolute; overflow: visible; pointer-events: none; left: 63.5px; top: 63.5px;" + > + <line x1="0.5" + y1="0.5" + x2="62.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-primary-color)" + > + </line> + </svg> + <div x="126" + y="64" + class="cmpui_circle__root cmpui_angle-input__nob" + style="--cmpui-circle-nob-radius: 12px; --cmpui-circle-nob-stroke-width: 0px; left: 114px; top: 52px;" + > + </div> + <div x="64" + y="64" + class="cmpui_circle__root" + style="--cmpui-circle-nob-fill: var(--cmpui-primary-color); --cmpui-circle-nob-radius: 2px; --cmpui-circle-nob-stroke-color: transparent; --cmpui-circle-nob-stroke-width: 0px; border: 0px solid transparent; left: 62px; top: 62px;" + > + </div> +</div> +`; + +exports[`Components/Form/AngleInput Step smoke-test 1`] = ` +<div class="cmpui_angle-input__root" + style="width: 64px; height: 64px;" +> + <svg width="64" + height="64" + viewbox="0 0 64 64" + > + <circle cx="32" + cy="32" + r="31" + stroke="var(--cmpui-border-color)" + fill="none" + stroke-width="1" + > + </circle> + </svg> + <svg width="5" + height="1" + viewbox="0 0 5 1" + style="position: absolute; overflow: visible; pointer-events: none; left: 55.5px; top: 31.5px;" + > + <line x1="0.5" + y1="0.5" + x2="4.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3.8284271247461916" + height="3.8284271247461916" + viewbox="0 0 3.8284271247461916 3.8284271247461916" + style="position: absolute; overflow: visible; pointer-events: none; left: 48.4706px; top: 48.4706px;" + > + <line x1="0.5" + y1="0.5" + x2="3.3284271247461916" + y2="3.3284271247461916" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="1" + height="5" + viewbox="0 0 1 5" + style="position: absolute; overflow: visible; pointer-events: none; left: 31.5px; top: 55.5px;" + > + <line x1="0.5" + y1="0.5" + x2="0.5" + y2="4.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3.828427124746188" + height="3.8284271247461916" + viewbox="0 0 3.828427124746188 3.8284271247461916" + style="position: absolute; overflow: visible; pointer-events: none; left: 11.701px; top: 48.4706px;" + > + <line x1="3.328427124746188" + y1="0.5" + x2="0.5" + y2="3.3284271247461916" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="5" + height="1" + viewbox="0 0 5 1" + style="position: absolute; overflow: visible; pointer-events: none; left: 3.5px; top: 31.5px;" + > + <line x1="4.5" + y1="0.5" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3.8284271247461916" + height="3.828427124746188" + viewbox="0 0 3.8284271247461916 3.828427124746188" + style="position: absolute; overflow: visible; pointer-events: none; left: 11.701px; top: 11.701px;" + > + <line x1="3.3284271247461916" + y1="3.328427124746188" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="1" + height="5" + viewbox="0 0 1 5" + style="position: absolute; overflow: visible; pointer-events: none; left: 31.5px; top: 3.5px;" + > + <line x1="0.5" + y1="4.5" + x2="0.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="3.8284271247461916" + height="3.8284271247461916" + viewbox="0 0 3.8284271247461916 3.8284271247461916" + style="position: absolute; overflow: visible; pointer-events: none; left: 48.4706px; top: 11.701px;" + > + <line x1="0.5" + y1="3.3284271247461916" + x2="3.3284271247461916" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-border-color)" + > + </line> + </svg> + <svg width="31" + height="1" + viewbox="0 0 31 1" + style="position: absolute; overflow: visible; pointer-events: none; left: 31.5px; top: 31.5px;" + > + <line x1="0.5" + y1="0.5" + x2="30.5" + y2="0.5" + stroke-width="1" + stroke="var(--cmpui-primary-color)" + > + </line> + </svg> + <div x="62" + y="32" + class="cmpui_circle__root cmpui_angle-input__nob" + style="--cmpui-circle-nob-radius: 8px; --cmpui-circle-nob-stroke-width: 0px; left: 54px; top: 24px;" + > + </div> + <div x="32" + y="32" + class="cmpui_circle__root" + style="--cmpui-circle-nob-fill: var(--cmpui-primary-color); --cmpui-circle-nob-radius: 2px; --cmpui-circle-nob-stroke-color: transparent; --cmpui-circle-nob-stroke-width: 0px; border: 0px solid transparent; left: 30px; top: 30px;" + > + </div> +</div> +`; diff --git a/src/components/AngleInput/index.css b/src/components/AngleInput/index.css new file mode 100644 index 0000000..1a1c657 --- /dev/null +++ b/src/components/AngleInput/index.css @@ -0,0 +1,18 @@ +.cmpui_angle-input__root { + --cmpui-circle-nob-radius: 6px; + --cmpui-circle-nob-stroke-width: 1px; + --cmpui-circle-nob-fill: var(--cmpui-primary-color); + --cmpui-circle-nob-stroke-color: var(--cmpui-border-color); + + background-color: var(--cmpui-bg-color); + + border-radius: 9999px; + position: relative; +} + +.cmpui_angle-input__nob { + fill: var(--cmpui-primary-color); + stroke: var(--cmpui-border-color); + + cursor: grab; +} diff --git a/src/components/AngleInput/index.stories.tsx b/src/components/AngleInput/index.stories.tsx new file mode 100644 index 0000000..e05e58e --- /dev/null +++ b/src/components/AngleInput/index.stories.tsx @@ -0,0 +1,39 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { AngleInput } from "."; + +const meta: Meta<typeof AngleInput> = { + title: "Components/Form/AngleInput", + component: AngleInput, +}; + +export default meta; +export type Story = StoryObj<typeof AngleInput>; + +export const Basic: Story = { + render: function Render() { + const [value, setValue] = useState(0); + return <AngleInput value={value} onChange={setValue} />; + }, +}; + +export const Step: Story = { + render: function Render() { + const [value, setValue] = useState(0); + return <AngleInput value={value} onChange={setValue} step={8} />; + }, +}; + +export const Size: Story = { + render: function Render() { + const [value, setValue] = useState(0); + return ( + <AngleInput + value={value} + onChange={setValue} + radius={64} + nobRadius={12} + /> + ); + }, +}; diff --git a/src/components/AngleInput/index.tsx b/src/components/AngleInput/index.tsx new file mode 100644 index 0000000..b93b10d --- /dev/null +++ b/src/components/AngleInput/index.tsx @@ -0,0 +1,156 @@ +import { useRef } from "react"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { Circle } from "../Circle"; +import { Line } from "../Line"; + +import "./index.css"; + +export type AngleInputProps = { + value: number; + nobRadius?: number; + onChange?: (value: number) => void; + radius?: number; + step?: number; +}; + +export function AngleInput({ + radius = 32, + step = 12, + nobRadius = 8, + ...props +}: AngleInputProps) { + const diameter = radius * 2; + const x = Math.cos(props.value) * (radius - 2); + const y = Math.sin(props.value) * (radius - 2); + const ref = useRef<HTMLDivElement>(null); + + const nobRef = useRef<HTMLDivElement>(null); + + const handlePointerDown = createDragHandler({ + onDown: (e) => { + const rect = ref.current?.getBoundingClientRect(); + if (!rect) return; + + if (!nobRef.current) return; + nobRef.current.style.cursor = "grabbing"; + + const nobRect = nobRef.current.getBoundingClientRect(); + const nobCenterX = nobRect.left + nobRect.width / 2; + const nobCenterY = nobRect.top + nobRect.height / 2; + + const centerX = rect.left + rect.width / 2; + const centerY = rect.top + rect.height / 2; + e.stopPropagation(); + return { + centerX, + centerY, + offsetX: nobCenterX - e.clientX, + offsetY: nobCenterY - e.clientY, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.centerX + ctx.offsetX; + const dy = e.clientY - ctx.centerY + ctx.offsetY; + + const angle = Math.atan2(dy, dx); + props.onChange?.(angle); + }, + onUp: () => { + if (!nobRef.current) return; + nobRef.current.style.cursor = "grab"; + }, + }); + + const handlePointerDownRoot = createDragHandler({ + onDown: (e) => { + const rect = ref.current?.getBoundingClientRect(); + if (!rect) return; + + const centerX = rect.left + rect.width / 2; + const centerY = rect.top + rect.height / 2; + + const angle = Math.atan2(e.clientY - centerY, e.clientX - centerX); + props.onChange?.(angle); + return { + centerX, + centerY, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.centerX; + const dy = e.clientY - ctx.centerY; + const angle = Math.atan2(dy, dx); + props.onChange?.(angle); + }, + }); + + return ( + <div + className="cmpui_angle-input__root" + onPointerDown={handlePointerDownRoot} + ref={ref} + style={{ + width: diameter, + height: diameter, + }} + > + <svg + width={diameter} + height={diameter} + viewBox={`0 0 ${diameter} ${diameter}`} + > + <circle + cx={radius} + cy={radius} + r={radius - 1} + stroke="var(--cmpui-border-color)" + fill="none" + strokeWidth={1} + /> + </svg> + {Array.from({ length: step }).map((_, i) => { + const angle = (i * Math.PI) / (step / 2); + const x = Math.cos(angle) * (radius - 4); + const y = Math.sin(angle) * (radius - 4); + const x1 = Math.cos(angle) * (radius - 8); + const y1 = Math.sin(angle) * (radius - 8); + return ( + <Line + key={i} + x1={x1 + radius} + y1={y1 + radius} + x2={x + radius} + y2={y + radius} + strokeWidth={1} + stroke="var(--cmpui-border-color)" + /> + ); + })} + <Line + x1={radius} + y1={radius} + x2={x + radius} + y2={y + radius} + strokeWidth={1} + stroke="var(--cmpui-primary-color)" + /> + <Circle + ref={nobRef} + x={x + radius} + y={y + radius} + onPointerDown={handlePointerDown} + radius={nobRadius} + className="cmpui_angle-input__nob" + /> + <Circle + x={radius} + y={radius} + radius={2} + strokeColor="transparent" + fill="var(--cmpui-primary-color)" + /> + </div> + ); +} diff --git a/src/components/Button/__snapshots__/index.stories.tsx.snap b/src/components/Button/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..d10f92e --- /dev/null +++ b/src/components/Button/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Actions/Button Basic smoke-test 1`] = ` +<button type="button" + class="cmpui_button" + data-variant="primary" + data-size="M" +> + Button +</button> +`; + +exports[`Components/Actions/Button Disabled smoke-test 1`] = ` +<button type="button" + class="cmpui_button" + disabled + data-variant="primary" + data-size="M" +> + Button +</button> +`; + +exports[`Components/Actions/Button Secondary smoke-test 1`] = ` +<button type="button" + class="cmpui_button" + data-variant="secondary" + data-size="M" +> + Button +</button> +`; + +exports[`Components/Actions/Button Small smoke-test 1`] = ` +<button type="button" + class="cmpui_button" + data-variant="primary" + data-size="S" +> + Button +</button> +`; diff --git a/src/components/Button/index.css b/src/components/Button/index.css new file mode 100644 index 0000000..63147ad --- /dev/null +++ b/src/components/Button/index.css @@ -0,0 +1,80 @@ +.cmpui_button { + background-color: var(--cmpui-primary-color); + + align-items: center; + border-radius: 9999px; + border: none; + box-sizing: border-box; + color: white; + cursor: pointer; + display: flex; + font-family: unset; + font-size: 16px; + height: 32px; + justify-content: center; + line-height: 16px; + outline: none; + padding: 0; + padding: 8px 16px; + text-align: center; + text-decoration: none; +} + +.cmpui_button:hover { + background-color: var(--cmpui-primary-hover-color); +} + +.cmpui_button:active { + background-color: var(--cmpui-primary-active-color); +} + +.cmpui_button:focus-visible { + outline: var(--cmpui-primary-color) solid 1px; + outline-offset: 1px; +} + +/* disabled */ + +.cmpui_button:disabled { + cursor: default; + opacity: 0.5; +} + +.cmpui_button:disabled:hover { + background-color: var(--cmpui-primary-color); +} + +.cmpui_button:disabled:active { + background-color: var(--cmpui-primary-color); +} + +/* Variant: secondary */ + +.cmpui_button[data-variant="secondary"] { + background-color: var(--cmpui-secondary-color); +} + +.cmpui_button[data-variant="secondary"]:hover { + background-color: var(--cmpui-secondary-hover-color); +} + +.cmpui_button[data-variant="secondary"]:active { + background-color: var(--cmpui-secondary-active-color); +} + +.cmpui_button[data-variant="secondary"]:disabled:hover { + background-color: var(--cmpui-secondary-color); +} + +.cmpui_button[data-variant="secondary"]:disabled:active { + background-color: var(--cmpui-secondary-color); +} + +/* Size: S */ + +.cmpui_button[data-size="S"] { + font-size: 12px; + height: 24px; + line-height: 12px; + padding: 4px 12px; +} diff --git a/src/components/Button/index.stories.tsx b/src/components/Button/index.stories.tsx new file mode 100644 index 0000000..3ca0668 --- /dev/null +++ b/src/components/Button/index.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Button } from "."; + +const meta: Meta<typeof Button> = { + title: "Components/Actions/Button", + component: Button, +}; + +export default meta; +type Story = StoryObj<typeof Button>; + +export const Basic: Story = { + render: () => { + return <Button>Button</Button>; + }, +}; + +export const Secondary: Story = { + render: () => { + return <Button variant="secondary">Button</Button>; + }, +}; + +export const Small: Story = { + render: () => { + return <Button size="S">Button</Button>; + }, +}; + +export const Disabled: Story = { + render: () => { + return <Button disabled>Button</Button>; + }, +}; diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx new file mode 100644 index 0000000..7b916ed --- /dev/null +++ b/src/components/Button/index.tsx @@ -0,0 +1,37 @@ +import { forwardRef } from "react"; +import { CustomJSXElement } from "../../types/CustomJSXElement"; +import { classNames } from "../../utils/classNames"; + +import "./index.css"; + +export type ButtonProps<T extends CustomJSXElement = "button"> = { + as?: T; + size?: "S" | "M"; + variant?: "primary" | "secondary"; +} & Omit<React.ComponentProps<T>, "as">; + +export const Button = forwardRef(function Button<T extends CustomJSXElement>( + { + variant = "primary", + size = "M", + children, + className, + as, + ...props + }: ButtonProps<T>, + ref: React.ForwardedRef<HTMLButtonElement>, +) { + const Component = as || "button"; + return ( + <Component + ref={ref} + type="button" + className={classNames("cmpui_button", className)} + {...props} + data-variant={variant} + data-size={size} + > + {children} + </Component> + ); +}) as <T extends CustomJSXElement = "button">(p: ButtonProps<T>) => JSX.Element; diff --git a/src/components/CanvasView/View.ts b/src/components/CanvasView/View.ts new file mode 100644 index 0000000..2a13217 --- /dev/null +++ b/src/components/CanvasView/View.ts @@ -0,0 +1,5 @@ +export type View = { + x: number; + y: number; + scale: number; +}; diff --git a/src/components/CanvasView/ViewMode.ts b/src/components/CanvasView/ViewMode.ts new file mode 100644 index 0000000..782e2d7 --- /dev/null +++ b/src/components/CanvasView/ViewMode.ts @@ -0,0 +1 @@ +export type ViewMode = "pan" | "zoom-in" | "zoom-out" | "default"; diff --git a/src/components/CanvasView/__snapshots__/index.stories.tsx.snap b/src/components/CanvasView/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..3918409 --- /dev/null +++ b/src/components/CanvasView/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/View/CanvasView Basic smoke-test 1`] = ` +<div style="width: 100vw; height: 512px;"> + <div class="cmpui_canvas-view__root" + tabindex="-1" + style="cursor: auto;" + > + <div style="position: absolute; pointer-events: none; transform-origin: 0px 0px; top: 100px; left: 200px; transform: scale(1);"> + <div style="width: 200px; height: 100px; background: white;"> + <div class="alpha-checker-board" + style="width: 200px; height: 100px;" + > + </div> + </div> + </div> + </div> +</div> +`; + +exports[`Components/View/CanvasView Grab smoke-test 1`] = ` +<div style="width: 100vw; height: 512px;"> + <div class="cmpui_canvas-view__root" + tabindex="-1" + style="cursor: grab;" + > + <div style="position: absolute; pointer-events: none; transform-origin: 0px 0px; top: 100px; left: 200px; transform: scale(1);"> + <div style="width: 200px; height: 100px; background: white;"> + <div class="alpha-checker-board" + style="width: 200px; height: 100px;" + > + </div> + </div> + </div> + </div> +</div> +`; + +exports[`Components/View/CanvasView Zoom smoke-test 1`] = ` +<div style="width: 100vw; height: 512px;"> + <div class="cmpui_canvas-view__root" + tabindex="-1" + style="cursor: zoom-in;" + > + <div style="position: absolute; pointer-events: none; transform-origin: 0px 0px; top: 100px; left: 200px; transform: scale(1);"> + <div style="width: 200px; height: 100px; background: white;"> + <div class="alpha-checker-board" + style="width: 200px; height: 100px;" + > + </div> + </div> + </div> + </div> +</div> +`; diff --git a/src/components/CanvasView/index.css b/src/components/CanvasView/index.css new file mode 100644 index 0000000..72bbf56 --- /dev/null +++ b/src/components/CanvasView/index.css @@ -0,0 +1,10 @@ +.cmpui_canvas-view__root { + display: flex; + height: 100%; + position: relative; + width: 100%; +} + +.cmpui_canvas-view__root:focus { + outline: none; +} diff --git a/src/components/CanvasView/index.stories.tsx b/src/components/CanvasView/index.stories.tsx new file mode 100644 index 0000000..79dacf5 --- /dev/null +++ b/src/components/CanvasView/index.stories.tsx @@ -0,0 +1,165 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { CanvasView, CanvasViewProps } from "."; +import { createKeyDownUpHandler } from "../../utils/interactions/createKeyDownUpHandler"; +import { View } from "./View"; +import { ViewMode } from "./ViewMode"; + +import "../../styles/alpha-checker-board.css"; + +function usePointerEnterFocus() { + return useCallback((e: React.PointerEvent<HTMLElement>) => { + e.currentTarget.focus({ + preventScroll: true, + }); + }, []); +} + +const meta: Meta<typeof CanvasView> = { + title: "Components/View/CanvasView", + component: CanvasView, + parameters: { + layout: "fullscreen", + }, +}; + +export default meta; +type Story = StoryObj<typeof CanvasView>; + +function BaseStory(props: CanvasViewProps) { + return ( + <div + style={{ + width: "100vw", + height: 512, + }} + > + <CanvasView + {...props} + maxScale={50} + minScale={0.2} + content={ + <> + <div style={{ width: 200, height: 100, background: "white" }}> + <div + className="alpha-checker-board" + style={{ + width: 200, + height: 100, + }} + /> + </div> + </> + } + /> + </div> + ); +} + +export const Basic: Story = { + render: () => { + const [view, setView] = useState<View>({ + x: 200, + y: 100, + scale: 1, + }); + + const [keyStack, setKeyStack] = useState<string[]>([]); + const handleKeyDowns = useMemo( + () => + [" ", "Alt", "Shift"].map((key) => + createKeyDownUpHandler(key, { + onDown: (e) => { + e.preventDefault(); + setKeyStack((keyStack) => { + if (keyStack.includes(key)) { + return keyStack; + } + return [...keyStack, key]; + }); + }, + onUp: () => { + setKeyStack((keyStack) => keyStack.filter((k) => k !== key)); + }, + }), + ), + [], + ); + + const handleKeyDown = (e: React.KeyboardEvent) => { + handleKeyDowns.map((handler) => handler(e)); + }; + + const mode = useMemo(() => { + if (keyStack.includes(" ")) { + return "pan"; + } + if (keyStack.includes("Alt") && keyStack.includes("Shift")) { + return "zoom-out"; + } + if (keyStack.includes("Alt")) { + return "zoom-in"; + } + return "default"; + }, [keyStack]); + + const handlePointerEnter = usePointerEnterFocus(); + + return ( + <BaseStory + onKeyDown={handleKeyDown} + onChangeView={setView} + view={view} + mode={mode} + onPointerEnter={handlePointerEnter} + /> + ); + }, +}; + +export const Grab: Story = { + render: () => { + const [view, setView] = useState<View>({ + x: 200, + y: 100, + scale: 1, + }); + + return <BaseStory onChangeView={setView} view={view} mode={"pan"} />; + }, +}; + +export const Zoom: Story = { + render: () => { + const [view, setView] = useState<View>({ + x: 200, + y: 100, + scale: 1, + }); + + const [mode, setMode] = useState<ViewMode>("zoom-in"); + + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === "Alt") { + setMode("zoom-out"); + window.addEventListener("keyup", handleKeyUp); + } + }; + const handleKeyUp = (e: KeyboardEvent) => { + if (e.key === "Alt") { + setMode("zoom-in"); + } + window.removeEventListener("keyup", handleKeyUp); + }; + + window.addEventListener("keydown", handleKeyDown); + + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, []); + + return <BaseStory onChangeView={setView} view={view} mode={mode} />; + }, +}; diff --git a/src/components/CanvasView/index.tsx b/src/components/CanvasView/index.tsx new file mode 100644 index 0000000..38b782f --- /dev/null +++ b/src/components/CanvasView/index.tsx @@ -0,0 +1,206 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { useAddEventListener } from "../../utils/interactions/useAddEventListener"; +import { View } from "./View"; +import { ViewMode } from "./ViewMode"; + +import "./index.css"; + +export * from "./View"; +export * from "./ViewMode"; + +export type CanvasViewProps = { + children?: React.ReactNode; + content?: React.ReactNode; + onChangeView: (view: View) => void; + view: View; + mode?: ViewMode; + minScale?: number; + maxScale?: number; + mouseZoomScale?: number; + trackPadZoomScale?: number; + trackPadMoveScaleX?: number; + trackPadMoveScaleY?: number; + pointerDownZoomScale?: number; +} & Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "content">; + +export function CanvasView({ + mouseZoomScale = 0.04, + trackPadZoomScale = -0.02, + trackPadMoveScaleX = 1, + trackPadMoveScaleY = 1, + pointerDownZoomScale = 100, + minScale, + maxScale, + children, + content, + view, + mode, + onChangeView, + style, + ...props +}: CanvasViewProps) { + const ref = useRef<HTMLDivElement>(null); + const [cursor, setCursor] = useState< + "auto" | "grab" | "grabbing" | "zoom-in" | "zoom-out" + >("auto"); + const modeRef = useRef(mode); + + const zoom = useCallback( + (clientX: number, clientY: number, delta: number) => { + if (!ref.current) return; + let rate = 1 + delta / 200; + + const rect = ref.current.getBoundingClientRect(); + const parentRect = ref.current.parentElement?.getBoundingClientRect(); + if (!parentRect) return; + const offsetX = clientX - rect.left; + const offsetY = clientY - rect.top; + + const NX = offsetX - view.x; + const NY = offsetY - view.y; + + if (maxScale !== undefined && view.scale * rate > maxScale) { + rate = maxScale / view.scale; + } else if (minScale !== undefined && view.scale * rate < minScale) { + rate = minScale / view.scale; + } + + onChangeView({ + x: view.x + NX - NX * rate, + y: view.y + NY - NY * rate, + scale: view.scale * rate, + }); + }, + [view, onChangeView, maxScale, minScale], + ); + + useAddEventListener( + ref, + "wheel", + useCallback( + (e) => { + const isTrackpad = Number.isInteger(e.deltaY); + const isZoom = e.ctrlKey || e.metaKey; + + if (isTrackpad && !isZoom) { + onChangeView({ + x: view.x - e.deltaX * trackPadMoveScaleX, + y: view.y - e.deltaY * trackPadMoveScaleY, + scale: view.scale, + }); + e.preventDefault(); + return; + } + + zoom(e.clientX, e.clientY, -e.deltaY); + e.preventDefault(); + }, + [view, onChangeView, zoom, trackPadMoveScaleY, trackPadMoveScaleX], + ), + useMemo(() => ({ passive: false }), []), + ); + + useEffect(() => { + if (mode === "pan") { + setCursor("grab"); + } else if (mode === "zoom-in") { + setCursor("zoom-in"); + } else if (mode === "zoom-out") { + setCursor("zoom-out"); + } else { + setCursor("auto"); + } + modeRef.current = mode; + }, [mode]); + + const handlePointerDownForPan = useMemo( + () => + createDragHandler< + | { + startX: number; + startY: number; + startOSX: number; + startOSY: number; + } + | undefined + >({ + onDown: (e: React.PointerEvent<HTMLElement | SVGElement>) => { + if (mode !== "pan") return false; + setCursor("grabbing"); + return { + startX: e.clientX, + startY: e.clientY, + startOSX: view.x, + startOSY: view.y, + }; + }, + onMove: (e, ctx) => { + if (ctx === undefined) return; + const deltaX = ctx.startX - e.clientX; + const deltaY = ctx.startY - e.clientY; + + onChangeView({ + x: ctx.startOSX - deltaX, + y: ctx.startOSY - deltaY, + scale: view.scale, + }); + }, + onUp: () => { + if (modeRef.current === "pan") { + setCursor("grab"); + } else { + setCursor("auto"); + } + }, + }), + [mode, view, onChangeView], + ); + + const handlePointerDown = useCallback( + (e: React.PointerEvent<HTMLElement>) => { + if (mode === "zoom-in") { + zoom(e.pageX, e.pageY, pointerDownZoomScale); + } else if (mode === "zoom-out") { + zoom(e.pageX, e.pageY, -pointerDownZoomScale); + } else { + handlePointerDownForPan(e); + } + }, + [mode, handlePointerDownForPan, pointerDownZoomScale, zoom], + ); + + const contentParentStyle = useMemo( + () => ({ + position: "absolute" as const, + pointerEvents: "none" as const, + transformOrigin: "0 0", + top: `${view.y}px`, + left: `${view.x}px`, + transform: `scale(${view.scale})`, + }), + [view.x, view.y, view.scale], + ); + + const rootStyle = useMemo( + () => ({ + cursor, + ...style, + }), + [cursor, style], + ); + + return ( + <div + className="cmpui_canvas-view__root" + tabIndex={-1} + ref={ref} + onPointerDown={handlePointerDown} + style={rootStyle} + {...props} + > + <div style={contentParentStyle}>{content}</div> + {children} + </div> + ); +} diff --git a/src/components/Checkbox/CheckSVG.tsx b/src/components/Checkbox/CheckSVG.tsx new file mode 100644 index 0000000..5222706 --- /dev/null +++ b/src/components/Checkbox/CheckSVG.tsx @@ -0,0 +1,13 @@ +export function CheckSVG() { + return ( + <svg + xmlns="http://www.w3.org/2000/svg" + height="16" + viewBox="0 -960 960 960" + width="16" + fill="currentColor" + > + <path d="M382-208 122-468l90-90 170 170 366-366 90 90-456 456Z" /> + </svg> + ); +} diff --git a/src/components/Checkbox/__snapshots__/index.stories.tsx.snap b/src/components/Checkbox/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..e08cefb --- /dev/null +++ b/src/components/Checkbox/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,129 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Form/Checkbox Basic smoke-test 1`] = ` +<div class="cmpui_checkbox__root"> + <div class="cmpui_checkbox__box"> + <input type="checkbox" + class="cmpui_checkbox__input" + id="checkbox-basic" + > + <div class="cmpui_checkbox__indicator" + data-checked="false" + > + <svg xmlns="http://www.w3.org/2000/svg" + height="16" + viewbox="0 -960 960 960" + width="16" + fill="currentColor" + > + <path d="M382-208 122-468l90-90 170 170 366-366 90 90-456 456Z"> + </path> + </svg> + </div> + </div> + <label class="cmpui_checkbox__label" + for="checkbox-basic" + > + Label + </label> +</div> +`; + +exports[`Components/Form/Checkbox Checked smoke-test 1`] = ` +<div class="cmpui_checkbox__root"> + <div class="cmpui_checkbox__box"> + <input type="checkbox" + class="cmpui_checkbox__input" + id="checkbox-checked" + checked + > + <div class="cmpui_checkbox__indicator" + data-checked="true" + > + <svg xmlns="http://www.w3.org/2000/svg" + height="16" + viewbox="0 -960 960 960" + width="16" + fill="currentColor" + > + <path d="M382-208 122-468l90-90 170 170 366-366 90 90-456 456Z"> + </path> + </svg> + </div> + </div> + <label class="cmpui_checkbox__label" + for="checkbox-checked" + > + Label + </label> +</div> +`; + +exports[`Components/Form/Checkbox Disabled smoke-test 1`] = ` +<div class="cmpui_checkbox__root" + aria-disabled="true" +> + <div class="cmpui_checkbox__box"> + <input type="checkbox" + class="cmpui_checkbox__input" + id="checkbox-disabled" + disabled + > + <div class="cmpui_checkbox__indicator"> + <svg xmlns="http://www.w3.org/2000/svg" + height="16" + viewbox="0 -960 960 960" + width="16" + fill="currentColor" + > + <path d="M382-208 122-468l90-90 170 170 366-366 90 90-456 456Z"> + </path> + </svg> + </div> + </div> + <label class="cmpui_checkbox__label" + for="checkbox-disabled" + > + Label + </label> +</div> +`; + +exports[`Components/Form/Checkbox Label smoke-test 1`] = ` +<div class="cmpui_checkbox__root"> + <div class="cmpui_checkbox__box"> + <input type="checkbox" + class="cmpui_checkbox__input" + id="checkbox-label" + checked + > + <div class="cmpui_checkbox__indicator" + data-checked="true" + > + <svg xmlns="http://www.w3.org/2000/svg" + height="16" + viewbox="0 -960 960 960" + width="16" + fill="currentColor" + > + <path d="M382-208 122-468l90-90 170 170 366-366 90 90-456 456Z"> + </path> + </svg> + </div> + </div> + <label class="cmpui_checkbox__label" + for="checkbox-label" + > + <div style="display: flex; align-items: center; gap: 4px;"> + <span class="material-symbols-outlined" + style="font-size: 16px;" + > + star + </span> + <div> + Custom Label + </div> + </div> + </label> +</div> +`; diff --git a/src/components/Checkbox/index.css b/src/components/Checkbox/index.css new file mode 100644 index 0000000..373152a --- /dev/null +++ b/src/components/Checkbox/index.css @@ -0,0 +1,71 @@ +.cmpui_checkbox__root { + align-items: center; + display: flex; + gap: 8px; +} + +.cmpui_checkbox__root[aria-disabled="true"] { + cursor: default; + opacity: 0.5; +} + +.cmpui_checkbox__box { + display: flex; + height: min-content; + position: relative; + width: min-content; +} + +.cmpui_checkbox__input { + background-color: var(--cmpui-bg-color); + border: 1px solid var(--cmpui-border-color); + + appearance: none; + border-radius: 4px; + box-sizing: border-box; + cursor: pointer; + height: 24px; + margin: 0; + padding: 0 2px; + position: relative; + transition: background-color 100ms; + width: 24px; + will-change: background-color; +} + +.cmpui_checkbox__input:focus-visible { + outline: var(--cmpui-primary-color) solid 1px; + + outline-offset: 1px; +} +.cmpui_checkbox__input:checked { + background-color: var(--cmpui-primary-color); +} + +.cmpui_checkbox__input:disabled { + cursor: default; + opacity: 0.5; +} + +.cmpui_checkbox__indicator { + align-items: center; + color: white; + display: flex; + display: none; + height: 100%; + justify-content: center; + pointer-events: none; + position: absolute; + top: 0; + width: 100%; +} + +.cmpui_checkbox__indicator[data-checked="true"] { + display: flex; +} + +.cmpui_checkbox__label { + color: var(--cmpui-text-color); + + font-size: 14px; +} diff --git a/src/components/Checkbox/index.stories.tsx b/src/components/Checkbox/index.stories.tsx new file mode 100644 index 0000000..2608efd --- /dev/null +++ b/src/components/Checkbox/index.stories.tsx @@ -0,0 +1,71 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { Checkbox } from "."; +import { Icon } from "../../__stories__/Icon"; + +const meta: Meta<typeof Checkbox> = { + title: "Components/Form/Checkbox", + component: Checkbox, +}; + +export default meta; + +type Story = StoryObj<typeof Checkbox>; + +export const Basic: Story = { + render: function Render() { + const [checked, setChecked] = useState(false); + return ( + <Checkbox + label="Label" + checked={checked} + id="checkbox-basic" + onChange={setChecked} + /> + ); + }, +}; + +export const Label: Story = { + render: function Render() { + const [checked, setChecked] = useState(true); + return ( + <Checkbox + checked={checked} + onChange={setChecked} + label={ + <div style={{ display: "flex", alignItems: "center", gap: 4 }}> + <Icon + style={{ + fontSize: 16, + }} + name="star" + /> + <div>Custom Label</div> + </div> + } + id="checkbox-label" + /> + ); + }, +}; + +export const Disabled: Story = { + render: () => { + return <Checkbox label="Label" id="checkbox-disabled" disabled />; + }, +}; + +export const Checked: Story = { + render: function Render() { + const [checked, setChecked] = useState(true); + return ( + <Checkbox + label="Label" + id="checkbox-checked" + checked={checked} + onChange={setChecked} + /> + ); + }, +}; diff --git a/src/components/Checkbox/index.tsx b/src/components/Checkbox/index.tsx new file mode 100644 index 0000000..7ec123f --- /dev/null +++ b/src/components/Checkbox/index.tsx @@ -0,0 +1,43 @@ +import { useCallback } from "react"; +import { CheckSVG } from "./CheckSVG"; + +import "./index.css"; + +export type CheckboxProps = { + label?: React.ReactNode; + checked?: boolean; + onChange?: (checked: boolean) => void; + disabled?: boolean; + id?: string; +}; + +export function Checkbox(props: CheckboxProps) { + const handleChange = useCallback( + (e: React.ChangeEvent<HTMLInputElement>) => { + props.onChange?.(e.target.checked); + }, + [props.onChange], + ); + return ( + <div className="cmpui_checkbox__root" aria-disabled={props.disabled}> + <div className="cmpui_checkbox__box"> + <input + type="checkbox" + className="cmpui_checkbox__input" + id={props.id} + disabled={props.disabled} + checked={props.checked} + onChange={handleChange} + /> + <div className="cmpui_checkbox__indicator" data-checked={props.checked}> + <CheckSVG /> + </div> + </div> + {props.label && ( + <label className="cmpui_checkbox__label" htmlFor={props.id}> + {props.label} + </label> + )} + </div> + ); +} diff --git a/src/components/Circle/index.css b/src/components/Circle/index.css new file mode 100644 index 0000000..43e06ef --- /dev/null +++ b/src/components/Circle/index.css @@ -0,0 +1,17 @@ +.cmpui_circle__root { + background-color: var(--cmpui-circle-nob-fill); + width: calc(var(--cmpui-circle-nob-radius) * 2); + max-width: calc(var(--cmpui-circle-nob-radius) * 2); + min-width: calc(var(--cmpui-circle-nob-radius) * 2); + height: calc(var(--cmpui-circle-nob-radius) * 2); + max-height: calc(var(--cmpui-circle-nob-radius) * 2); + min-height: calc(var(--cmpui-circle-nob-radius) * 2); + position: absolute; + border-radius: var(--cmpui-circle-nob-radius); + /* transform: translate( + calc(-1 * var(--cmpui-circle-nob-radius)), + calc(-1 * var(--cmpui-circle-nob-radius)) + ); */ + border: var(--cmpui-circle-nob-stroke-width) solid var(--cmpui-circle-nob-stroke-color); + box-sizing: border-box; +} diff --git a/src/components/Circle/index.tsx b/src/components/Circle/index.tsx new file mode 100644 index 0000000..89179ae --- /dev/null +++ b/src/components/Circle/index.tsx @@ -0,0 +1,40 @@ +import { forwardRef } from "react"; +import { classNames } from "../../utils/classNames"; +import { px } from "../../utils/px"; + +import "./index.css"; + +export type CircleProps = { + x: number; + y: number; + className?: string; + radius?: number; + strokeColor?: string; + strokeWidth?: string | number; + fill?: string; +} & Omit<React.ComponentPropsWithoutRef<"div">, "children">; + +export const Circle = forwardRef(function Nob( + { strokeColor, strokeWidth, fill, style, radius = 0, ...props }: CircleProps, + fRef: React.ForwardedRef<HTMLDivElement>, +) { + return ( + <div + ref={fRef} + {...props} + className={classNames("cmpui_circle__root", props.className)} + style={ + { + "--cmpui-circle-nob-fill": fill, + "--cmpui-circle-nob-radius": px(radius), + "--cmpui-circle-nob-stroke-color": strokeColor, + "--cmpui-circle-nob-stroke-width": `${strokeWidth ?? 0}px`, + border: `${strokeWidth ?? 0}px solid ${strokeColor}`, + left: props.x - radius, + top: props.y - radius, + ...style, + } as React.CSSProperties + } + /> + ); +}); diff --git a/src/components/ColorInput/__snapshots__/index.stories.tsx.snap b/src/components/ColorInput/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..c10b905 --- /dev/null +++ b/src/components/ColorInput/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Colors/ColorInput Primary smoke-test 1`] = ` +<div style="width: 192px;"> + <div class="cmpui_color-input__root"> + <div class="cmpui_text-input__root"> + <div class="alpha-checker-board" + style="--cmpui-block-size: 4px;" + > + <div tabindex="0" + class="cmpui_color-input__color" + style="background-color: rgb(198, 73, 186); mask-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 50%, black 50%);" + > + </div> + </div> + <label class="cmpui_text-input__label"> + ColorInput + </label> + <input type="text" + class="cmpui_text-input__input" + placeholder + value="#c649ba" + > + </div> + <div class="cmpui_text-input__root cmpui_slider-number-input__root"> + <label class="cmpui_text-input__label cmpui_slider-number-input__label"> + % + </label> + <input type="text" + class="cmpui_text-input__input" + placeholder + value="50" + > + </div> + </div> +</div> +`; diff --git a/src/components/ColorInput/index.css b/src/components/ColorInput/index.css new file mode 100644 index 0000000..1eacd94 --- /dev/null +++ b/src/components/ColorInput/index.css @@ -0,0 +1,45 @@ +.cmpui_color-input__root { + display: flex; + gap: 2px; + width: 100%; +} + +.cmpui_color-input__root > .cmpui_text-input__root:nth-child(1) { + width: 100%; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.cmpui_color-input__root > .cmpui_text-input__root:nth-child(2) { + width: 64px; + min-width: 64px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.cmpui_color-input__input { + visibility: hidden; + appearance: none; + position: absolute; + width: 32px; + height: 32px; + max-width: 32px; + max-height: 32px; + min-width: 32px; + min-height: 32px; + inline-size: 32px; + block-size: 32px; + margin: 0; + padding: 0; + transform: translate(-4px, 0px); +} + +.cmpui_color-input__color { + display: flex; + align-items: center; + justify-content: center; + width: 20px; + height: 12px; + cursor: pointer; + mask-image: linear-gradient(to right, transparent 50%, black 50%); +} diff --git a/src/components/ColorInput/index.stories.tsx b/src/components/ColorInput/index.stories.tsx new file mode 100644 index 0000000..748b124 --- /dev/null +++ b/src/components/ColorInput/index.stories.tsx @@ -0,0 +1,32 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { ColorInput } from "."; +import { hexToHsv } from "../../utils/colors/hexToHsv"; + +const meta: Meta<typeof ColorInput> = { + title: "Components/Colors/ColorInput", + component: ColorInput, +}; + +export default meta; +type Story = StoryObj<typeof ColorInput>; + +export const Primary: Story = { + render: function RenderBasic() { + const [color, setColor] = useState({ ...hexToHsv("#c649ba"), a: 0.5 }); + + return ( + <div + style={{ + width: 192, + }} + > + <ColorInput + label="ColorInput" + value={color} + onChange={(value) => setColor(value)} + /> + </div> + ); + }, +}; diff --git a/src/components/ColorInput/index.tsx b/src/components/ColorInput/index.tsx new file mode 100644 index 0000000..821caa8 --- /dev/null +++ b/src/components/ColorInput/index.tsx @@ -0,0 +1,164 @@ +import { ForwardedRef, forwardRef, useCallback, useState } from "react"; +import { hsvaToRgba } from "../../utils/colors"; +import { hexToHsv } from "../../utils/colors/hexToHsv"; +import { hsvToHex } from "../../utils/colors/hsvToHex"; +import { isValidHex6 } from "../../utils/colors/isValidHex6"; +import { rgbToCss } from "../../utils/colors/rgbToCss"; +import { HSVA } from "../../utils/colors/types/HSVA"; +import { clamp } from "../../utils/math/clamp"; +import { ColorPickerCircle } from "../ColorPickerCircle"; +import { Popover } from "../Popover"; +import { SliderNumberField } from "../SliderNumberField"; +import { TextInput } from "../TextInput"; + +import "../../styles/alpha-checker-board.css"; +import "./index.css"; + +export type ColorInputProps = { + value: HSVA; + label?: string; + onChange?: (value: HSVA) => void; + onStart?: () => void; + onEnd?: () => void; +}; + +const ColorView = forwardRef(function ColorView( + props: { + onClick?: () => void; + value: HSVA; + }, + ref: ForwardedRef<HTMLDivElement>, +) { + const rgba = hsvaToRgba(props.value); + const handleKeyDown = useCallback( + (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + props.onClick?.(); + } + }, + [props.onClick], + ); + return ( + <div + ref={ref} + className="alpha-checker-board" + style={ + { + "--cmpui-block-size": "4px", + } as React.CSSProperties + } + > + <div + onClick={props.onClick} + onKeyDown={handleKeyDown} + tabIndex={0} + className="cmpui_color-input__color" + style={{ + backgroundColor: rgbToCss(rgba), + maskImage: `linear-gradient(to right, rgba(0,0,0,${props.value.a}) 50%, black 50%)`, + }} + /> + </div> + ); +}); + +export function ColorInput(props: ColorInputProps) { + const [prevValue, setPrevValue] = useState<string>(hsvToHex(props.value)); + const [isFocused, setIsFocused] = useState<HSVA | null>(null); + + const [open, setOpen] = useState(false); + + const handleChangeHsva = useCallback( + (hsva: HSVA) => { + const _a = hsva.a === undefined ? props.value.a : hsva.a; + props.onChange?.({ + ...hsva, + a: _a, + }); + setPrevValue( + hsvToHex({ + ...hsva, + a: _a, + }), + ); + }, + [props.onChange, props.value.a], + ); + + const handleChangeAlpha = useCallback( + (a: number[]) => { + props.onChange?.({ ...props.value, a: a[0] / 100 }); + }, + [props.onChange, props.value], + ); + + const handleChangeInput = useCallback( + (e: React.ChangeEvent<HTMLInputElement>) => { + const value = e.target.value; + if (value.length > 7) return; + if (isValidHex6(value)) { + props.onChange?.(hexToHsv(value)); + } + setPrevValue(value); + }, + [props.onChange], + ); + + const handleBlur = useCallback( + (e: React.FocusEvent<HTMLInputElement>) => { + if (!isValidHex6(e.target.value)) { + props.onChange?.(isFocused || props.value); + setPrevValue(hsvToHex(isFocused || props.value)); + } else { + props.onChange?.({ ...hexToHsv(e.target.value), a: props.value.a }); + setPrevValue(e.target.value); + } + setIsFocused(null); + }, + [isFocused, props.onChange, props.value.a, props.value], + ); + + return ( + <div className="cmpui_color-input__root"> + <TextInput + label={props.label} + prefix={ + <Popover + isOpen={open} + onOpenChange={() => setOpen(false)} + content={ + <div> + <ColorPickerCircle + onChange={handleChangeHsva} + alpha={props.value.a} + hue={props.value.h} + saturation={props.value.s} + value={props.value.v} + onStart={props.onStart} + onEnd={props.onEnd} + /> + </div> + } + > + <ColorView + onClick={() => setOpen((prev) => !prev)} + value={props.value} + /> + </Popover> + } + onFocus={() => setIsFocused(props.value)} + value={isFocused ? prevValue : hsvToHex(props.value)} + onChange={handleChangeInput} + onBlur={handleBlur} + /> + <SliderNumberField + label="%" + value={[props.value.a * 100]} + onChangeValue={handleChangeAlpha} + numToString={(value) => `${clamp(value, 0, 100).toFixed(0)}`} + onStart={props.onStart} + onEnd={props.onEnd} + /> + </div> + ); +} diff --git a/src/components/ColorLoupe/__snapshots__/index.stories.tsx.snap b/src/components/ColorLoupe/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..f630a13 --- /dev/null +++ b/src/components/ColorLoupe/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Colors/ColorLoupe Default smoke-test 1`] = ` +<div style="position: relative; width: 100px; height: 100px;"> + <svg width="1" + height="25" + viewbox="0 0 1 25" + style="position: absolute; overflow: visible; pointer-events: none; left: 49.5px; top: 17.5px;" + > + <line stroke="var(--cmpui-border-color)" + stroke-width="1" + x1="0.5" + x2="0.5" + y1="24.5" + y2="0.5" + > + </line> + </svg> + <div x="50" + y="18" + class="cmpui_circle__root alpha-checker-board" + style="--cmpui-circle-nob-fill: white; --cmpui-circle-nob-radius: 16px; --cmpui-circle-nob-stroke-color: var(--cmpui-border-color); --cmpui-circle-nob-stroke-width: 1px; border: 1px solid var(--cmpui-border-color); left: 34px; top: 2px; z-index: 1; --block-size: 4px;" + > + </div> + <div x="50" + y="18" + class="cmpui_circle__root" + style="--cmpui-circle-nob-fill: #c649ba; --cmpui-circle-nob-radius: 16px; --cmpui-circle-nob-stroke-color: var(--cmpui-border-color); --cmpui-circle-nob-stroke-width: 1px; border: 1px solid var(--cmpui-border-color); left: 34px; top: 2px; z-index: 1;" + > + </div> +</div> +`; diff --git a/src/components/ColorLoupe/index.stories.tsx b/src/components/ColorLoupe/index.stories.tsx new file mode 100644 index 0000000..0d9dc6c --- /dev/null +++ b/src/components/ColorLoupe/index.stories.tsx @@ -0,0 +1,26 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { ColorLoupe } from "."; + +const meta: Meta<typeof ColorLoupe> = { + title: "Components/Colors/ColorLoupe", + component: ColorLoupe, +}; + +export default meta; +type Story = StoryObj<typeof ColorLoupe>; + +export const Default: Story = { + render: function Render() { + return ( + <div + style={{ + position: "relative", + width: "100px", + height: "100px", + }} + > + <ColorLoupe color="#c649ba" x={50} y={50} /> + </div> + ); + }, +}; diff --git a/src/components/ColorLoupe/index.tsx b/src/components/ColorLoupe/index.tsx new file mode 100644 index 0000000..1e15417 --- /dev/null +++ b/src/components/ColorLoupe/index.tsx @@ -0,0 +1,49 @@ +import { memo } from "react"; +import { Circle } from "../Circle"; +import { Line } from "../Line"; + +export type ColorLoupeProps = { + color: string; + nobRadius?: number; + x: number; + y: number; +}; + +export const ColorLoupe = memo(function ColorLoupe({ + color, + nobRadius = 8, + x, + y, +}: ColorLoupeProps) { + return ( + <> + <Line + stroke="var(--cmpui-border-color)" + strokeWidth={1} + x1={x} + x2={x} + y1={y - nobRadius} + y2={y - nobRadius * 4} + /> + <Circle + fill={"white"} + radius={nobRadius * 2} + strokeColor="var(--cmpui-border-color)" + strokeWidth={1} + style={{ zIndex: 1, "--block-size": "4px" } as React.CSSProperties} + x={x} + y={y - nobRadius * 4} + className="alpha-checker-board" + /> + <Circle + fill={color} + radius={nobRadius * 2} + strokeColor="var(--cmpui-border-color)" + strokeWidth={1} + style={{ zIndex: 1 }} + x={x} + y={y - nobRadius * 4} + /> + </> + ); +}); diff --git a/src/components/ColorPickerCircle/__snapshots__/index.stories.tsx.snap b/src/components/ColorPickerCircle/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..db812c1 --- /dev/null +++ b/src/components/ColorPickerCircle/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,66 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Colors/ColorPickerCircle Default smoke-test 1`] = ` +<div class="cmpui_color-picker-circle__root"> + <div> + <div class="cmpui_hue-circle__root" + tabindex="0" + style="--cmpui-width: 24px; --cmpui-size: 192px;" + > + <div class="cmpui_hue-circle__hue" + style="width: 192px; height: 192px;" + > + </div> + <div x="27.8363521006857" + y="46.911130537989536" + class="cmpui_circle__root cmpui_hue-circle__nob" + style="--cmpui-circle-nob-fill: rgb(255,0,231); --cmpui-circle-nob-radius: 8px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: 19.8364px; top: 38.9111px;" + > + </div> + <div class="cmpui_hue-circle__inner"> + </div> + </div> + <div class="cmpui_color-picker-circle__sv-picker-parent"> + <div class="cmpui_sv-picker__root" + tabindex="0" + > + <canvas width="93.33809511662427" + height="93.33809511662427" + style="width: 93.3381px; height: 93.3381px;" + > + </canvas> + <div class="cmpui_circle__root cmpui_sv-picker__nob" + x="58.92556509887897" + y="20.86380949665719" + style="--cmpui-circle-nob-fill: rgb(198,73,186); --cmpui-circle-nob-radius: 8px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 50.9256px; top: 12.8638px;" + > + </div> + </div> + </div> + </div> + <div class="cmpui_color-slider__root" + tabindex="0" + > + <div style="position: relative; overflow: hidden; cursor: pointer; width: 192px; height: 20px;"> + <div class="alpha-checker-board" + style="width: 192px; height: 20px;" + > + <div style="width: 100%; height: 100%; background: rgb(198, 73, 186); mask-image: linear-gradient(to right, transparent 0%, black 100%);"> + </div> + </div> + <div x="192" + y="10" + class="cmpui_circle__root alpha-checker-board" + style="--cmpui-circle-nob-fill: white; --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: 185.333px; top: 3.33333px; --cmpui-block-size: 4px; pointer-events: none;" + > + </div> + <div x="192" + y="10" + class="cmpui_circle__root cmpui_color-slider__nob" + style="--cmpui-circle-nob-fill: rgba(198,73,186,1); --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: 185.333px; top: 3.33333px;" + > + </div> + </div> + </div> +</div> +`; diff --git a/src/components/ColorPickerCircle/index.css b/src/components/ColorPickerCircle/index.css new file mode 100644 index 0000000..1b7e1d7 --- /dev/null +++ b/src/components/ColorPickerCircle/index.css @@ -0,0 +1,18 @@ +.cmpui_color-picker-circle__root { + display: flex; + flex-direction: column; + gap: 8px; + padding: 8px; + position: relative; +} + +.cmpui_color-picker-circle__root > div { + position: relative; +} + +.cmpui_color-picker-circle__sv-picker-parent { + left: 50%; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); +} diff --git a/src/components/ColorPickerCircle/index.stories.tsx b/src/components/ColorPickerCircle/index.stories.tsx new file mode 100644 index 0000000..0876b3d --- /dev/null +++ b/src/components/ColorPickerCircle/index.stories.tsx @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useCallback, useState } from "react"; +import { ColorPickerCircle } from "."; +import { HSVA } from "../.."; +import { hexToHsv } from "../../utils/colors/hexToHsv"; + +const meta: Meta<typeof ColorPickerCircle> = { + title: "Components/Colors/ColorPickerCircle", + component: ColorPickerCircle, +}; + +export default meta; +type Story = StoryObj<typeof ColorPickerCircle>; + +export const Default: Story = { + render: function Render() { + const hsv = hexToHsv("#c649ba"); + const [saturation, setSaturation] = useState(hsv.s); + const [value, setValue] = useState(hsv.v); + const [hue, setHue] = useState(hsv.h); + const [alpha, setAlpha] = useState(hsv.a); + + const handleChange = useCallback((hsva: HSVA) => { + setHue(hsva.h); + setSaturation(hsva.s); + setValue(hsva.v); + setAlpha(hsva.a); + }, []); + + return ( + <ColorPickerCircle + hue={hue} + onChange={handleChange} + alpha={alpha} + saturation={saturation} + value={value} + /> + ); + }, +}; diff --git a/src/components/ColorPickerCircle/index.tsx b/src/components/ColorPickerCircle/index.tsx new file mode 100644 index 0000000..705ec06 --- /dev/null +++ b/src/components/ColorPickerCircle/index.tsx @@ -0,0 +1,127 @@ +import { useCallback, useMemo } from "react"; +import { hsvaToRgba } from "../../utils/colors"; +import { hsvToRgb } from "../../utils/colors/hsvToRgb"; +import { rgbToCss } from "../../utils/colors/rgbToCss"; +import { ColorPickerRectProps } from "../ColorPickerRect"; +import { ColorSlider } from "../ColorSlider"; +import { HueCircle } from "../HueCircle"; +import { SVPicker } from "../SVPicker"; + +import "./index.css"; + +export type ColorPickerCircleProps = ColorPickerRectProps & { + circleStrokeWidth?: number; +}; + +export function ColorPickerCircle({ + hue, + saturation, + value, + alpha, + onChange, + size = 192, + circleStrokeWidth = 24, + onStart, + onEnd, +}: ColorPickerCircleProps) { + const rectSize = size - circleStrokeWidth * 2 - 12; + + const handleChangeSV = useCallback( + (s: number, v: number) => { + onChange({ + h: hue, + s, + v, + a: alpha ?? 1, + }); + }, + [hue, alpha, onChange], + ); + + const hsva = useMemo( + () => ({ h: hue, s: saturation, v: value, a: alpha ?? 1 }), + [hue, saturation, value, alpha], + ); + + const rgba = useMemo(() => hsvaToRgba(hsva), [hsva]); + + const background = useMemo(() => rgbToCss(hsvToRgb(hsva)), [hsva]); + + const bgStyle = useMemo( + () => ({ + width: "100%", + height: "100%", + background: background, + maskImage: "linear-gradient(to right, transparent 0%, black 100%)", + }), + [background], + ); + + const handleAlphaChange = useCallback( + (a: number) => { + onChange({ + h: hue, + s: saturation, + v: value, + a, + }); + }, + [hue, saturation, value, onChange], + ); + + const handleHueChange = useCallback( + (h: number) => { + onChange({ + h, + s: saturation, + v: value, + a: alpha ?? 1, + }); + }, + [saturation, value, alpha, onChange], + ); + + const svPickerSize = useMemo( + () => Math.cos(Math.PI / 4) * rectSize, + [rectSize], + ); + + return ( + <> + <div className="cmpui_color-picker-circle__root"> + <div> + <HueCircle + strokeWidth={circleStrokeWidth} + hue={hue} + size={size} + onHueChange={handleHueChange} + onStart={onStart} + onEnd={onEnd} + /> + <div className="cmpui_color-picker-circle__sv-picker-parent"> + <SVPicker + width={svPickerSize} + height={svPickerSize} + hue={hue} + onChange={handleChangeSV} + saturation={saturation} + value={value} + onStart={onStart} + onEnd={onEnd} + /> + </div> + </div> + {alpha !== undefined && ( + <ColorSlider + color={rgba} + value={alpha} + onChange={handleAlphaChange} + bg={<div style={bgStyle} />} + onStart={onStart} + onEnd={onEnd} + /> + )} + </div> + </> + ); +} diff --git a/src/components/ColorPickerRect/__snapshots__/index.stories.tsx.snap b/src/components/ColorPickerRect/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..17c4777 --- /dev/null +++ b/src/components/ColorPickerRect/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,69 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Colors/ColorPickerRect Default smoke-test 1`] = ` +<div class="cmpui_color-picker-rect__root"> + <div class="cmpui_sv-picker__root" + tabindex="0" + > + <canvas width="192" + height="192" + style="width: 192px; height: 192px;" + > + </canvas> + <div class="cmpui_circle__root cmpui_sv-picker__nob" + x="96" + y="96" + style="--cmpui-circle-nob-fill: rgb(128,64,64); --cmpui-circle-nob-radius: 8px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 88px; top: 88px;" + > + </div> + </div> + <div class="cmpui_color-slider__root" + tabindex="0" + > + <div style="position: relative; overflow: hidden; cursor: pointer; width: 192px; height: 20px;"> + <div class="alpha-checker-board" + style="width: 192px; height: 20px;" + > + <div style="width: 100%; height: 100%; background-image: linear-gradient(to right, rgb(255, 0, 0) 0%, rgb(255, 255, 0) 17%, rgb(0, 255, 0) 33%, rgb(0, 255, 255) 50%, rgb(0, 0, 255) 67%, rgb(255, 0, 255) 83%, rgb(255, 0, 0) 100%);"> + </div> + </div> + <div x="0" + y="10" + class="cmpui_circle__root alpha-checker-board" + style="--cmpui-circle-nob-fill: white; --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: -6.66667px; top: 3.33333px; --cmpui-block-size: 4px; pointer-events: none;" + > + </div> + <div x="0" + y="10" + class="cmpui_circle__root cmpui_color-slider__nob" + style="--cmpui-circle-nob-fill: rgba(255,0,0,1); --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: -6.66667px; top: 3.33333px;" + > + </div> + </div> + </div> + <div class="cmpui_color-slider__root" + tabindex="0" + > + <div style="position: relative; overflow: hidden; cursor: pointer; width: 192px; height: 20px;"> + <div class="alpha-checker-board" + style="width: 192px; height: 20px;" + > + <div style="width: 100%; height: 100%; background: rgb(128, 64, 64); mask-image: linear-gradient(to right, transparent 0%, black 100%);"> + </div> + </div> + <div x="192" + y="10" + class="cmpui_circle__root alpha-checker-board" + style="--cmpui-circle-nob-fill: white; --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 185.333px; top: 3.33333px; --cmpui-block-size: 4px; pointer-events: none;" + > + </div> + <div x="192" + y="10" + class="cmpui_circle__root cmpui_color-slider__nob" + style="--cmpui-circle-nob-fill: rgba(128,64,64,1); --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 185.333px; top: 3.33333px;" + > + </div> + </div> + </div> +</div> +`; diff --git a/src/components/ColorPickerRect/index.css b/src/components/ColorPickerRect/index.css new file mode 100644 index 0000000..59565e5 --- /dev/null +++ b/src/components/ColorPickerRect/index.css @@ -0,0 +1,8 @@ +.cmpui_color-picker-rect__root { + display: flex; + flex-direction: column; + gap: 8px; + height: fit-content; + position: relative; + width: fit-content; +} diff --git a/src/components/ColorPickerRect/index.stories.tsx b/src/components/ColorPickerRect/index.stories.tsx new file mode 100644 index 0000000..77f3b7b --- /dev/null +++ b/src/components/ColorPickerRect/index.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { ColorPickerRect } from "."; + +const meta: Meta<typeof ColorPickerRect> = { + title: "Components/Colors/ColorPickerRect", + component: ColorPickerRect, +}; + +export default meta; +type Story = StoryObj<typeof ColorPickerRect>; + +export const Default: Story = { + render: function Render() { + const [saturation, setSaturation] = useState(0.5); + const [value, setValue] = useState(0.5); + const [hue, setHue] = useState(0); + const [alpha, setAlpha] = useState(1); + + return ( + <ColorPickerRect + hue={hue} + onChange={(hsva) => { + setHue(hsva.h); + setSaturation(hsva.s); + setValue(hsva.v); + setAlpha(hsva.a); + }} + alpha={alpha} + saturation={saturation} + value={value} + /> + ); + }, +}; diff --git a/src/components/ColorPickerRect/index.tsx b/src/components/ColorPickerRect/index.tsx new file mode 100644 index 0000000..26dced9 --- /dev/null +++ b/src/components/ColorPickerRect/index.tsx @@ -0,0 +1,117 @@ +import { useMemo } from "react"; +import { HSVA, hsvaToRgba } from "../../utils/colors"; +import { hsvToRgb } from "../../utils/colors/hsvToRgb"; +import { rgbToCss } from "../../utils/colors/rgbToCss"; +import { ColorSlider } from "../ColorSlider"; +import { SVPicker } from "../SVPicker"; + +import "./index.css"; + +export type ColorPickerRectProps = { + alpha?: number; + hue: number; + saturation: number; + size?: number; + value: number; + onChange: (hsva: HSVA) => void; + onStart?: () => void; + onEnd?: () => void; +}; + +export function ColorPickerRect({ + alpha, + hue, + onChange, + saturation, + size, + value, +}: ColorPickerRectProps) { + const hsv = useMemo( + () => ({ h: hue, s: saturation, v: value }), + [hue, saturation, value], + ); + + const hueColor = useMemo( + () => ({ + ...hsvToRgb({ + h: hue, + s: 1, + v: 1, + }), + a: 1, + }), + [hue], + ); + + const hsva = useMemo(() => ({ ...hsv, a: alpha ?? 1 }), [hsv, alpha]); + const rgba = useMemo(() => hsvaToRgba(hsva), [hsva]); + + return ( + <div className="cmpui_color-picker-rect__root"> + <SVPicker + hue={hue} + onChange={(h, v) => + onChange({ + h, + s: saturation, + v, + a: alpha ?? 1, + }) + } + saturation={saturation} + value={value} + width={size} + height={size} + /> + <ColorSlider + color={hueColor} + value={hue / 360} + onChange={(v) => { + onChange({ + h: v * 360, + s: saturation, + v: value, + a: alpha ?? 1, + }); + }} + bg={ + <div + style={{ + width: "100%", + height: "100%", + backgroundImage: + "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)", + }} + /> + } + /> + {alpha !== undefined && ( + <ColorSlider + color={rgba} + value={alpha} + onChange={(a) => { + onChange({ + h: hue, + s: saturation, + v: value, + a, + }); + }} + bg={ + <> + <div + style={{ + width: "100%", + height: "100%", + background: rgbToCss(hsvToRgb(hsv)), + maskImage: + "linear-gradient(to right, transparent 0%, black 100%)", + }} + /> + </> + } + /> + )} + </div> + ); +} diff --git a/src/components/ColorSlider/__snapshots__/index.stories.tsx.snap b/src/components/ColorSlider/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..8e0bc36 --- /dev/null +++ b/src/components/ColorSlider/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,82 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Colors/ColorSlider Default smoke-test 1`] = ` +<div class="cmpui_color-slider__root" + tabindex="0" +> + <div style="position: relative; overflow: hidden; cursor: pointer; width: 192px; height: 20px;"> + <div class="alpha-checker-board" + style="width: 192px; height: 20px;" + > + <div style="width: 100%; height: 100%; background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgb(0, 0, 0));"> + </div> + </div> + <div x="96" + y="10" + class="cmpui_circle__root alpha-checker-board" + style="--cmpui-circle-nob-fill: white; --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: 89.3333px; top: 3.33333px; --cmpui-block-size: 4px; pointer-events: none;" + > + </div> + <div x="96" + y="10" + class="cmpui_circle__root cmpui_color-slider__nob" + style="--cmpui-circle-nob-fill: rgba(127.5,127.5,127.5,0.5); --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: 89.3333px; top: 3.33333px;" + > + </div> + </div> +</div> +`; + +exports[`Components/Colors/ColorSlider HeightAndNobSize smoke-test 1`] = ` +<div class="cmpui_color-slider__root" + tabindex="0" +> + <div style="position: relative; overflow: hidden; cursor: pointer; width: 192px; height: 32px;"> + <div class="alpha-checker-board" + style="width: 192px; height: 32px;" + > + <div style="width: 100%; height: 100%; background-image: linear-gradient(to right, black, red);"> + </div> + </div> + <div x="96" + y="16" + class="cmpui_circle__root alpha-checker-board" + style="--cmpui-circle-nob-fill: white; --cmpui-circle-nob-radius: 10.666666666666666px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 85.3333px; top: 5.33333px; --cmpui-block-size: 4px; pointer-events: none;" + > + </div> + <div x="96" + y="16" + class="cmpui_circle__root cmpui_color-slider__nob" + style="--cmpui-circle-nob-fill: rgba(127.5,0,0,1); --cmpui-circle-nob-radius: 10.666666666666666px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 85.3333px; top: 5.33333px;" + > + </div> + </div> +</div> +`; + +exports[`Components/Colors/ColorSlider Hue smoke-test 1`] = ` +<div class="cmpui_color-slider__root" + tabindex="0" +> + <div style="position: relative; overflow: hidden; cursor: pointer; width: 192px; height: 20px;"> + <div class="alpha-checker-board" + style="width: 192px; height: 20px;" + > + <div style="width: 100%; height: 100%; background-image: linear-gradient(to right, rgb(255, 0, 0) 0%, rgb(255, 255, 0) 17%, rgb(0, 255, 0) 33%, rgb(0, 255, 255) 50%, rgb(0, 0, 255) 67%, rgb(255, 0, 255) 83%, rgb(255, 0, 0) 100%);"> + </div> + </div> + <div x="96" + y="10" + class="cmpui_circle__root alpha-checker-board" + style="--cmpui-circle-nob-fill: white; --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: 89.3333px; top: 3.33333px; --cmpui-block-size: 4px; pointer-events: none;" + > + </div> + <div x="96" + y="10" + class="cmpui_circle__root cmpui_color-slider__nob" + style="--cmpui-circle-nob-fill: rgba(0,255,255,1); --cmpui-circle-nob-radius: 6.666666666666667px; --cmpui-circle-nob-stroke-color: rgb(0,0,0); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(0, 0, 0); left: 89.3333px; top: 3.33333px;" + > + </div> + </div> +</div> +`; diff --git a/src/components/ColorSlider/index.css b/src/components/ColorSlider/index.css new file mode 100644 index 0000000..97b0153 --- /dev/null +++ b/src/components/ColorSlider/index.css @@ -0,0 +1,25 @@ +.cmpui_color-slider__root { + background-color: white; + position: relative; + border: 1px solid var(--cmpui-border-color); + box-sizing: border-box; +} + +.cmpui_color-slider__root:focus-visible { + outline: 1px solid var(--cmpui-primary-color); + outline-offset: 1px; +} + +.cmpui_color-slider__nob { + position: absolute; + cursor: grab; + border-radius: 9999px; +} + +.cmpui_color-slider__nob:active { + cursor: grabbing; +} + +.cmpui_color-slider__nob:focus { + outline: none; +} diff --git a/src/components/ColorSlider/index.stories.tsx b/src/components/ColorSlider/index.stories.tsx new file mode 100644 index 0000000..6cd815c --- /dev/null +++ b/src/components/ColorSlider/index.stories.tsx @@ -0,0 +1,99 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useMemo, useState } from "react"; +import { ColorSlider } from "."; +import { hsvToRgb } from "../../utils/colors/hsvToRgb"; + +const meta: Meta<typeof ColorSlider> = { + title: "Components/Colors/ColorSlider", + component: ColorSlider, +}; + +export default meta; +type Story = StoryObj<typeof ColorSlider>; + +export const Default: Story = { + render: function Render() { + const [value, setValue] = useState(0.5); + + return ( + <ColorSlider + color={{ + r: (1 - value) * 255, + g: (1 - value) * 255, + b: (1 - value) * 255, + a: value, + }} + value={value} + onChange={setValue} + bg={ + <div + style={{ + width: "100%", + height: "100%", + backgroundImage: + "linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 1))", + }} + /> + } + /> + ); + }, +}; + +export const Hue: Story = { + render: function Render() { + const [value, setValue] = useState(0.5); + + const color = useMemo(() => { + const { r, g, b } = hsvToRgb({ h: value * 360, s: 1, v: 1 }); + return { r, g, b, a: 1 }; + }, [value]); + + return ( + <ColorSlider + color={color} + value={value} + onChange={setValue} + bg={ + <div + style={{ + width: "100%", + height: "100%", + backgroundImage: + "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)", + }} + /> + } + /> + ); + }, +}; + +export const HeightAndNobSize: Story = { + render: function Render() { + const [value, setValue] = useState(0.5); + + return ( + <ColorSlider + color={{ + r: value * 255, + g: 0, + b: 0, + a: 1, + }} + height={32} + value={value} + onChange={setValue} + bg={ + <div + style={{ + width: "100%", + height: "100%", + backgroundImage: "linear-gradient(to right, black, red)", + }} + /> + } + /> + ); + }, +}; diff --git a/src/components/ColorSlider/index.tsx b/src/components/ColorSlider/index.tsx new file mode 100644 index 0000000..61c7955 --- /dev/null +++ b/src/components/ColorSlider/index.tsx @@ -0,0 +1,202 @@ +import { useCallback, useMemo, useState } from "react"; +import { useTouchStartPrevent } from "../.."; +import "../../styles/alpha-checker-board.css"; +import { classNames } from "../../utils/classNames"; +import { blendColors } from "../../utils/colors/blendColors"; +import { WHITE } from "../../utils/colors/const"; +import { getHighContrast } from "../../utils/colors/getHighContrast"; +import { rgbToCss } from "../../utils/colors/rgbToCss"; +import { rgbaToCss } from "../../utils/colors/rgbaToCss"; +import { RGBA } from "../../utils/colors/types/RGBA"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { useKeyDownStartEnd } from "../../utils/interactions/useKeyDownStartEnd"; +import { clamp } from "../../utils/math/clamp"; +import { Circle } from "../Circle"; +import { ColorLoupe } from "../ColorLoupe"; + +import "./index.css"; + +export type ColorSliderProps = { + value: number; + children?: React.ReactNode; + color: RGBA; + onChange: (value: number) => void; + bg?: React.ReactNode; + width?: number; + height?: number; + step?: number; + shiftStep?: number; + className?: string; + onStart?: () => void; + onEnd?: () => void; +}; + +export function ColorSlider({ + width = 192, + height = 20, + step = 0.01, + shiftStep = 0.1, + ...props +}: ColorSliderProps) { + const [isDown, setIsDown] = useState(false); + const nobRadius = height / 3; + + const updateKeyDown = useKeyDownStartEnd(props.onStart, props.onEnd); + + const handleKeyDown = useCallback( + (e: React.KeyboardEvent) => { + if (e.key === "ArrowLeft" || e.key === "ArrowRight") { + updateKeyDown(); + const sign = e.key === "ArrowLeft" ? -1 : 1; + const signedStep = e.shiftKey ? shiftStep * sign : step * sign; + const alpha = clamp(props.value + signedStep, 0, 1); + props.onChange(alpha); + e.preventDefault(); + } + }, + [props.value, props.onChange, shiftStep, step, updateKeyDown], + ); + + const handleFocus = useCallback(() => { + setIsDown(true); + }, []); + + const handleBlur = useCallback(() => { + setIsDown(false); + }, []); + + const pointerDown = useMemo( + () => + createDragHandler({ + onDown: (e) => { + props.onStart?.(); + const { left } = e.currentTarget.getBoundingClientRect(); + + const x = e.clientX - left; + + const hue = clamp(x / width, 0, 1); + + props.onChange(hue); + + setIsDown(true); + + return { + startX: e.clientX, + startY: e.clientY, + hue: hue, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.startX; + const alpha = clamp(ctx.hue + dx / width, 0, 1); + props.onChange(alpha); + }, + onUp: () => { + setIsDown(false); + props.onEnd?.(); + }, + }), + [props.onChange, props.onStart, props.onEnd, width], + ); + + const handlePointerDown = createDragHandler({ + onDown: (e) => { + setIsDown(true); + e.stopPropagation(); + return { + startX: e.clientX, + startY: e.clientY, + alpha: props.value, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.startX; + const alpha = clamp(ctx.alpha + dx / width, 0, 1); + props.onChange(alpha); + }, + onUp: () => { + setIsDown(false); + }, + }); + + const ref = useTouchStartPrevent<HTMLDivElement>(); + + const x = props.value * width; + const y = height / 2; + const nobRef = useTouchStartPrevent<HTMLDivElement>(); + const color = useMemo(() => { + return rgbToCss( + getHighContrast(blendColors(props.color, WHITE, props.color.a)), + ); + }, [props.color]); + return ( + <div + className={classNames(props.className, "cmpui_color-slider__root")} + onKeyDown={handleKeyDown} + onFocus={handleFocus} + onBlur={handleBlur} + tabIndex={0} + > + <div + style={{ + position: "relative", + overflow: "hidden", + cursor: "pointer", + width: width, + height: height, + }} + onPointerDown={pointerDown} + ref={ref} + > + <div + className="alpha-checker-board" + style={{ + width, + height, + }} + > + {props.bg} + </div> + + <Circle + x={x} + y={y} + radius={nobRadius} + fill="white" + strokeWidth={2} + strokeColor={color} + style={ + { + "--cmpui-block-size": "4px", + pointerEvents: "none", + } as React.CSSProperties + } + className="alpha-checker-board" + /> + <Circle + x={x} + y={y} + radius={nobRadius} + fill={rgbaToCss(props.color)} + strokeColor={color} + strokeWidth={2} + ref={nobRef} + onPointerDown={handlePointerDown} + className="cmpui_color-slider__nob" + /> + </div> + {isDown && ( + <> + <ColorLoupe + nobRadius={nobRadius} + x={x} + y={y} + color={rgbaToCss(props.color)} + /> + </> + )} + </div> + ); +} diff --git a/src/components/ContextMenu/ContextMenuItem.tsx b/src/components/ContextMenu/ContextMenuItem.tsx new file mode 100644 index 0000000..4e12595 --- /dev/null +++ b/src/components/ContextMenu/ContextMenuItem.tsx @@ -0,0 +1,16 @@ +import * as RadixContextMenu from "@radix-ui/react-context-menu"; +import { ListItem } from "../ListItem"; + +export type ContextMenuItemProps = React.ComponentProps< + typeof RadixContextMenu.Item +>; + +export function ContextMenuItem({ children, ...props }: ContextMenuItemProps) { + return ( + <RadixContextMenu.Item {...props} asChild> + <ListItem size="S" rounded> + {children} + </ListItem> + </RadixContextMenu.Item> + ); +} diff --git a/src/components/ContextMenu/ContextMenuSeparator.tsx b/src/components/ContextMenu/ContextMenuSeparator.tsx new file mode 100644 index 0000000..9f68ad4 --- /dev/null +++ b/src/components/ContextMenu/ContextMenuSeparator.tsx @@ -0,0 +1,5 @@ +import * as RadixContextMenu from "@radix-ui/react-context-menu"; + +export function ContextMenuSeparator() { + return <RadixContextMenu.Separator className="context-menu-separator" />; +} diff --git a/src/components/ContextMenu/__snapshots__/index.stories.tsx.snap b/src/components/ContextMenu/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..efd32e5 --- /dev/null +++ b/src/components/ContextMenu/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Float/ContextMenu Basic smoke-test 1`] = ` +<div data-state="closed" + style="width: 200px; height: 200px; border-radius: 4px; border: 1px solid var(--cmpui-border-color); touch-action: none; user-select: none; display: flex; justify-content: center; align-items: center;" +> + Right click me +</div> +`; diff --git a/src/components/ContextMenu/index.css b/src/components/ContextMenu/index.css new file mode 100644 index 0000000..870d34b --- /dev/null +++ b/src/components/ContextMenu/index.css @@ -0,0 +1,7 @@ +.context-menu-separator { + background-color: var(--cmpui-border-color); + + height: 1px; + margin: 3px; + width: 100%; +} diff --git a/src/components/ContextMenu/index.stories.tsx b/src/components/ContextMenu/index.stories.tsx new file mode 100644 index 0000000..b66408c --- /dev/null +++ b/src/components/ContextMenu/index.stories.tsx @@ -0,0 +1,72 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { ContextMenu } from "."; +import { ShortcutListItem } from "../../__stories__/ShortcutListItem"; +import { ContextMenuItem } from "./ContextMenuItem"; + +const meta: Meta<typeof ContextMenu> = { + title: "Components/Float/ContextMenu", + component: ContextMenu, +}; + +export default meta; +type Story = StoryObj<typeof ContextMenu>; + +function ShortcutContextMenuItem( + props: Omit<React.ComponentProps<typeof ShortcutListItem>, "as">, +) { + return <ShortcutListItem {...props} as={ContextMenuItem} />; +} + +export const Basic: Story = { + render: function Render() { + const [open, setOpen] = useState(false); + return ( + <> + <ContextMenu + content={ + <div + style={{ + width: 128, + }} + > + <ShortcutContextMenuItem shortcut="⌘ Z"> + Undo + </ShortcutContextMenuItem> + <ShortcutContextMenuItem shortcut="⇧ ⌘ Z"> + Redo + </ShortcutContextMenuItem> + <ShortcutContextMenuItem shortcut="⌘ X"> + Cut + </ShortcutContextMenuItem> + <ShortcutContextMenuItem shortcut="⌘ C"> + Copy + </ShortcutContextMenuItem> + <ShortcutContextMenuItem shortcut="⌘ V"> + Paste + </ShortcutContextMenuItem> + </div> + } + open={open} + onOpenChange={(open) => setOpen(open)} + > + <div + style={{ + width: 200, + height: 200, + borderRadius: 4, + border: "1px solid var(--cmpui-border-color)", + touchAction: "none", + userSelect: "none", + display: "flex", + justifyContent: "center", + alignItems: "center", + }} + > + Right click me + </div> + </ContextMenu> + </> + ); + }, +}; diff --git a/src/components/ContextMenu/index.tsx b/src/components/ContextMenu/index.tsx new file mode 100644 index 0000000..32b33c0 --- /dev/null +++ b/src/components/ContextMenu/index.tsx @@ -0,0 +1,27 @@ +import * as RadixContextMenu from "@radix-ui/react-context-menu"; +import { FloatBox } from "../FloatBox"; + +import "./index.css"; + +export type ContextMenuProps = { + children: React.ReactNode; + content: React.ReactNode; + open?: boolean; + onOpenChange?: (open: boolean) => void; +}; + +export function ContextMenu(props: ContextMenuProps) { + return ( + <RadixContextMenu.Root onOpenChange={props.onOpenChange}> + <RadixContextMenu.Trigger asChild> + {props.children} + </RadixContextMenu.Trigger> + + <RadixContextMenu.Portal> + <RadixContextMenu.Content asChild> + <FloatBox>{props.content}</FloatBox> + </RadixContextMenu.Content> + </RadixContextMenu.Portal> + </RadixContextMenu.Root> + ); +} diff --git a/src/components/CubicControls/CubicCommand.ts b/src/components/CubicControls/CubicCommand.ts new file mode 100644 index 0000000..764c0f6 --- /dev/null +++ b/src/components/CubicControls/CubicCommand.ts @@ -0,0 +1,35 @@ +export type MoveCommand = { + type: "move"; + x: number; + y: number; +}; + +export type CubicCommand = { + type: "cubic"; + x1: number; + y1: number; + x2: number; + y2: number; + x: number; + y: number; +}; + +export type LineCommand = { + type: "line"; + x: number; + y: number; +}; + +export type QuadraticCommand = { + type: "quadratic"; + x1: number; + y1: number; + x: number; + y: number; +}; + +export type Command = + | MoveCommand + | CubicCommand + | LineCommand + | QuadraticCommand; diff --git a/src/components/CubicControls/__snapshots__/index.stories.tsx.snap b/src/components/CubicControls/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..35ba615 --- /dev/null +++ b/src/components/CubicControls/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,66 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Controls/CubicControls Default smoke-test 1`] = ` +<div style="width: 100px; height: 100px; position: relative;"> + <svg stroke="var(--cmpui-primary-color)" + width="108" + height="108" + viewbox="-4 -4 108 108" + class="cmpui_curve-controls-svg" + style="position: absolute; left: -4px; top: -4px; width: 108px; height: 108px; pointer-events: none;" + > + <path d="M 0 100" + stroke-width="1" + fill="none" + > + </path> + <path d="M 0 100 C 50 100 50 0 100 0" + stroke-width="1" + fill="none" + > + </path> + </svg> + <svg width="51" + height="1" + viewbox="0 0 51 1" + class="cmpui_cubic-controls__line" + style="position: absolute; overflow: visible; pointer-events: none; left: -0.5px; top: 99.5px;" + > + <line class="cmpui_cubic-controls__line" + stroke-width="1" + x1="0.5" + y1="0.5" + x2="50.5" + y2="0.5" + > + </line> + </svg> + <svg width="51" + height="1" + viewbox="0 0 51 1" + class="cmpui_cubic-controls__line" + style="position: absolute; overflow: visible; pointer-events: none; left: 49.5px; top: -0.5px;" + > + <line class="cmpui_cubic-controls__line" + stroke-width="1" + x1="50.5" + y1="0.5" + x2="0.5" + y2="0.5" + > + </line> + </svg> + <div class="cmpui_circle__root cmpui_cubic-controls__circle" + x="50" + y="100" + style="--cmpui-circle-nob-fill: var(--cmpui-primary-color); --cmpui-circle-nob-radius: 6px; --cmpui-circle-nob-stroke-color: var(--cmpui-border-color); --cmpui-circle-nob-stroke-width: 1px; border: 1px solid var(--cmpui-border-color); left: 44px; top: 94px;" + > + </div> + <div class="cmpui_circle__root cmpui_cubic-controls__circle" + x="50" + y="0" + style="--cmpui-circle-nob-fill: var(--cmpui-primary-color); --cmpui-circle-nob-radius: 6px; --cmpui-circle-nob-stroke-color: var(--cmpui-border-color); --cmpui-circle-nob-stroke-width: 1px; border: 1px solid var(--cmpui-border-color); left: 44px; top: -6px;" + > + </div> +</div> +`; diff --git a/src/components/CubicControls/index.css b/src/components/CubicControls/index.css new file mode 100644 index 0000000..108a344 --- /dev/null +++ b/src/components/CubicControls/index.css @@ -0,0 +1,15 @@ +.cmpui_cubic-controls__circle { + cursor: grab; + stroke-width: 1px; +} + +.cmpui_cubic-controls__circle:active { + cursor: grabbing; +} + +.cmpui_cubic-controls__line { + stroke: var(--cmpui-border-color); + + fill: none; + pointer-events: none; +} diff --git a/src/components/CubicControls/index.stories.tsx b/src/components/CubicControls/index.stories.tsx new file mode 100644 index 0000000..d286e2e --- /dev/null +++ b/src/components/CubicControls/index.stories.tsx @@ -0,0 +1,48 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { clamp } from "../../utils/math/clamp"; +import { CubicControls } from "../CubicControls"; +import { Command, CubicCommand } from "./CubicCommand"; + +const meta: Meta<typeof CubicControls> = { + title: "Components/Controls/CubicControls", + component: CubicControls, +}; + +export default meta; +type Story = StoryObj<typeof CubicControls>; + +export const Default: Story = { + render: function Render() { + const [commands, setCommands] = useState<Command[]>([ + { type: "move", x: 0, y: 100 }, + { type: "cubic", x: 100, y: 0, x1: 50, y1: 100, x2: 50, y2: 0 }, + ]); + const cubic = commands[1] as CubicCommand; + + return ( + <div + style={{ + width: 100, + height: 100, + position: "relative", + }} + > + <CubicControls + prev={commands[0]} + cubic={cubic} + onChange={(cubic) => { + cubic.x = clamp(cubic.x, 0, 100); + cubic.y = clamp(cubic.y, 0, 100); + cubic.x1 = clamp(cubic.x1, 0, 100); + cubic.y1 = clamp(cubic.y1, 0, 100); + cubic.x2 = clamp(cubic.x2, 0, 100); + cubic.y2 = clamp(cubic.y2, 0, 100); + + setCommands([commands[0], cubic]); + }} + /> + </div> + ); + }, +}; diff --git a/src/components/CubicControls/index.tsx b/src/components/CubicControls/index.tsx new file mode 100644 index 0000000..3e39659 --- /dev/null +++ b/src/components/CubicControls/index.tsx @@ -0,0 +1,122 @@ +import { useCallback, useMemo } from "react"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { Circle } from "../Circle"; +import { Line } from "../Line"; +import { Path } from "../Path"; +import { Command, CubicCommand, MoveCommand } from "./CubicCommand"; + +import "./index.css"; + +export type CubicControlsProps = { + prev: { x: number; y: number }; + cubic: CubicCommand; + onChange?: (cubic: CubicCommand) => void; +}; + +export function CubicControls({ prev, cubic, onChange }: CubicControlsProps) { + const { x1, y1, x2, y2, x, y } = cubic; + const { x: x0, y: y0 } = prev; + + const move: MoveCommand = { + type: "move", + x: prev.x, + y: prev.y, + }; + + const getPointerDownHandler = useCallback(( + x: number, + y: number, + onChange: (x: number, y: number) => void, + ) => { + return createDragHandler({ + onDown: (e) => { + return { + x: e.clientX, + y: e.clientY, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.x; + const dy = e.clientY - ctx.y; + + const x1 = x + dx; + const y1 = y + dy; + onChange(x1, y1); + }, + }); + }, []); + + const handleP1 = useMemo(() => { + return getPointerDownHandler(x1, y1, (x1, y1) => { + onChange?.({ ...cubic, x1, y1 }); + }); + }, [cubic, x1, y1, onChange, getPointerDownHandler]); + + const handleP2 = useMemo(() => { + return getPointerDownHandler(x2, y2, (x2, y2) => { + onChange?.({ ...cubic, x2, y2 }); + }); + }, [cubic, x2, y2, onChange, getPointerDownHandler]); + + const handlePathChange = useCallback( + (commands: Command[]) => { + commands.forEach((command) => { + if (command.type !== "cubic") return; + onChange?.(command); + }); + }, + [onChange], + ); + + const commands = useMemo(() => [move, cubic], [move, cubic]); + + return ( + <> + <Path + commands={commands} + onChange={handlePathChange} + stroke="var(--cmpui-primary-color)" + style={{ + pointerEvents: "none", + }} + /> + <Line + className="cmpui_cubic-controls__line" + strokeWidth={1} + x1={x0} + y1={y0} + x2={x1} + y2={y1} + /> + <Line + className="cmpui_cubic-controls__line" + strokeWidth={1} + x1={x} + y1={y} + x2={x2} + y2={y2} + /> + <Circle + className="cmpui_cubic-controls__circle" + x={x1} + y={y1} + radius={6} + onPointerDown={handleP1} + fill="var(--cmpui-primary-color)" + strokeColor="var(--cmpui-border-color)" + strokeWidth={1} + /> + <Circle + className="cmpui_cubic-controls__circle" + x={x2} + y={y2} + radius={6} + onPointerDown={handleP2} + fill="var(--cmpui-primary-color)" + strokeColor="var(--cmpui-border-color)" + strokeWidth={1} + /> + </> + ); +} diff --git a/src/components/DropdownMenu/DropdownMenuItem.tsx b/src/components/DropdownMenu/DropdownMenuItem.tsx new file mode 100644 index 0000000..05ffb7f --- /dev/null +++ b/src/components/DropdownMenu/DropdownMenuItem.tsx @@ -0,0 +1,19 @@ +import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; +import { ListItem } from "../ListItem"; + +export type DropdownMenuItemProps = React.ComponentProps< + typeof DropdownMenu.Item +>; + +export function DropdownMenuItem({ + children, + ...props +}: DropdownMenuItemProps) { + return ( + <DropdownMenu.Item {...props} asChild> + <ListItem size="S" rounded> + {children} + </ListItem> + </DropdownMenu.Item> + ); +} diff --git a/src/components/DropdownMenu/__snapshots__/index.stories.tsx.snap b/src/components/DropdownMenu/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..778e8dc --- /dev/null +++ b/src/components/DropdownMenu/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Float/DropdownMenu Basic smoke-test 1`] = ` +<div style="height: 128px;"> + <button type="button" + class="cmpui_button" + id="radix-:r0:" + aria-haspopup="menu" + aria-expanded="false" + data-state="closed" + data-variant="primary" + data-size="M" + > + Open + </button> +</div> +`; diff --git a/src/components/DropdownMenu/index.stories.tsx b/src/components/DropdownMenu/index.stories.tsx new file mode 100644 index 0000000..e2d4a0c --- /dev/null +++ b/src/components/DropdownMenu/index.stories.tsx @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { DropdownMenu } from "."; +import { Button } from "../Button"; +import { DropdownMenuItem } from "./DropdownMenuItem"; + +const meta: Meta<typeof DropdownMenu> = { + title: "Components/Float/DropdownMenu", + component: DropdownMenu, +}; + +export default meta; +type Story = StoryObj<typeof DropdownMenu>; + +export const Basic: Story = { + render: function Render() { + const [open, setOpen] = useState(false); + return ( + <div + style={{ + height: 128, + }} + > + <DropdownMenu + content={ + <> + <DropdownMenuItem>New</DropdownMenuItem> + <DropdownMenuItem>Delete</DropdownMenuItem> + <DropdownMenuItem disabled>Disabled</DropdownMenuItem> + </> + } + open={open} + onOpenChange={(open) => setOpen(open)} + > + <Button>Open</Button> + </DropdownMenu> + </div> + ); + }, +}; diff --git a/src/components/DropdownMenu/index.tsx b/src/components/DropdownMenu/index.tsx new file mode 100644 index 0000000..1754e27 --- /dev/null +++ b/src/components/DropdownMenu/index.tsx @@ -0,0 +1,29 @@ +import * as RadixDropdownMenu from "@radix-ui/react-dropdown-menu"; +import { FloatBox } from "../FloatBox"; + +export type DropdownMenuProps = { + children: React.ReactNode; + content: React.ReactNode; + open?: boolean; + onOpenChange?: (open: boolean) => void; +}; + +export function DropdownMenu(props: DropdownMenuProps) { + return ( + <RadixDropdownMenu.Root open={props.open} onOpenChange={props.onOpenChange}> + <RadixDropdownMenu.Trigger asChild> + {props.children} + </RadixDropdownMenu.Trigger> + + <RadixDropdownMenu.Content + align="start" + sideOffset={2} + collisionPadding={8} + alignOffset={0} + asChild + > + <FloatBox>{props.content}</FloatBox> + </RadixDropdownMenu.Content> + </RadixDropdownMenu.Root> + ); +} diff --git a/src/components/FloatBox/__snapshots__/index.stories.tsx.snap b/src/components/FloatBox/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..88ddbcd --- /dev/null +++ b/src/components/FloatBox/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,63 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Float/FloatBox Basic smoke-test 1`] = ` +<div class="cmpui_float-box__root" + style="width: 128px;" +> + <li class="cmpui_list-item__root shortcut-list-item" + data-size="S" + data-rounded="true" + > + <div style="width: 100%;"> + Undo + </div> + <div style="font-size: 10px; margin-left: 16px; white-space: nowrap;"> + ⌘ Z + </div> + </li> + <li class="cmpui_list-item__root shortcut-list-item" + data-size="S" + data-rounded="true" + > + <div style="width: 100%;"> + Redo + </div> + <div style="font-size: 10px; margin-left: 16px; white-space: nowrap;"> + ⇧ ⌘ Z + </div> + </li> + <li class="cmpui_list-item__root shortcut-list-item" + data-size="S" + data-rounded="true" + > + <div style="width: 100%;"> + Cut + </div> + <div style="font-size: 10px; margin-left: 16px; white-space: nowrap;"> + ⌘ X + </div> + </li> + <li class="cmpui_list-item__root shortcut-list-item" + data-size="S" + data-rounded="true" + > + <div style="width: 100%;"> + Copy + </div> + <div style="font-size: 10px; margin-left: 16px; white-space: nowrap;"> + ⌘ C + </div> + </li> + <li class="cmpui_list-item__root shortcut-list-item" + data-size="S" + data-rounded="true" + > + <div style="width: 100%;"> + Paste + </div> + <div style="font-size: 10px; margin-left: 16px; white-space: nowrap;"> + ⌘ V + </div> + </li> +</div> +`; diff --git a/src/components/FloatBox/index.css b/src/components/FloatBox/index.css new file mode 100644 index 0000000..6d44f83 --- /dev/null +++ b/src/components/FloatBox/index.css @@ -0,0 +1,19 @@ +.cmpui_float-box__root { + background-color: var(--cmpui-bg-color); + border: 1px solid var(--cmpui-border-color); + box-shadow: var(--cmpui-float-shadow); + + align-items: center; + border-radius: 4px; + box-sizing: border-box; + display: flex; + flex-direction: column; + font-size: 12px; + height: fit-content; + padding: 4px; + position: relative; + transition: all 0.2s ease-in-out; + width: fit-content; + z-index: 1000; +} + diff --git a/src/components/FloatBox/index.stories.tsx b/src/components/FloatBox/index.stories.tsx new file mode 100644 index 0000000..bb3abb0 --- /dev/null +++ b/src/components/FloatBox/index.stories.tsx @@ -0,0 +1,39 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { FloatBox } from "."; +import { ShortcutListItem } from "../../__stories__/ShortcutListItem"; + +const meta: Meta<typeof FloatBox> = { + title: "Components/Float/FloatBox", + component: FloatBox, +}; + +export default meta; +type Story = StoryObj<typeof FloatBox>; + +export const Basic: Story = { + render: function Render() { + return ( + <FloatBox + style={{ + width: 128, + }} + > + <ShortcutListItem rounded size="S" shortcut="⌘ Z"> + Undo + </ShortcutListItem> + <ShortcutListItem rounded size="S" shortcut="⇧ ⌘ Z"> + Redo + </ShortcutListItem> + <ShortcutListItem rounded size="S" shortcut="⌘ X"> + Cut + </ShortcutListItem> + <ShortcutListItem rounded size="S" shortcut="⌘ C"> + Copy + </ShortcutListItem> + <ShortcutListItem rounded size="S" shortcut="⌘ V"> + Paste + </ShortcutListItem> + </FloatBox> + ); + }, +}; diff --git a/src/components/FloatBox/index.tsx b/src/components/FloatBox/index.tsx new file mode 100644 index 0000000..02b639d --- /dev/null +++ b/src/components/FloatBox/index.tsx @@ -0,0 +1,16 @@ +import { forwardRef } from "react"; +import { classNames } from "../../utils/classNames"; + +import "./index.css"; + +export const FloatBox = forwardRef<HTMLDivElement, React.ComponentProps<"div">>( + function FloatBox({ className, ...props }, ref) { + return ( + <div + className={classNames("cmpui_float-box__root", className)} + ref={ref} + {...props} + /> + ); + }, +); diff --git a/src/components/Grid/__snapshots__/index.stories.tsx.snap b/src/components/Grid/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..e2820d5 --- /dev/null +++ b/src/components/Grid/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/View/Grid Basic smoke-test 1`] = ` +<div style="width: 100vh; height: 300px;"> + <div class="cmpui_grid__root" + style="--offset-x: 10px; --offset-y: 25px; --size-x: 50px; --size-y: 50px;" + > + </div> +</div> +`; diff --git a/src/components/Grid/index.css b/src/components/Grid/index.css new file mode 100644 index 0000000..38cdc1a --- /dev/null +++ b/src/components/Grid/index.css @@ -0,0 +1,21 @@ +.cmpui_grid__root { + --cmpui-color: color-mix( + in srgb, + var(--cmpui-primary-color) 50%, + var(--cmpui-bg-color) + ); + --cmpui-size-x: 50px; + --cmpui-size-y: 50px; + + background-image: linear-gradient(0deg, var(--cmpui-color) 1px, transparent 1px), + linear-gradient(-90deg, var(--cmpui-color) 1px, transparent 1px); + background-position: var(--cmpui-offset-x) var(--cmpui-offset-y); + background-size: var(--cmpui-size-x) var(--cmpui-size-y); + + height: 100%; + left: 0px; + opacity: 0.5; + position: absolute; + top: 0px; + width: 100%; +} diff --git a/src/components/Grid/index.stories.tsx b/src/components/Grid/index.stories.tsx new file mode 100644 index 0000000..5f70a60 --- /dev/null +++ b/src/components/Grid/index.stories.tsx @@ -0,0 +1,28 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Grid } from "."; + +const meta: Meta<typeof Grid> = { + title: "Components/View/Grid", + component: Grid, + parameters: { + layout: "fullscreen", + }, +}; + +export default meta; +type Story = StoryObj<typeof Grid>; + +export const Basic: Story = { + render: function Render() { + return ( + <div + style={{ + width: "100vh", + height: 300, + }} + > + <Grid sizeX={50} sizeY={50} offsetX={10} offsetY={25} /> + </div> + ); + }, +}; diff --git a/src/components/Grid/index.tsx b/src/components/Grid/index.tsx new file mode 100644 index 0000000..84b81eb --- /dev/null +++ b/src/components/Grid/index.tsx @@ -0,0 +1,42 @@ +import { useLayoutEffect, useRef } from "react"; +import { classNames } from "../../utils/classNames"; + +import "./index.css"; + +export type GridProps = { + offsetX?: number; + offsetY?: number; + sizeX?: number; + sizeY?: number; + color?: string; +} & Omit<React.ComponentPropsWithoutRef<"div">, "children">; + +export function Grid({ + offsetX = 0, + offsetY = 0, + sizeX = 50, + sizeY = 50, + className, + ...props +}: GridProps) { + const ref = useRef<HTMLDivElement>(null); + + useLayoutEffect(() => { + if (!ref.current) return; + ref.current.style.setProperty("--offset-x", `${offsetX}px`); + ref.current.style.setProperty("--offset-y", `${offsetY}px`); + ref.current.style.setProperty("--size-x", `${sizeX}px`); + ref.current.style.setProperty("--size-y", `${sizeY}px`); + if (props.color) { + ref.current.style.setProperty("--color", props.color); + } + }); + + return ( + <div + className={classNames("cmpui_grid__root", className)} + ref={ref} + {...props} + /> + ); +} diff --git a/src/components/HueCircle/__snapshots__/index.stories.tsx.snap b/src/components/HueCircle/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..a010992 --- /dev/null +++ b/src/components/HueCircle/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,61 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Colors/HueCircle Default smoke-test 1`] = ` +<div class="cmpui_hue-circle__root" + tabindex="0" + style="--cmpui-width: 24px; --cmpui-size: 192px;" +> + <div class="cmpui_hue-circle__hue" + style="width: 192px; height: 192px;" + > + </div> + <div x="96" + y="12" + class="cmpui_circle__root cmpui_hue-circle__nob" + style="--cmpui-circle-nob-fill: rgb(255,0,0); --cmpui-circle-nob-radius: 8px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 88px; top: 4px;" + > + </div> + <div class="cmpui_hue-circle__inner"> + </div> +</div> +`; + +exports[`Components/Colors/HueCircle ForMobile smoke-test 1`] = ` +<div class="cmpui_hue-circle__root" + tabindex="0" + style="--cmpui-width: 32px; --cmpui-size: 192px;" +> + <div class="cmpui_hue-circle__hue" + style="width: 192px; height: 192px;" + > + </div> + <div x="96" + y="16" + class="cmpui_circle__root cmpui_hue-circle__nob" + style="--cmpui-circle-nob-fill: rgb(255,0,0); --cmpui-circle-nob-radius: 10.666666666666666px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 85.3333px; top: 5.33333px;" + > + </div> + <div class="cmpui_hue-circle__inner"> + </div> +</div> +`; + +exports[`Components/Colors/HueCircle Size smoke-test 1`] = ` +<div class="cmpui_hue-circle__root" + tabindex="0" + style="--cmpui-width: 24px; --cmpui-size: 64px;" +> + <div class="cmpui_hue-circle__hue" + style="width: 64px; height: 64px;" + > + </div> + <div x="32" + y="12" + class="cmpui_circle__root cmpui_hue-circle__nob" + style="--cmpui-circle-nob-fill: rgb(255,0,0); --cmpui-circle-nob-radius: 8px; --cmpui-circle-nob-stroke-color: rgb(255,255,255); --cmpui-circle-nob-stroke-width: 2px; border: 2px solid rgb(255, 255, 255); left: 24px; top: 4px;" + > + </div> + <div class="cmpui_hue-circle__inner"> + </div> +</div> +`; diff --git a/src/components/HueCircle/index.css b/src/components/HueCircle/index.css new file mode 100644 index 0000000..5e09f4b --- /dev/null +++ b/src/components/HueCircle/index.css @@ -0,0 +1,55 @@ +.cmpui_hue-circle__hue { + border: 1px solid var(--cmpui-border-color); + + background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red); + border-radius: 50%; + border-radius: 9999px; + box-sizing: border-box; + cursor: pointer; + position: relative; + + mask-image: radial-gradient( + var(--cmpui-size) var(--cmpui-size), + rgba(0, 0, 0, 0) calc(var(--cmpui-size) / 2 - var(--cmpui-width)), + black calc(var(--cmpui-size) / 2 - var(--cmpui-width) + 1px) + ); +} + +.cmpui_hue-circle__hue:focus-visible { + outline: 1px solid var(--cmpui-primary-color); + outline-offset: 1px; +} + +.cmpui_hue-circle__root { + --cmpui-width: 16px; + + position: relative; +} + +.cmpui_hue-circle__root:focus-visible { + outline: 1px solid var(--cmpui-primary-color); + outline-offset: 1px; + border-radius: 9999px; +} + +.cmpui_hue-circle__nob { + cursor: grab; +} + +.cmpui_hue-circle__nob:active { + cursor: grabbing; +} + +.cmpui_hue-circle__inner { + background: transparent; + border: 1px solid var(--cmpui-border-color); + height: calc(100% - var(--cmpui-width) * 2); + left: calc(var(--cmpui-width)); + top: calc(var(--cmpui-width)); + width: calc(100% - var(--cmpui-width) * 2); + + border-radius: 9999px; + box-sizing: border-box; + cursor: default; + position: absolute; +} diff --git a/src/components/HueCircle/index.stories.tsx b/src/components/HueCircle/index.stories.tsx new file mode 100644 index 0000000..669ba32 --- /dev/null +++ b/src/components/HueCircle/index.stories.tsx @@ -0,0 +1,37 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { HueCircle } from "."; + +const meta: Meta<typeof HueCircle> = { + title: "Components/Colors/HueCircle", + component: HueCircle, +}; + +export default meta; +type Story = StoryObj<typeof HueCircle>; + +export const Default: Story = { + render: function Render() { + const [hue, setHue] = useState(0); + + return <HueCircle hue={hue} onHueChange={setHue} />; + }, +}; + +export const Size: Story = { + render: function Render() { + const [hue, setHue] = useState(0); + + return <HueCircle hue={hue} onHueChange={setHue} size={64} />; + }, +}; + +export const ForMobile: Story = { + render: function Render() { + const [hue, setHue] = useState(0); + + return ( + <HueCircle hue={hue} showLoupe onHueChange={setHue} strokeWidth={32} /> + ); + }, +}; diff --git a/src/components/HueCircle/index.tsx b/src/components/HueCircle/index.tsx new file mode 100644 index 0000000..bede27b --- /dev/null +++ b/src/components/HueCircle/index.tsx @@ -0,0 +1,221 @@ +import { useCallback, useMemo, useState } from "react"; +import { useTouchStartPrevent } from "../.."; +import { hsvToRgb } from "../../utils/colors/hsvToRgb"; +import { rgbToCss } from "../../utils/colors/rgbToCss"; +import { useHighContrastColor } from "../../utils/colors/useHighContrastColor"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { useKeyDownStartEnd } from "../../utils/interactions/useKeyDownStartEnd"; +import { degToRad } from "../../utils/math/degToRad"; +import { radToDeg } from "../../utils/math/radToDeg"; +import { Circle } from "../Circle"; +import { ColorLoupe } from "../ColorLoupe"; + +import "./index.css"; + +const _360 = 360; + +export type HueCircleProps = { + hue: number; + size?: number; + strokeWidth?: number; + showLoupe?: boolean; + onHueChange?: (hue: number) => void; + onStart?: () => void; + onEnd?: () => void; +}; + +export function HueCircle({ + strokeWidth = 24, + size = 192, + showLoupe = true, + ...props +}: HueCircleProps) { + const nobRadius = strokeWidth / 3; + const radius = size / 2 - strokeWidth / 2; + + const rad = degToRad(props.hue) - Math.PI / 2; + const x = Math.cos(rad) * radius + size / 2; + const y = Math.sin(rad) * radius + size / 2; + + const [isDown, setIsDown] = useState(false); + const updateKeyDown = useKeyDownStartEnd(props.onStart, props.onEnd); + + const handleKeyDown = useMemo( + () => (e: React.KeyboardEvent) => { + let sign = 0; + if (e.key === "ArrowLeft" || e.key === "ArrowDown") { + sign = -1; + updateKeyDown(); + } else if (e.key === "ArrowRight" || e.key === "ArrowUp") { + sign = 1; + updateKeyDown(); + } + + if (sign !== 0) { + const signedStep = 1 * sign; + const value = props.hue + signedStep; + if (value < 0) { + props.onHueChange?.(value + _360); + } else { + props.onHueChange?.(value); + } + e.preventDefault(); + } + }, + [props.onHueChange, props.hue, updateKeyDown], + ); + + const handleFocus = useCallback(() => { + setIsDown(true); + }, []); + + const handleBlur = useCallback(() => { + setIsDown(false); + }, []); + + const handlePointerDown = useMemo( + () => + createDragHandler({ + onDown: (e) => { + setIsDown(true); + props.onStart?.(); + const rect = e.currentTarget.getBoundingClientRect(); + const centerX = rect.left + size / 2; + const centerY = rect.top + size / 2; + + const angle = + Math.atan2(e.clientY - centerY, e.clientX - centerX) + Math.PI / 2; + const hue = radToDeg(angle); + if (hue < 0) { + props.onHueChange?.(hue + _360); + return { + centerX, + centerY, + }; + } + props.onHueChange?.(hue); + + return { + centerX, + centerY, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.centerX; + const dy = e.clientY - ctx.centerY; + const angle = Math.atan2(dy, dx) + Math.PI / 2; + const hue = radToDeg(angle); + if (hue < 0) { + props.onHueChange?.(hue + _360); + return; + } + props.onHueChange?.(hue); + }, + onUp: () => { + setIsDown(false); + props.onEnd?.(); + }, + }), + [props.onHueChange, size, props.onEnd, props.onStart], + ); + + const handlePointerDownNob = useMemo( + () => + createDragHandler({ + onDown: (e) => { + setIsDown(true); + const rect = ref.current?.getBoundingClientRect(); + if (!rect) return false; + const centerX = rect.left + size / 2; + const centerY = rect.top + size / 2; + + const nobRect = e.currentTarget.getBoundingClientRect(); + const nobCenterX = nobRect.left + nobRect.width / 2; + const nobCenterY = nobRect.top + nobRect.height / 2; + + e.stopPropagation(); + + return { + centerX, + centerY, + offsetX: nobCenterX - e.clientX, + offsetY: nobCenterY - e.clientY, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.centerX + ctx.offsetX; + const dy = e.clientY - ctx.centerY + ctx.offsetY; + const angle = Math.atan2(dy, dx) + Math.PI / 2; + const hue = radToDeg(angle); + if (hue < 0) { + props.onHueChange?.(hue + _360); + return; + } + props.onHueChange?.(hue); + }, + onUp: () => { + setIsDown(false); + }, + }), + [props.onHueChange, size], + ); + + const ref = useTouchStartPrevent<HTMLDivElement>(); + + const onlyHue = useMemo(() => { + return { + h: props.hue, + s: 1, + v: 1, + }; + }, [props.hue]); + + const stroke = useHighContrastColor(onlyHue); + + const fill = useMemo(() => { + return rgbToCss(hsvToRgb(onlyHue)); + }, [onlyHue]); + + return ( + <div + className="cmpui_hue-circle__root" + style={ + { + "--cmpui-width": `${strokeWidth}px`, + "--cmpui-size": `${size}px`, + } as React.CSSProperties + } + tabIndex={0} + onKeyDown={handleKeyDown} + onFocus={handleFocus} + onBlur={handleBlur} + > + <div + className="cmpui_hue-circle__hue" + onPointerDown={handlePointerDown} + ref={ref} + style={{ + width: size, + height: size, + }} + /> + <Circle + x={x} + y={y} + radius={nobRadius} + fill={fill} + onPointerDown={handlePointerDownNob} + strokeWidth={2} + strokeColor={stroke} + className="cmpui_hue-circle__nob" + /> + + <div className="cmpui_hue-circle__inner" /> + {showLoupe && isDown && ( + <ColorLoupe nobRadius={nobRadius} x={x} y={y} color={fill} /> + )} + </div> + ); +} diff --git a/src/components/IconButton/IconButtonGroup.tsx b/src/components/IconButton/IconButtonGroup.tsx new file mode 100644 index 0000000..1ef01d2 --- /dev/null +++ b/src/components/IconButton/IconButtonGroup.tsx @@ -0,0 +1,19 @@ +import React, { forwardRef } from "react"; +import { classNames } from "../../utils/classNames"; + +export const IconButtonGroup = forwardRef< + HTMLDivElement, + { + children: React.ReactNode; + className?: string; + } +>((props, ref) => { + return ( + <div + ref={ref} + className={classNames("cmpui_icon-button__group", props.className)} + > + {props.children} + </div> + ); +}); diff --git a/src/components/IconButton/__snapshots__/index.stories.tsx.snap b/src/components/IconButton/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..6cec3b2 --- /dev/null +++ b/src/components/IconButton/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,131 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Actions/IconButton Basic smoke-test 1`] = ` +<div style="display: flex; gap: 4px;"> + <button type="button" + class="cmpui_icon-button__root" + data-size="M" + > + <span class="material-symbols-outlined" + data-filled="true" + style="font-size: 20px;" + > + arrow_selector_tool + </span> + </button> + <button type="button" + class="cmpui_icon-button__root" + aria-selected="true" + data-size="M" + > + <span class="material-symbols-outlined" + style="font-size: 20px;" + > + square + </span> + <svg width="6" + height="6" + viewbox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + style="position: absolute; bottom: 4px; right: 4px; transform: scaleX(-1);" + > + <title> + corner + + + + + + + +`; + +exports[`Components/Actions/IconButton Disabled smoke-test 1`] = ` + +`; + +exports[`Components/Actions/IconButton Group smoke-test 1`] = ` +
+ + + +
+`; + +exports[`Components/Actions/IconButton Selected smoke-test 1`] = ` + +`; + +exports[`Components/Actions/IconButton Small smoke-test 1`] = ` + +`; diff --git a/src/components/IconButton/index.css b/src/components/IconButton/index.css new file mode 100644 index 0000000..e94c8d7 --- /dev/null +++ b/src/components/IconButton/index.css @@ -0,0 +1,97 @@ +.cmpui_icon-button__root { + color: var(--cmpui-text-color); + + align-items: center; + background-color: transparent; + border-radius: 4px; + border: none; + box-sizing: border-box; + cursor: pointer; + display: flex; + font-size: 16px; + height: 32px; + justify-content: center; + line-height: 16px; + padding: 0; + position: relative; + text-align: center; + text-decoration: none; + transition: background-color 0.1s ease-in-out; + width: 32px; + will-change: background-color; +} + +.cmpui_icon-button__root:hover { + background-color: var(--cmpui-bg-hover-color); +} + +.cmpui_icon-button__root:active { + background-color: var(--cmpui-bg-active-color); +} + +.cmpui_icon-button__root:focus-visible { + background-color: var(--cmpui-bg-active-color); + outline: var(--cmpui-primary-color) solid 1px; + + outline-offset: 1px; +} + +.cmpui_icon-button__root[aria-selected="true"] { + background-color: var(--cmpui-bg-focus-color); + + color: white; +} + +.cmpui_icon-button__root[aria-selected="true"]:hover { + background-color: var(--cmpui-bg-focus-color); +} + +.cmpui_icon-button__root[aria-selected="true"]:active { + background-color: var(--cmpui-bg-focus-color); +} + +.cmpui_icon-button__root[data-size="S"] { + font-size: 12px; + height: 24px; + line-height: 12px; + width: 24px; +} + +.cmpui_icon-button__root:disabled { + opacity: 0.5; + cursor: default; +} + +.cmpui_icon-button__root:disabled:hover { + background-color: transparent; +} + +.cmpui_icon-button__root:disabled:active { + background-color: transparent; +} + +.cmpui_icon-button__group { + border: 1px solid var(--cmpui-border-color); + background-color: var(--cmpui-bg-color); + + align-items: center; + border-radius: 4px; + box-sizing: border-box; + display: flex; + flex-direction: row; + height: 32px; +} + +.cmpui_icon-button__group > .cmpui_icon-button__root { + border-radius: 0; +} + +.cmpui_icon-button__group > :first-child { + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} + +.cmpui_icon-button__group > :last-child { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; +} diff --git a/src/components/IconButton/index.stories.tsx b/src/components/IconButton/index.stories.tsx new file mode 100644 index 0000000..6873798 --- /dev/null +++ b/src/components/IconButton/index.stories.tsx @@ -0,0 +1,99 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { IconButton } from "."; +import { Icon } from "../../__stories__/Icon"; +import { IconButtonGroup } from "./IconButtonGroup"; + +const meta: Meta = { + title: "Components/Actions/IconButton", + component: IconButton, +}; + +export default meta; + +type Story = StoryObj; + +const corner = ( + + corner + + +); + +export const Basic: Story = { + render: () => { + return ( +
+ + + + + + {corner} + + + + +
+ ); + }, +}; + +export const Selected: Story = { + render: () => { + return ( + + + + ); + }, +}; + +export const Disabled: Story = { + render: () => { + return ( + + + + ); + }, +}; + +export const Small: Story = { + render: () => { + return ( + + + + ); + }, +}; + +export const Group: Story = { + render: () => { + return ( + + + + + + + + + + + + ); + }, +}; diff --git a/src/components/IconButton/index.tsx b/src/components/IconButton/index.tsx new file mode 100644 index 0000000..9f03649 --- /dev/null +++ b/src/components/IconButton/index.tsx @@ -0,0 +1,29 @@ +import { forwardRef } from "react"; +import { classNames } from "../../utils/classNames"; + +import "./index.css"; + +export type IconButton = { + selected?: boolean; + size?: "S" | "M"; +} & JSX.IntrinsicElements["button"]; + +export const IconButton = forwardRef( + function IconButton( + { children, size = "M", selected, className, ...props }, + ref, + ) { + return ( + + ); + }, +); diff --git a/src/components/Line/__snapshots__/index.stories.tsx.snap b/src/components/Line/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..1e2bbcf --- /dev/null +++ b/src/components/Line/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Controls/Line Basic smoke-test 1`] = ` +
+ + + + +
+`; diff --git a/src/components/Line/index.stories.tsx b/src/components/Line/index.stories.tsx new file mode 100644 index 0000000..16fb063 --- /dev/null +++ b/src/components/Line/index.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Line } from "."; + +const meta: Meta = { + title: "Components/Controls/Line", + component: Line, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = { + render: function Render() { + return ( +
+ +
+ ); + }, +}; diff --git a/src/components/Line/index.tsx b/src/components/Line/index.tsx new file mode 100644 index 0000000..1277f41 --- /dev/null +++ b/src/components/Line/index.tsx @@ -0,0 +1,38 @@ +import React from "react"; + +export type LineProps = { + strokeWidth: number; + x1: number; + x2: number; + y1: number; + y2: number; +} & React.SVGProps; + +export function Line(props: LineProps) { + const width = Math.abs(props.x2 - props.x1); + const height = Math.abs(props.y2 - props.y1); + const padding = props.strokeWidth; + return ( + + + + ); +} diff --git a/src/components/ListItem/__snapshots__/index.stories.tsx.snap b/src/components/ListItem/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..c4ac65b --- /dev/null +++ b/src/components/ListItem/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,120 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/View/ListItem Basic smoke-test 1`] = ` +
    +
  1. + Item1 +
  2. +
  3. + Item2 +
  4. +
  5. + Item3 +
  6. +
+`; + +exports[`Components/View/ListItem Commands smoke-test 1`] = ` +
+
    +
  1. + Undo + + ⌘ Z + +
  2. +
  3. + Redo + + ⇧ ⌘ Z + +
  4. +
  5. + Cut + + ⌘ X + +
  6. +
  7. + Copy + + ⌘ C + +
  8. +
  9. + Paste + + ⌘ V + +
  10. +
+
+`; + +exports[`Components/View/ListItem Selected smoke-test 1`] = ` +
    +
  1. + Item1 +
  2. +
  3. + Item2 +
  4. +
  5. + Item3 +
  6. +
+`; + +exports[`Components/View/ListItem Small smoke-test 1`] = ` +
    +
  1. + Item1 +
  2. +
  3. + Item2 +
  4. +
  5. + Item3 +
  6. +
+`; diff --git a/src/components/ListItem/index.css b/src/components/ListItem/index.css new file mode 100644 index 0000000..dc959b6 --- /dev/null +++ b/src/components/ListItem/index.css @@ -0,0 +1,60 @@ +.cmpui_list-item__root { + color: var(--cmpui-text-color); + + align-items: center; + box-sizing: border-box; + display: flex; + flex-direction: row; + font-size: 14px; + min-height: 32px; + padding: 0 8px; + width: 100%; + cursor: pointer; +} + +.cmpui_list-item__root:hover { + background-color: var(--cmpui-bg-hover-color); +} + +.cmpui_list-item__root:active { + background-color: var(--cmpui-bg-active-color); +} + +.cmpui_list-item__root[data-highlighted], +.cmpui_list-item__root[data-highlighted]:active, +.cmpui_list-item__root[data-highlighted]:active, +.cmpui_list-item__root[data-highlighted]:hover, +.cmpui_list-item__root:focus-visible { + background-color: var(--cmpui-bg-focus-color); + color: white; + outline: none; +} + +.cmpui_list-item__root[aria-selected="true"] { + background-color: var(--cmpui-bg-focus-color); + + color: white; +} + +.cmpui_list-item__root[aria-disabled="true"], +.cmpui_list-item__root[aria-disabled="true"]:hover, +.cmpui_list-item__root[aria-disabled="true"]:active { + background-color: transparent; + cursor: default; + opacity: 0.7; +} + +.cmpui_list-item__root[data-size="S"] { + font-size: 12px; + height: 24px; + min-height: 24px; +} + +.cmpui_list-item__root[data-rounded="true"] { + border-radius: 4px; +} + +.cmpui_list-list__root { + margin: 0; + padding: 0; +} diff --git a/src/components/ListItem/index.stories.tsx b/src/components/ListItem/index.stories.tsx new file mode 100644 index 0000000..7c636ba --- /dev/null +++ b/src/components/ListItem/index.stories.tsx @@ -0,0 +1,95 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { List, ListItem } from "."; +import { FloatBox } from "../FloatBox"; + +const meta: Meta = { + title: "Components/View/ListItem", + component: ListItem, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = { + render: function RenderBasic() { + return ( + + Item1 + Item2 + Item3 + + ); + }, +}; + +export const Selected: Story = { + render: function RenderBasic() { + return ( + + Item1 + Item2 + Item3 + + ); + }, +}; + +export const Small: Story = { + render: function RenderBasic() { + return ( + + Item1 + Item2 + Item3 + + ); + }, +}; + +function CommandItem(props: { + children?: React.ReactNode; + shortcut?: string; + selected?: boolean; +}) { + return ( + + {props.children} + {props.shortcut && ( + + {props.shortcut} + + )} + + ); +} + +export const Commands: Story = { + render: function RenderBasic() { + return ( + + + Undo + Redo + Cut + + Copy + + Paste + + + ); + }, +}; diff --git a/src/components/ListItem/index.tsx b/src/components/ListItem/index.tsx new file mode 100644 index 0000000..0fe4074 --- /dev/null +++ b/src/components/ListItem/index.tsx @@ -0,0 +1,58 @@ +import React, { ForwardedRef, forwardRef } from "react"; +import { CustomJSXElement } from "../../types/CustomJSXElement"; +import { classNames } from "../../utils/classNames"; + +import "./index.css"; + +export type ListItemProps = { + as?: T; + children: React.ReactNode; + className?: string; + rounded?: boolean; + selected?: boolean; + size?: "S" | "M"; +} & React.ComponentProps; + +export const ListItem = forwardRef(function ListItem< + T extends CustomJSXElement, +>( + { + as: Component = "li", + children, + className, + rounded, + size = "M", + ...props + }: ListItemProps, + ref: ForwardedRef, +) { + return ( + + {children} + + ); +}) as (p: ListItemProps) => JSX.Element; + +export const List = forwardRef< + HTMLUListElement, + React.ComponentProps<"ul"> & { + as?: React.ElementType; + } +>(({ className, children, as: Component = "ul", ...props }, ref) => { + return ( + + {children} + + ); +}); diff --git a/src/components/MenuBarButton/MenuBar.tsx b/src/components/MenuBarButton/MenuBar.tsx new file mode 100644 index 0000000..d305e29 --- /dev/null +++ b/src/components/MenuBarButton/MenuBar.tsx @@ -0,0 +1,15 @@ +import * as RadixMenubar from "@radix-ui/react-menubar"; +import React from "react"; + +export type MenuBarProps = { + children: React.ReactNode; + className?: string; +}; + +export function MenuBar(props: MenuBarProps) { + return ( + + {props.children} + + ); +} diff --git a/src/components/MenuBarButton/MenuBarItem.tsx b/src/components/MenuBarButton/MenuBarItem.tsx new file mode 100644 index 0000000..5ec8866 --- /dev/null +++ b/src/components/MenuBarButton/MenuBarItem.tsx @@ -0,0 +1,24 @@ +import * as RadixMenubar from "@radix-ui/react-menubar"; +import React from "react"; +import { ListItem } from "../ListItem"; + +export type MenuBarItemProps = { + children: React.ReactNode; + className?: string; + disabled?: boolean; +} & React.ComponentPropsWithoutRef; + +export function MenuBarItem({ + className, + disabled, + children, + ...props +}: MenuBarItemProps) { + return ( + + + {children} + + + ); +} diff --git a/src/components/MenuBarButton/MenuBarSeparator.tsx b/src/components/MenuBarButton/MenuBarSeparator.tsx new file mode 100644 index 0000000..2d7d4d0 --- /dev/null +++ b/src/components/MenuBarButton/MenuBarSeparator.tsx @@ -0,0 +1,5 @@ +import * as RadixMenubar from "@radix-ui/react-menubar"; + +export function MenuBarSeparator() { + return ; +} diff --git a/src/components/MenuBarButton/MenuBarSubButton.tsx b/src/components/MenuBarButton/MenuBarSubButton.tsx new file mode 100644 index 0000000..b1dd6e4 --- /dev/null +++ b/src/components/MenuBarButton/MenuBarSubButton.tsx @@ -0,0 +1,43 @@ +import * as RadixMenubar from "@radix-ui/react-menubar"; +import React from "react"; +import { FloatBox } from "../FloatBox"; +import { ListItem } from "../ListItem"; + +export type MenuBarSubButtonProps = { + children: React.ReactNode; + className?: string; + content: React.ReactNode; + shortcut?: string | React.ReactNode; +}; + +export function MenuBarSubButton(props: MenuBarSubButtonProps) { + return ( + + + + {props.children} + + + + + + + + + {props.content} + + + + ); +} diff --git a/src/components/MenuBarButton/__snapshots__/index.stories.tsx.snap b/src/components/MenuBarButton/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..6efab5e --- /dev/null +++ b/src/components/MenuBarButton/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,63 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Float/MenuBarButton Basic smoke-test 1`] = ` + +`; diff --git a/src/components/MenuBarButton/index.css b/src/components/MenuBarButton/index.css new file mode 100644 index 0000000..bc5a401 --- /dev/null +++ b/src/components/MenuBarButton/index.css @@ -0,0 +1,68 @@ +.cmpui_menu-bar-button__root { + background-color: var(--cmpui-bg-color); + color: var(--cmpui-text-color); + + align-items: center; + border-radius: 5px; + border: 1px solid transparent; + box-sizing: border-box; + cursor: pointer; + display: flex; + flex-direction: column; + font-size: 12px; + height: 24px; + justify-content: center; + padding: 0 8px; + transition: border 0.1s ease-in-out; + width: fit-content; +} + +.cmpui_menu-bar-button__root:hover { + border: 1px solid var(--cmpui-border-hover-color); +} + +.cmpui_menu-bar-button__root:active { + background-color: var(--cmpui-bg-focus-color); + border: 1px solid transparent; + + color: white; +} + +.cmpui_menu-bar-button__root[data-highlighted], +.cmpui_menu-bar-button__root[data-highlighted]:active, +.cmpui_menu-bar-button__root[data-state="open"], +.cmpui_menu-bar-button__root[data-state="open"]:active { + background-color: var(--cmpui-bg-focus-color); + border: 1px solid transparent; + + color: white; + outline: none; +} + +.cmpui_menu-bar-button__root:focus-visible { + background-color: var(--cmpui-bg-focus-color); + color: white; + + outline: none; +} + +.cmpui_menu-bar-button__root[data-selected] { + background-color: var(--cmpui-bg-focus-color); +} + +.cmpui_menu-bar-item__shortcut { + color: var(--cmpui-text2-color); + font-family: var(--cmpui-font-mono); + + font-size: 10px; + margin-left: 8px; +} + +.cmpui_menu-bar__root { + display: flex; +} + +.cmpui_menu-bar-sub-button__list-item { + display: flex; + justify-content: space-between; +} diff --git a/src/components/MenuBarButton/index.stories.tsx b/src/components/MenuBarButton/index.stories.tsx new file mode 100644 index 0000000..e00723f --- /dev/null +++ b/src/components/MenuBarButton/index.stories.tsx @@ -0,0 +1,158 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { MenuBarButton } from "."; +import { ShortcutListItem } from "../../__stories__/ShortcutListItem"; +import { MenuBar } from "./MenuBar"; +import { MenuBarItem } from "./MenuBarItem"; +import { MenuBarSeparator } from "./MenuBarSeparator"; +import { MenuBarSubButton } from "./MenuBarSubButton"; + +const meta: Meta = { + title: "Components/Float/MenuBarButton", + component: MenuBarButton, +}; + +export default meta; +type Story = StoryObj; + +function ShortcutMenuBarItem( + props: Omit, "as">, +) { + return ; +} + +export const Basic: Story = { + render: function RenderBasic() { + const fileCommands = [ + { + name: "New File", + shortcut: "⌘ N", + }, + { + name: "Open File", + shortcut: "⌘ O", + disabled: true, + }, + { + name: "Save File", + shortcut: "⌘ S", + }, + { + name: "Save File As", + shortcut: "⇧ ⌘ S", + }, + ]; + + const editCommands = [ + { + name: "Undo", + shortcut: "⌘ Z", + }, + { + name: "Redo", + shortcut: "⇧ ⌘ Z", + }, + { + name: "Cut", + shortcut: "⌘ X", + }, + { + name: "Copy", + shortcut: "⌘ C", + }, + { + name: "Paste", + shortcut: "⌘ V", + }, + ]; + + const viewCommands = [ + { + name: "Zoom In", + shortcut: "⇧ ⌘ =", + }, + { + name: "Zoom Out", + shortcut: "⌘ -", + }, + { + name: "Zoom to Fit", + shortcut: "⌘ 0", + }, + { + name: "Zoom to Selection", + shortcut: "⌘ 1", + }, + ]; + + const helpCommands = [ + { + name: "About", + shortcut: "", + }, + ]; + + return ( + + + {fileCommands.map((command) => ( + + {command.name} + + ))} + + + Copy Link + Copy Text + Email + SNS + + } + > + Share + + + } + > + File + + ( + + {command.name} + + ))} + > + Edit + + + ( + + {command.name} + + ))} + > + View + + + + {helpCommands[0].name} + + } + > + Help + + + ); + }, +}; diff --git a/src/components/MenuBarButton/index.tsx b/src/components/MenuBarButton/index.tsx new file mode 100644 index 0000000..e389dce --- /dev/null +++ b/src/components/MenuBarButton/index.tsx @@ -0,0 +1,40 @@ +import * as RadixMenubar from "@radix-ui/react-menubar"; +import React, { forwardRef } from "react"; +import { classNames } from "../../utils/classNames"; +import { FloatBox } from "../FloatBox"; + +import "./index.css"; + +export type MenuBarButtonProps = { + content?: React.ReactNode; + selected?: boolean; +} & Omit, "content">; + +export const MenuBarButton = forwardRef( + ({ selected, content, ...props }, ref) => { + return ( + + + + + + + {content} + + + + ); + }, +); diff --git a/src/components/Modal/__snapshots__/index.stories.tsx.snap b/src/components/Modal/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..34852a2 --- /dev/null +++ b/src/components/Modal/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Float/Modal Primary smoke-test 1`] = ` + +`; diff --git a/src/components/Modal/index.css b/src/components/Modal/index.css new file mode 100644 index 0000000..498c29d --- /dev/null +++ b/src/components/Modal/index.css @@ -0,0 +1,73 @@ +.cmpui_modal__root { + background-color: var(--cmpui-bg-color); + + animation: contentShow 100ms; + left: 50%; + min-width: 256px; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); +} + +.cmpui_modal__header { + align-items: center; + display: flex; + gap: 16px; + justify-content: center; + min-height: 24px; + text-align: center; +} + +.cmpui_modal__divider { + background-color: var(--cmpui-border-color); + + all: unset; + display: block; + height: 1px; + margin: 4px 0; + width: 100%; +} + +.cmpui_modal__title { + color: var(--cmpui-text-color); + + font-size: 14px; + font-weight: bold; +} + +.cmpui_modal__overlay { + background-color: var(--cmpui-overlay-color); + + animation: overlayShow 100ms; + inset: 0; + position: absolute; +} + +.cmpui_modal__close-button { + background-color: transparent; + border: none; + cursor: pointer; + position: absolute; + right: 4px; + top: 4px; +} + +@keyframes overlayShow { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes contentShow { + from { + opacity: 0; + transform: translate(-50%, -48%) scale(0.96); + } + to { + opacity: 1; + transform: translate(-50%, -50%) scale(1); + } +} diff --git a/src/components/Modal/index.stories.tsx b/src/components/Modal/index.stories.tsx new file mode 100644 index 0000000..b6463b3 --- /dev/null +++ b/src/components/Modal/index.stories.tsx @@ -0,0 +1,103 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { useCallback, useState } from "react"; +import { Modal } from "."; +import { Button } from "../Button"; +import { SliderNumberField } from "../SliderNumberField"; +import { TextInput } from "../TextInput"; + +const meta: Meta = { + title: "Components/Float/Modal", + component: Modal, +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + render: function RenderBasic() { + const [open, setOpen] = useState(false); + return ( + <> + + setOpen(false)}> + { + setOpen(false); + }} + /> + + + ); + }, +}; + +function Body({ + onClose, +}: { + onClose?: () => void; +} = {}) { + const [name, setName] = useState("Awesome project"); + const [width, setWidth] = useState(256); + const [height, setHeight] = useState(512); + + const handleChangeName = useCallback( + (e: React.ChangeEvent) => { + setName(e.target.value); + }, + [], + ); + + const handleChangeWidth = useCallback((value: number | number[]) => { + if (typeof value !== "number") throw new Error("value is not number"); + setWidth(value); + }, []); + + const handleChangeHeight = useCallback((value: number | number[]) => { + if (typeof value !== "number") throw new Error("value is not number"); + setHeight(value); + }, []); + + return ( +
+ +
+ +
+ × +
+ +
+ + +
+ ); +} diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx new file mode 100644 index 0000000..fce1935 --- /dev/null +++ b/src/components/Modal/index.tsx @@ -0,0 +1,69 @@ +import * as Dialog from "@radix-ui/react-dialog"; +import React from "react"; +import { classNames } from "../../utils/classNames"; +import { FloatBox } from "../FloatBox"; +import { IconButton } from "../IconButton"; + +import "./index.css"; + +export type ModalProps = { + children: React.ReactNode; + container?: HTMLElement | null; + hideCloseButton?: boolean; + onClose?: () => void; + open?: boolean; + title: string; + trigger?: React.ReactNode; + className?: string; +}; + +export function Modal(props: ModalProps) { + return ( + { + if (!open && props.onClose) { + props.onClose(); + } + }} + > + {props.trigger && ( + {props.trigger} + )} + + + + +
+ +
{props.title}
+
+ {!props.hideCloseButton && ( + + + + + + + + )} +
+
+
{props.children}
+
+
+
+
+ ); +} diff --git a/src/components/Path/__snapshots__/index.stories.tsx.snap b/src/components/Path/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..9e402ef --- /dev/null +++ b/src/components/Path/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Controls/Path Basic smoke-test 1`] = ` + + + + + + +`; diff --git a/src/components/Path/index.stories.tsx b/src/components/Path/index.stories.tsx new file mode 100644 index 0000000..d136c50 --- /dev/null +++ b/src/components/Path/index.stories.tsx @@ -0,0 +1,23 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Path } from "."; + +const meta: Meta = { + title: "Components/Controls/Path", + component: Path, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = { + render: function Render() { + return ( + + ); + }, +}; diff --git a/src/components/Path/index.tsx b/src/components/Path/index.tsx new file mode 100644 index 0000000..cf9d5a8 --- /dev/null +++ b/src/components/Path/index.tsx @@ -0,0 +1,84 @@ +import React, { useEffect } from "react"; +import { Command } from "../CubicControls/CubicCommand"; + +export type PathProps = { + commands: Command[]; + onClickCurve?: (event: React.MouseEvent) => void; + onChange?: (commands: Command[]) => void; +} & Omit, "onChange">; + +export function Path({ + commands, + onClickCurve, + onChange, + ...props +}: PathProps) { + const ref = React.useRef(null); + const [x, setX] = React.useState(0); + const [y, setY] = React.useState(0); + const [width, setWidth] = React.useState(0); + const [height, setHeight] = React.useState(0); + + const offset = 4; + + useEffect(() => { + if (!ref.current) return; + const bbox = ref.current.getBBox(); + setX(bbox.x - offset); + setY(bbox.y - offset); + setWidth(bbox.width + offset * 2); + setHeight(bbox.height + offset * 2); + }, [ref.current, setX, setY, setWidth, setHeight]); + + function commandToD(command: Command[][0]) { + switch (command.type) { + case "move": + return `M ${command.x} ${command.y}`; + case "line": + return `L ${command.x} ${command.y}`; + case "quadratic": + return `Q ${command.x1} ${command.y1} ${command.x} ${command.y}`; + case "cubic": + return `C ${command.x1} ${command.y1} ${command.x2} ${command.y2} ${command.x} ${command.y}`; + } + } + + return ( + + {commands.map((command, i) => { + let d = commandToD(command); + const prev = commands[i - 1]; + + if (prev) { + const prevD = commandToD(prev); + d = `${prevD} ${d}`; + } + + return ( + + ); + })} + + ); +} diff --git a/src/components/Popover/__snapshots__/index.stories.tsx.snap b/src/components/Popover/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..6cb60a6 --- /dev/null +++ b/src/components/Popover/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Float/Popover Primary smoke-test 1`] = ` + +`; diff --git a/src/components/Popover/index.css b/src/components/Popover/index.css new file mode 100644 index 0000000..52c5ef9 --- /dev/null +++ b/src/components/Popover/index.css @@ -0,0 +1,63 @@ +.cmpui_popover__root { + animation-duration: 100ms; +} + +.cmpui_popover__root[data-state="open"][data-side="top"] { + animation-name: slideDownAndFade; +} + +.cmpui_popover__root[data-state="open"][data-side="right"] { + animation-name: slideLeftAndFade; +} + +.cmpui_popover__root[data-state="open"][data-side="bottom"] { + animation-name: slideUpAndFade; +} + +.cmpui_popover__root[data-state="open"][data-side="left"] { + animation-name: slideRightAndFade; +} + +@keyframes slideUpAndFade { + from { + opacity: 0; + transform: translateY(2px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideRightAndFade { + from { + opacity: 0; + transform: translateX(-2px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slideDownAndFade { + from { + opacity: 0; + transform: translateY(-2px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideLeftAndFade { + from { + opacity: 0; + transform: translateX(2px); + } + to { + opacity: 1; + transform: translateX(0); + } +} diff --git a/src/components/Popover/index.stories.tsx b/src/components/Popover/index.stories.tsx new file mode 100644 index 0000000..434c48b --- /dev/null +++ b/src/components/Popover/index.stories.tsx @@ -0,0 +1,107 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { useCallback, useState } from "react"; +import { Popover } from "."; +import { Button } from "../Button"; +import { SliderNumberField } from "../SliderNumberField"; +import { TextInput } from "../TextInput"; + +const meta: Meta = { + title: "Components/Float/Popover", + component: Popover, +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + render: function RenderBasic() { + const [open, setOpen] = useState(false); + return ( + <> + setOpen(false)} + content={ + { + setOpen(false); + }} + /> + } + > + + + + ); + }, +}; + +function Body({ + onClose, +}: { + onClose?: () => void; +} = {}) { + const [name, setName] = useState("Awesome project"); + const [width, setWidth] = useState(256); + const [height, setHeight] = useState(512); + + const handleChangeName = useCallback( + (e: React.ChangeEvent) => { + setName(e.target.value); + }, + [], + ); + + const handleChangeWidth = useCallback((value: number[]) => { + setWidth(value[0]); + }, []); + + const handleChangeHeight = useCallback((value: number[]) => { + setHeight(value[0]); + }, []); + + return ( +
+ +
+ +
+ × +
+ +
+ + +
+ ); +} diff --git a/src/components/Popover/index.tsx b/src/components/Popover/index.tsx new file mode 100644 index 0000000..0109a69 --- /dev/null +++ b/src/components/Popover/index.tsx @@ -0,0 +1,29 @@ +import * as RadixPopover from "@radix-ui/react-popover"; +import { FloatBox } from "../FloatBox"; + +import "./index.css"; + +export type PopoverProps = { + children: React.ReactNode; + content: React.ReactNode; + isOpen?: boolean; + onOpenChange?: (isOpen: boolean) => void; +}; + +export function Popover(props: PopoverProps) { + return ( + + {props.children} + + + {props.content} + + + + ); +} diff --git a/src/components/RectGizmo/AngleNob.tsx b/src/components/RectGizmo/AngleNob.tsx new file mode 100644 index 0000000..016e146 --- /dev/null +++ b/src/components/RectGizmo/AngleNob.tsx @@ -0,0 +1,94 @@ +import { useMemo } from "react"; +import { createDragHandler } from "../../utils/interactions"; +import { useTouchStartPrevent } from "../../utils/interactions"; +import { Vector2 } from "../../utils/math"; +import { rotateVector } from "../../utils/math"; +import { Circle } from "../Circle"; +import { Line } from "../Line"; +import { createRotateHorizontalResize } from "./lib/createRotateHorizontalResize"; + +type AngleNobProps = { + angle: number; + length: number; + onChange: (angle: number) => void; + startLength: number; + x: number; + y: number; + nobRadius?: number; + onEnd?: () => void; + onStart?: () => void; +}; + +export function AngleNob({ nobRadius = 10, ...props }: AngleNobProps) { + const ref = useTouchStartPrevent(); + + const handleAngle = createDragHandler({ + onDown: (e) => { + e.stopPropagation(); + props.onStart?.(); + return { + startX: e.clientX, + startY: e.clientY, + startAngle: props.angle, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const a = ctx.startAngle + Math.PI / 2; + const nobCenter = new Vector2( + ctx.startX + Math.cos(a) * props.length, + ctx.startY + Math.sin(a) * props.length, + ); + const deltaX = e.clientX - nobCenter.x; + const deltaY = e.clientY - nobCenter.y; + const newAngle = Math.atan2(deltaY, deltaX) + Math.PI / 2; + props.onChange(newAngle); + }, + onUp: props.onEnd, + }); + + const angleNobPos = rotateVector( + new Vector2(props.x, props.y - props.length), + { x: props.x, y: props.y }, + props.angle, + ); + + const angleStartNobPos = rotateVector( + new Vector2(props.x, props.y - props.startLength), + { x: props.x, y: props.y }, + props.angle, + ); + const steppedAngle = useMemo(() => { + const step = Math.PI / 12; + return Math.round(props.angle / step) * step; + }, [props.angle]); + + const style = useMemo( + () => ({ + cursor: createRotateHorizontalResize(steppedAngle), + }), + [steppedAngle], + ); + + return ( + <> + + + + ); +} diff --git a/src/components/RectGizmo/MovableRect.tsx b/src/components/RectGizmo/MovableRect.tsx new file mode 100644 index 0000000..8682546 --- /dev/null +++ b/src/components/RectGizmo/MovableRect.tsx @@ -0,0 +1,76 @@ +import { useMemo } from "react"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { useTouchStartPrevent } from "../../utils/interactions/useTouchStartPrevent"; + +type MovableRectProps = { + angle: number; + height: number; + onMove: (args: { x?: number; y?: number }) => void; + width: number; + x: number; + y: number; + onEnd?: () => void; + onStart?: () => void; +}; + +export function MovableRect({ + angle, + height, + onMove, + width, + x, + y, + onEnd, + onStart, +}: MovableRectProps) { + const rectWidth = width < 0 ? -width : width; + const rectHeight = height < 0 ? -height : height; + const rectX = width < 0 ? x - rectWidth / 2 : x - rectWidth / 2; + const rectY = height < 0 ? y - rectHeight / 2 : y - rectHeight / 2; + + const handlePointerDownRect = useMemo( + () => + createDragHandler({ + onDown(e) { + e.stopPropagation(); + onStart?.(); + }, + onMove: (e, __, { dx, dy }) => { + onMove({ + x: x + dx, + y: y + dy, + }); + e.preventDefault(); + }, + onUp: onEnd, + }), + [onMove, x, y, onEnd, onStart], + ); + + const ref = useTouchStartPrevent(); + + return ( + + + + ); +} diff --git a/src/components/RectGizmo/__snapshots__/index.stories.tsx.snap b/src/components/RectGizmo/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..2349e77 --- /dev/null +++ b/src/components/RectGizmo/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,371 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Controls/RectGizmo Basic smoke-test 1`] = ` +
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + + + +
+`; + +exports[`Components/Controls/RectGizmo Debug smoke-test 1`] = ` +
+
+
+ x: 256.00 +
+
+ y: 256.00 +
+
+ w: 100.00 +
+
+ h: 50.00 +
+
+ a: 0.00 +
+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + + + +
+`; + +exports[`Components/Controls/RectGizmo NobSize smoke-test 1`] = ` +
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + + + +
+`; diff --git a/src/components/RectGizmo/index.css b/src/components/RectGizmo/index.css new file mode 100644 index 0000000..9633c4f --- /dev/null +++ b/src/components/RectGizmo/index.css @@ -0,0 +1,7 @@ +.cmpui_rect-gizmo__movable-rect { + cursor: grab; +} + +.cmpui_rect-gizmo__movable-rect:active { + cursor: grabbing; +} diff --git a/src/components/RectGizmo/index.stories.tsx b/src/components/RectGizmo/index.stories.tsx new file mode 100644 index 0000000..4641359 --- /dev/null +++ b/src/components/RectGizmo/index.stories.tsx @@ -0,0 +1,153 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { RectGizmo } from "."; + +const meta: Meta = { + title: "Components/Controls/RectGizmo", + component: RectGizmo, + parameters: { + layout: "fullscreen", + }, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = { + render: function Render() { + const [points, setPoints] = useState({ + x: 256, + y: 256, + width: 100, + height: 50, + angle: 0, + }); + return ( +
+ { + setPoints({ + ...points, + ...args, + }); + }} + isResizable + isRotatable + /> +
+ ); + }, +}; + +export const NobSize: Story = { + render: function Render() { + const [points, setPoints] = useState({ + x: 256, + y: 256, + width: 100, + height: 50, + angle: 0, + }); + return ( +
+ { + setPoints({ + ...points, + ...args, + }); + }} + isResizable + isRotatable + /> +
+ ); + }, +}; + +export const Debug: Story = { + render: function Render() { + const [points, setPoints] = useState({ + x: 256, + y: 256, + width: 100, + height: 50, + angle: 0, + }); + return ( +
+
0 ? 1 : -1 + }, ${points.height > 0 ? 1 : -1})`, + transformOrigin: "center", + color: "white", + whiteSpace: "nowrap", + }} + > +
x: {points.x.toFixed(2)}
+
y: {points.y.toFixed(2)}
+
w: {points.width.toFixed(2)}
+
h: {points.height.toFixed(2)}
+
a: {points.angle.toFixed(2)}
+
+ { + setPoints({ + ...points, + ...args, + }); + }} + isResizable + isRotatable + /> +
+ ); + }, +}; diff --git a/src/components/RectGizmo/index.tsx b/src/components/RectGizmo/index.tsx new file mode 100644 index 0000000..1c8676e --- /dev/null +++ b/src/components/RectGizmo/index.tsx @@ -0,0 +1,260 @@ +import { useCallback, useMemo } from "react"; +import { CornerPosition } from "../../types"; +import { useTouchStartPrevent } from "../../utils/interactions/useTouchStartPrevent"; +import { Vector2 } from "../../utils/math"; +import { rotateVector } from "../../utils/math/rotateVector"; +import { Circle, CircleProps } from "../Circle"; +import { Line } from "../Line"; +import { AngleNob } from "./AngleNob"; +import { MovableRect } from "./MovableRect"; +import { createResizeHandler } from "./lib/createResizeHandler"; +import { createRotateHorizontalResize } from "./lib/createRotateHorizontalResize"; +import { positionSignMap } from "./lib/positionSignMap"; + +import "./index.css"; + +const positions: CornerPosition[] = [ + "left-top", + "right-top", + "right-bottom", + "left-bottom", +]; + +export type RectGizmoProps = { + width: number; + height: number; + x: number; + y: number; + angle: number; + nobRadius?: number; + isRotatable?: boolean; + isResizable?: boolean; + onMove: (args: { + x?: number; + y?: number; + width?: number; + height?: number; + angle?: number; + }) => void; + onEnd?: () => void; + onStart?: () => void; +}; + +export function RectGizmo({ + width, + height, + x, + y, + angle, + onMove, + isRotatable = false, + isResizable = false, + nobRadius = 6, + onEnd, + onStart, +}: RectGizmoProps) { + const center = useMemo(() => new Vector2(x, y), [x, y]); + + const [rlt, rrt, rrb, rlb] = useMemo( + () => + positions.map((pos) => { + const [dx, dy] = positionSignMap[pos]; + const point = new Vector2(x + (dx * width) / 2, y + (dy * height) / 2); + + return rotateVector(point, center, angle); + }), + [angle, center, height, width, x, y], + ); + + const onMoveRect = useCallback( + (args: { + x: number; + y: number; + width: number; + height: number; + }) => { + onMove({ + x: args.x, + y: args.y, + width: args.width, + height: args.height, + angle, + }); + }, + [onMove, angle], + ); + + const ltpd = useMemo( + () => + createResizeHandler( + rlt, + rrb, + width, + height, + angle, + onMoveRect, + "left-top", + onEnd, + onStart, + ), + [rlt, rrb, width, height, angle, onMoveRect, onEnd, onStart], + ); + + const rtpd = useMemo( + () => + createResizeHandler( + rrt, + rlb, + width, + height, + angle, + onMoveRect, + "right-top", + onEnd, + onStart, + ), + [rrt, rlb, width, height, angle, onMoveRect, onEnd, onStart], + ); + const lbpd = useMemo( + () => + createResizeHandler( + rlb, + rrt, + width, + height, + angle, + onMoveRect, + "left-bottom", + onEnd, + onStart, + ), + [rlb, rrt, width, height, angle, onMoveRect, onEnd, onStart], + ); + const rbpd = useMemo( + () => + createResizeHandler( + rrb, + rlt, + width, + height, + angle, + onMoveRect, + "right-bottom", + onEnd, + onStart, + ), + [rlt, rrb, width, height, angle, onMoveRect, onEnd, onStart], + ); + + const linesPoints = useMemo( + () => [ + [rlt.x, rlt.y], + [rrt.x, rrt.y], + [rrb.x, rrb.y], + [rlb.x, rlb.y], + ], + [rlt, rrt, rrb, rlb], + ); + + const handlers = useMemo( + () => [ltpd, rtpd, rbpd, lbpd], + [ltpd, rtpd, rbpd, lbpd], + ); + + const steppedAngle = useMemo(() => { + const step = Math.PI / 12; + return Math.round(angle / step) * step; + }, [angle]); + + const memoCursorStyle = useMemo(() => { + return [0, 0, 0, 0].map((_, i) => { + return { + cursor: createRotateHorizontalResize( + steppedAngle + + Math.PI / 4 + + (i * Math.PI) / 2 + + (width < 0 ? Math.PI / 2 : 0) + + (height < 0 ? Math.PI / 2 : 0), + ), + }; + }); + }, [steppedAngle, width, height]); + + const handleChangeAngle = useCallback( + (angle: number) => { + onMove({ + x, + y, + width, + height, + angle, + }); + }, + [onMove, x, y, width, height], + ); + + return ( + <> + + {linesPoints.map((points, i) => { + const [x1, y1] = points; + const [x2, y2] = linesPoints[i + 1] ?? linesPoints[0]; + return ( + + ); + })} + + {isResizable && + handlers.map((handler, i) => { + const [x, y] = linesPoints[i]; + return ( + + ); + })} + + {isRotatable && ( + + )} + + ); +} + +function PreventTouchStartCircle(props: CircleProps) { + const ref = useTouchStartPrevent(); + return ; +} diff --git a/src/components/RectGizmo/lib/createCursorStyleBase64SVGUrl.ts b/src/components/RectGizmo/lib/createCursorStyleBase64SVGUrl.ts new file mode 100644 index 0000000..5a877a9 --- /dev/null +++ b/src/components/RectGizmo/lib/createCursorStyleBase64SVGUrl.ts @@ -0,0 +1,8 @@ +export function createCursorStyleBase64SVGUrl( + base64: string, + x: number, + y: number, + def: string, +) { + return `url(data:image/svg+xml;base64,${base64}) ${x} ${y}, ${def}`; +} diff --git a/src/components/RectGizmo/lib/createHorizontalResizeSVGString.ts b/src/components/RectGizmo/lib/createHorizontalResizeSVGString.ts new file mode 100644 index 0000000..1b959e3 --- /dev/null +++ b/src/components/RectGizmo/lib/createHorizontalResizeSVGString.ts @@ -0,0 +1,6 @@ +/** + * https://fonts.google.com/icons?selected=Material%20Symbols%20Outlined%3Awidth%3AFILL%400%3Bwght%40400%3BGRAD%400%3Bopsz%4024 + */ +export function createHorizontalResizeSVGString(deg: number) { + return ``; +} diff --git a/src/components/RectGizmo/lib/createResizeHandler.ts b/src/components/RectGizmo/lib/createResizeHandler.ts new file mode 100644 index 0000000..96673c2 --- /dev/null +++ b/src/components/RectGizmo/lib/createResizeHandler.ts @@ -0,0 +1,163 @@ +import { CornerPosition } from "../../../types"; +import { createDragHandler } from "../../../utils/interactions/createDragHandler"; +import { Vector2 } from "../../../utils/math"; +import { rotateVector } from "../../../utils/math/rotateVector"; +import { scaleVector } from "../../../utils/math/scaleVector"; +import { positionSignMap } from "./positionSignMap"; +import { resizeWithAspectRatio } from "./proportionalResize"; + +const positionSignAdjustMap: Record< + CornerPosition, + [number, number, number, number] +> = { + "left-top": [-1, -1, 1, -1], + "right-top": [1, 1, 1, -1], + "left-bottom": [-1, -1, -1, 1], + "right-bottom": [1, 1, -1, 1], +}; + +export function createResizeHandler( + p1: Vector2, + p2: Vector2, + width: number, + height: number, + angle: number, + onMove: (args: { + x: number; + y: number; + width: number; + height: number; + }) => void, + pos: CornerPosition, + onEnd?: () => void, + onStart?: () => void, +) { + let _dx = 0; + let _dy = 0; + + const getNewWidth = () => { + const diffWidth = + positionSignAdjustMap[pos][0] * _dx * Math.cos(angle) + + positionSignAdjustMap[pos][1] * _dy * Math.sin(angle); + const newWidth = width + diffWidth * 2; + return newWidth; + }; + + const getNewHeight = () => { + const diffHeight = + positionSignAdjustMap[pos][2] * _dx * Math.sin(angle) + + positionSignAdjustMap[pos][3] * _dy * Math.cos(angle); + const newHeight = height + diffHeight * 2; + return newHeight; + }; + + const startCenter = new Vector2((p1.x + p2.x) / 2, (p1.y + p2.y) / 2); + + return createDragHandler({ + onDown: (e) => { + e.stopPropagation(); + const startRatio = Math.abs(height / width); + const onKeyDown = (_: KeyboardEvent) => { + const result = resizeWithAspectRatio( + getNewWidth(), + getNewHeight(), + startRatio, + ); + onMove({ + x: startCenter.x, + y: startCenter.y, + ...result, + }); + }; + + const onKeyUp = () => { + onMove({ + x: startCenter.x, + y: startCenter.y, + width: getNewWidth(), + height: getNewHeight(), + }); + }; + + window.addEventListener("keydown", onKeyDown); + window.addEventListener("keyup", onKeyUp); + onStart?.(); + return { + startP2: p2, + startRatio, + startP1: p1, + startWidth: width, + startHeight: height, + startCenter, + cleanUp() { + window.removeEventListener("keydown", onKeyDown); + window.removeEventListener("keyup", onKeyUp); + }, + }; + }, + onMove: (e, ctx, { dx, dy }) => { + if (!ctx) return; + _dx = dx; + _dy = dy; + + const anchor = ctx.startCenter; + const startD = new Vector2( + anchor.x - ctx.startP1.x, + anchor.y - ctx.startP1.y, + ); + const newD = new Vector2( + anchor.x - (ctx.startP1.x + _dx), + anchor.y - (ctx.startP1.y + _dy), + ); + const scale = new Vector2(newD.x / startD.x, newD.y / startD.y); + if ( + Number.isNaN(scale.x) || + scale.x === Infinity || + scale.x === -Infinity + ) { + _dx = 0; + } + if ( + Number.isNaN(scale.y) || + scale.y === Infinity || + scale.y === -Infinity + ) { + _dy = 0; + } + const newP1 = new Vector2(ctx.startP1.x + _dx, ctx.startP1.y + _dy); + const newP2 = scaleVector(ctx.startP2, scale, anchor); + const newCenter = scaleVector(ctx.startCenter, scale, anchor); + const rotatedNewP1 = rotateVector(newP1, newCenter, -angle); + const rotatedNewP2 = rotateVector(newP2, newCenter, -angle); + let newWidth = rotatedNewP2.x - rotatedNewP1.x; + let newHeight = rotatedNewP2.y - rotatedNewP1.y; + newWidth *= -positionSignMap[pos][0]; + newHeight *= -positionSignMap[pos][1]; + + if (e.shiftKey) { + const result = resizeWithAspectRatio( + getNewWidth(), + getNewHeight(), + ctx.startRatio, + ); + onMove({ + x: ctx.startCenter.x, + y: ctx.startCenter.y, + ...result, + }); + } else { + onMove({ + width: newWidth, + height: newHeight, + x: newCenter.x, + y: newCenter.y, + }); + } + }, + onUp: (_, ctx) => { + if (!ctx) return; + ctx.cleanUp(); + onEnd?.(); + }, + }); +} diff --git a/src/components/RectGizmo/lib/createRotateHorizontalResize.ts b/src/components/RectGizmo/lib/createRotateHorizontalResize.ts new file mode 100644 index 0000000..f3ab570 --- /dev/null +++ b/src/components/RectGizmo/lib/createRotateHorizontalResize.ts @@ -0,0 +1,12 @@ +import { radToDeg } from "../../../utils/math/radToDeg"; +import { createCursorStyleBase64SVGUrl } from "./createCursorStyleBase64SVGUrl"; +import { createHorizontalResizeSVGString } from "./createHorizontalResizeSVGString"; + +export function createRotateHorizontalResize(rad: number) { + return createCursorStyleBase64SVGUrl( + btoa(createHorizontalResizeSVGString(radToDeg(rad))), + 8, + 8, + "ew-resize", + ); +} diff --git a/src/components/RectGizmo/lib/positionSignMap.ts b/src/components/RectGizmo/lib/positionSignMap.ts new file mode 100644 index 0000000..244a86a --- /dev/null +++ b/src/components/RectGizmo/lib/positionSignMap.ts @@ -0,0 +1,8 @@ +import { CornerPosition } from "../../../types"; + +export const positionSignMap: Record = { + "left-top": [-1, -1], + "right-top": [1, -1], + "left-bottom": [-1, +1], + "right-bottom": [1, 1], +}; diff --git a/src/components/RectGizmo/lib/proportionalResize.ts b/src/components/RectGizmo/lib/proportionalResize.ts new file mode 100644 index 0000000..3166599 --- /dev/null +++ b/src/components/RectGizmo/lib/proportionalResize.ts @@ -0,0 +1,28 @@ +type Result = { + width: number; + height: number; +}; + +export function resizeWithAspectRatio( + newWidth: number, + newHeight: number, + startRatio: number, +): Result { + const newHeightAbs = Math.abs(newHeight); + const newWidthAbs = Math.abs(newWidth); + + const newRatio = Math.abs(newHeightAbs / newWidthAbs); + if (newRatio > startRatio) { + const proWidth = newHeightAbs / startRatio; + return { + width: proWidth * Math.sign(newWidth), + height: newHeightAbs * Math.sign(newHeight), + }; + } + const proHeight = newWidthAbs * startRatio; + + return { + width: newWidthAbs * Math.sign(newWidth), + height: proHeight * Math.sign(newHeight), + }; +} diff --git a/src/components/Ruler/TimeText.tsx b/src/components/Ruler/TimeText.tsx new file mode 100644 index 0000000..55f0347 --- /dev/null +++ b/src/components/Ruler/TimeText.tsx @@ -0,0 +1,28 @@ +export function TimeText(props: { + time: string; + left: number; + orientation?: "horizontal" | "vertical"; +}) { + return ( +
+
+
+ {props.time} +
+
+ ); +} diff --git a/src/components/Ruler/__snapshots__/index.stories.tsx.snap b/src/components/Ruler/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..55c96ab --- /dev/null +++ b/src/components/Ruler/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,1474 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/View/Ruler Basic smoke-test 1`] = ` +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 +
+
+
+
+
+
+ 50 +
+
+
+
+
+
+ 100 +
+
+
+
+
+
+ 150 +
+
+
+
+
+
+ 200 +
+
+
+
+
+
+ 250 +
+
+
+
+
+
+ 300 +
+
+
+
+
+
+ 350 +
+
+
+
+
+
+ 400 +
+
+
+
+
+
+ 450 +
+
+
+
+
+
+ 500 +
+
+
+
+
+
+ 550 +
+
+
+
+
+
+ 600 +
+
+
+
+
+
+ 650 +
+
+
+
+
+
+ 700 +
+
+
+
+
+
+ 750 +
+
+
+
+
+
+ 800 +
+
+
+
+
+
+ 850 +
+
+
+
+
+
+ 900 +
+
+
+
+
+
+ 950 +
+
+
+
+
+
+ 1000 +
+
+
+
+
+
+ 1050 +
+
+
+
+
+
+ 1100 +
+
+
+
+
+
+ 1150 +
+
+
+
+
+
+ 1200 +
+
+
+
+
+
+ 1250 +
+
+
+
+
+
+ 1300 +
+
+
+`; + +exports[`Components/View/Ruler Vertical smoke-test 1`] = ` +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 +
+
+
+
+
+
+ 50 +
+
+
+
+
+
+ 100 +
+
+
+
+
+
+ 150 +
+
+
+
+
+
+ 200 +
+
+
+
+
+
+ 250 +
+
+
+
+
+
+ 300 +
+
+
+
+
+
+ 350 +
+
+
+
+
+
+ 400 +
+
+
+
+
+
+ 450 +
+
+
+
+
+
+ 500 +
+
+
+
+
+
+ 550 +
+
+
+
+`; diff --git a/src/components/Ruler/defaultRenderText.ts b/src/components/Ruler/defaultRenderText.ts new file mode 100644 index 0000000..da1c77d --- /dev/null +++ b/src/components/Ruler/defaultRenderText.ts @@ -0,0 +1,12 @@ +export function defaultRenderText(time: number) { + let viewTime = time.toFixed(2); + if (viewTime.endsWith(".00")) { + viewTime = viewTime.slice(0, -3); + } else if (viewTime.endsWith("0")) { + viewTime = viewTime.slice(0, -1); + } + if (viewTime === "-0") { + viewTime = "0"; + } + return viewTime; +} diff --git a/src/components/Ruler/defaultSteps.ts b/src/components/Ruler/defaultSteps.ts new file mode 100644 index 0000000..8c27707 --- /dev/null +++ b/src/components/Ruler/defaultSteps.ts @@ -0,0 +1 @@ +export const defaultSteps = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000]; diff --git a/src/components/Ruler/getStepPixel.ts b/src/components/Ruler/getStepPixel.ts new file mode 100644 index 0000000..3ac0bcc --- /dev/null +++ b/src/components/Ruler/getStepPixel.ts @@ -0,0 +1,16 @@ +export function getStepPixel( + pxPerUnit: number, + minInterval: number, + step: number[], + width: number, + offsetSec = 0, +) { + const stepI = step.findIndex((s) => s * pxPerUnit > minInterval); + const stepPx = step[stepI] * pxPerUnit; + const viewNumber = Math.ceil(width / stepPx); + const offset = (offsetSec * pxPerUnit) % stepPx; + if (Number.isNaN(viewNumber)) return []; + return [...Array(viewNumber + 1).keys()].map((i) => { + return i * stepPx - offset; + }); +} diff --git a/src/components/Ruler/index.css b/src/components/Ruler/index.css new file mode 100644 index 0000000..198eabe --- /dev/null +++ b/src/components/Ruler/index.css @@ -0,0 +1,82 @@ +.cmpui_ruler__root { + box-sizing: border-box; + display: flex; + font-size: 12px; + height: 24px; + overflow: hidden; + position: relative; + touch-action: none; + user-select: none; + width: 100%; +} + +.cmpui_ruler__root[data-orientation="vertical"] { + flex-direction: column; + height: 100%; + width: 24px; +} + +.cmpui_ruler__point { + border-left: 1px solid var(--cmpui-text-color); + bottom: 0px; + height: 4px; + pointer-events: none; + position: absolute; + touch-action: none; +} + +.cmpui_ruler__point[data-orientation="vertical"] { + border-top: 1px solid var(--cmpui-text-color); + border-left: none; + pointer-events: none; + position: absolute; + right: 0px; + touch-action: none; + width: 4px; +} + +.cmpui_ruler-text__root { + color: var(--cmpui-text-color); + height: 100%; + pointer-events: none; + position: absolute; + touch-action: none; +} + +.cmpui_ruler-text__root[data-orientation="vertical"] { + width: 100%; + height: 1px; +} + +.cmpui_ruler-text__line { + background-color: var(--cmpui-text2-color); + bottom: 0; + height: 8px; + pointer-events: none; + position: absolute; + touch-action: none; + width: 1px; +} + +.cmpui_ruler-text__line[data-orientation="vertical"] { + height: 1px; + width: 8px; + right: 0; +} + +.cmpui_ruler-text__text { + font-size: 10px; + line-height: 10px; + transform: translateX(-50%); +} + +.cmpui_ruler-text__text[data-orientation="vertical"] { + align-items: flex-end; + direction: ltr; + display: flex; + font-size: 10px; + line-height: 10px; + transform: rotateZ(180deg) translateY(50%); + width: 100%; + writing-mode: vertical-lr; +} diff --git a/src/components/Ruler/index.stories.tsx b/src/components/Ruler/index.stories.tsx new file mode 100644 index 0000000..0d01165 --- /dev/null +++ b/src/components/Ruler/index.stories.tsx @@ -0,0 +1,91 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useEffect, useState } from "react"; +import { Ruler } from "."; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; + +const meta: Meta = { + title: "Components/View/Ruler", + component: Ruler, + parameters: { + layout: "fullscreen", + }, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = { + render: function RenderBasic() { + const pxPerSec = 1; + const [offset, setOffset] = useState(-24); + const handlePointerDown = createDragHandler({ + onDown: (e) => { + return { + startX: e.clientX, + startY: e.clientY, + startOffset: offset, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.startX; + const offset = ctx.startOffset - dx / pxPerSec; + setOffset(offset); + }, + }); + return ( + + ); + }, +}; + +export const Vertical: Story = { + render: function RenderBasic() { + const pxPerSec = 1; + const [offset, setOffset] = useState(-24); + useEffect(() => { + const root = document.getElementById("storybook-root"); + if (!root) return; + + root.style.height = "100%"; + + return () => { + root.style.height = ""; + }; + }); + const handlePointerDown = createDragHandler({ + onDown: (e) => { + return { + startY: e.clientY, + startOffset: offset, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dy = e.clientY - ctx.startY; + const offset = ctx.startOffset - dy / pxPerSec; + setOffset(offset); + }, + }); + return ( +
+ +
+ ); + }, +}; diff --git a/src/components/Ruler/index.tsx b/src/components/Ruler/index.tsx new file mode 100644 index 0000000..28d73ae --- /dev/null +++ b/src/components/Ruler/index.tsx @@ -0,0 +1,105 @@ +import { forwardRef, memo, useMemo } from "react"; +import { classNames } from "../../utils/classNames"; +import { useRectResizeObserver } from "../../utils/interactions/useRectResizeObserver"; +import { mergeRefs } from "../../utils/mergeRefs"; +import { TimeText } from "./TimeText"; +import { defaultRenderText } from "./defaultRenderText"; +import { defaultSteps } from "./defaultSteps"; +import { getStepPixel } from "./getStepPixel"; + +import "./index.css"; + +export type RulerProps = { + offset?: number; + pxPerUnit?: number; + height?: number; + steps?: number[]; + renderText?: (time: number) => string; + minInterval?: number; + orientation?: "horizontal" | "vertical"; +} & Omit; + +export const Ruler = memo( + forwardRef( + ( + { + offset = 0, + pxPerUnit = 1, + renderText, + steps: propsSteps, + minInterval = 32, + className, + style, + orientation = "horizontal", + ...props + }: RulerProps, + fRef, + ) => { + const [rect, ref] = useRectResizeObserver(); + + + const length =(orientation === "horizontal" ? rect?.width : rect?.height) ?? 0; + + const steps = useMemo( + () => + getStepPixel( + pxPerUnit, + minInterval, + propsSteps ?? defaultSteps, + length, + offset, + ), + [pxPerUnit, minInterval, propsSteps, length, offset], + ); + const subSteps = useMemo( + () => + getStepPixel( + pxPerUnit, + minInterval / 4, + propsSteps ?? defaultSteps, + length, + offset, + ), + [pxPerUnit, minInterval, propsSteps, length, offset], + ); + + + return ( +
+ {subSteps.map((v) => { + return ( +
+ ); + })} + {steps.map((left) => { + const time = left / pxPerUnit + offset; + return ( + + ); + })} +
+ ); + }, + ), +); diff --git a/src/components/SVPicker/__snapshots__/index.stories.tsx.snap b/src/components/SVPicker/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..9db2ff7 --- /dev/null +++ b/src/components/SVPicker/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Colors/SVPicker Default smoke-test 1`] = ` +
+ + +
+
+
+`; diff --git a/src/components/SVPicker/index.css b/src/components/SVPicker/index.css new file mode 100644 index 0000000..acb8fcb --- /dev/null +++ b/src/components/SVPicker/index.css @@ -0,0 +1,23 @@ +.cmpui_sv-picker__root { + border: 1px solid var(--cmpui-border-color); + box-sizing: border-box; + display: flex; + height: fit-content; + position: relative; + touch-action: none; + width: fit-content; +} + +.cmpui_sv-picker__root:focus-visible { + outline: 1px solid var(--cmpui-primary-color); + outline-offset: 1px; +} + +.cmpui_sv-picker__nob { + cursor: grab; + transition: border 0.1s ease-in-out; +} + +.cmpui_sv-picker__nob:active { + cursor: grabbing; +} diff --git a/src/components/SVPicker/index.stories.tsx b/src/components/SVPicker/index.stories.tsx new file mode 100644 index 0000000..4904fe8 --- /dev/null +++ b/src/components/SVPicker/index.stories.tsx @@ -0,0 +1,30 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { SVPicker } from "."; + +const meta: Meta = { + title: "Components/Colors/SVPicker", + component: SVPicker, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: function Render() { + const [saturation, setSaturation] = useState(1); + const [value, setValue] = useState(1); + + return ( + { + setSaturation(s); + setValue(v); + }} + saturation={saturation} + value={value} + /> + ); + }, +}; diff --git a/src/components/SVPicker/index.tsx b/src/components/SVPicker/index.tsx new file mode 100644 index 0000000..7bb41d6 --- /dev/null +++ b/src/components/SVPicker/index.tsx @@ -0,0 +1,146 @@ +import { useCallback, useMemo, useState } from "react"; +import { hsvToRgb } from "../../utils/colors/hsvToRgb"; +import { rgbToCss } from "../../utils/colors/rgbToCss"; +import { useHighContrastColor } from "../../utils/colors/useHighContrastColor"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { useKeyDownStartEnd } from "../../utils/interactions/useKeyDownStartEnd"; +import { clamp } from "../../utils/math/clamp"; +import { Circle } from "../Circle"; +import { ColorLoupe } from "../ColorLoupe"; +import { SVCanvas } from "./lib/SVCanvas"; + +import "./index.css"; + +export type SVPickerProps = { + nobRadius?: number; + onChange: (saturation: number, value: number) => void; + hue: number; + saturation?: number; + showLoupe?: boolean; + value?: number; + width?: number; + height?: number; + onStart?: () => void; + onEnd?: () => void; +}; + +export function SVPicker({ + nobRadius = 8, + onChange, + hue, + saturation = 1, + showLoupe = true, + value = 1, + width = 192, + height = 192, + ...props +}: SVPickerProps) { + const x = saturation * width; + const y = (1 - value) * height; + + const [isDown, setIsDown] = useState(false); + + const updateKeyDown = useKeyDownStartEnd(props.onStart, props.onEnd); + + const handleKeyDown = useMemo( + () => (e: React.KeyboardEvent) => { + if (e.key === "ArrowLeft" || e.key === "ArrowRight") { + updateKeyDown(); + const sign = e.key === "ArrowLeft" ? -1 : 1; + const signedStep = 0.01 * sign; + const s = clamp(saturation + signedStep, 0, 1); + onChange(s, value); + e.preventDefault(); + } else if (e.key === "ArrowUp" || e.key === "ArrowDown") { + updateKeyDown(); + const sign = e.key === "ArrowUp" ? 1 : -1; + const signedStep = 0.01 * sign; + const v = clamp(value + signedStep, 0, 1); + onChange(saturation, v); + e.preventDefault(); + } + }, + [saturation, value, onChange, updateKeyDown], + ); + + const handleFocus = useCallback(() => { + setIsDown(true); + }, []); + + const handleBlur = useCallback(() => { + setIsDown(false); + }, []); + + const handlePointerDown = useMemo( + () => + createDragHandler({ + onDown: (e) => { + setIsDown(true); + props.onStart?.(); + return { + startX: e.clientX, + startY: e.clientY, + s: saturation, + v: value, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.startX; + const dy = e.clientY - ctx.startY; + const s = clamp(ctx.s + dx / width, 0, 1); + const v = clamp(ctx.v - dy / height, 0, 1); + onChange(s, v); + }, + onUp: () => { + setIsDown(false); + props.onEnd?.(); + }, + }), + [onChange, saturation, value, width, height, props.onEnd, props.onStart], + ); + + const fill = useMemo( + () => rgbToCss(hsvToRgb({ h: hue, s: saturation, v: value })), + [hue, saturation, value], + ); + + const hsv = useMemo( + () => ({ h: hue, s: saturation, v: value }), + [hue, saturation, value], + ); + + const strokeColor = useHighContrastColor(hsv); + + return ( +
+ + + {showLoupe && isDown && ( + + )} + +
+ ); +} diff --git a/src/components/SVPicker/lib/SVCanvas.tsx b/src/components/SVPicker/lib/SVCanvas.tsx new file mode 100644 index 0000000..bde8c30 --- /dev/null +++ b/src/components/SVPicker/lib/SVCanvas.tsx @@ -0,0 +1,93 @@ +import { memo, useEffect, useMemo, useRef } from "react"; +import { SVPickerProps } from ".."; +import { createDragHandler } from "../../../utils/interactions/createDragHandler"; +import { useTouchStartPrevent } from "../../../utils/interactions/useTouchStartPrevent"; +import { clamp } from "../../../utils/math/clamp"; +import { drawSV } from "./drawSV"; + +export const SVCanvas = memo(function SVCanvas( + props: SVPickerProps & { + width: number; + height: number; + onDownChange: (isDown: boolean) => void; + }, +) { + const canvasRef = useTouchStartPrevent(); + const ctx = useRef(null); + + useEffect(() => { + if (!canvasRef.current) return; + ctx.current = canvasRef.current?.getContext("2d", { + willReadFrequently: true, + }); + if (!ctx.current) return; + ctx.current.imageSmoothingEnabled = false; + ctx.current.imageSmoothingQuality = "low"; + }, [canvasRef.current]); + + useEffect(() => { + if (!ctx.current) return; + drawSV(ctx.current, props.hue); + }, [props.hue]); + + const handlePointerDownCanvas = useMemo( + () => + createDragHandler({ + onDown: (e) => { + props.onStart?.(); + const el = e.currentTarget; + const rect = el.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + const s = x / props.width; + const v = 1 - y / props.height; + props.onChange(s, v); + props.onDownChange(true); + + return { + startX: e.clientX, + startY: e.clientY, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + + const el = e.currentTarget; + if (!(el instanceof HTMLCanvasElement)) return; + const rect = el.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + const s = clamp(x / props.width, 0, 1); + const v = clamp(1 - y / props.height, 0, 1); + + props.onChange(s, v); + }, + + onUp: () => { + props.onDownChange(false); + props.onEnd?.(); + }, + }), + [ + props.height, + props.width, + props.onChange, + props.onDownChange, + props.onStart, + props.onEnd, + ], + ); + + return ( + + ); +}); diff --git a/src/components/SVPicker/lib/drawSV.tsx b/src/components/SVPicker/lib/drawSV.tsx new file mode 100644 index 0000000..a1eaffd --- /dev/null +++ b/src/components/SVPicker/lib/drawSV.tsx @@ -0,0 +1,21 @@ +import { hsvToRgb } from "../../../utils/colors/hsvToRgb"; + +export function drawSV(ctx: CanvasRenderingContext2D, hue: number) { + const width = ctx.canvas.width; + const height = ctx.canvas.height; + const imageData = ctx.getImageData(0, 0, width, height); + const data = imageData.data; + + for (let i = 0; i < height; i++) { + for (let j = 0; j < width; j++) { + const index = (i * width + j) * 4; + const { r, g, b } = hsvToRgb({ h: hue, s: j / height, v: 1 - i / width }); + data[index] = r; + data[index + 1] = g; + data[index + 2] = b; + data[index + 3] = 255; + } + } + + ctx.putImageData(imageData, 0, 0); +} diff --git a/src/components/Select/SelectItem.tsx b/src/components/Select/SelectItem.tsx new file mode 100644 index 0000000..457783e --- /dev/null +++ b/src/components/Select/SelectItem.tsx @@ -0,0 +1,44 @@ +import * as RadixSelect from "@radix-ui/react-select"; +import { ListItem } from "../ListItem"; + +export type SelectItemProps = { + children: React.ReactNode; + disabled?: boolean; + onSelect?: () => void; + value: string; +}; + +export function SelectItem(props: SelectItemProps) { + return ( + + + + + + + + {props.children} + + + ); +} diff --git a/src/components/Select/__snapshots__/index.stories.tsx.snap b/src/components/Select/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..25cf235 --- /dev/null +++ b/src/components/Select/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,121 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Form/Select Basic smoke-test 1`] = ` + +`; + +exports[`Components/Form/Select Disabled smoke-test 1`] = ` + +`; + +exports[`Components/Form/Select DisabledItem smoke-test 1`] = ` + +`; + +exports[`Components/Form/Select Fonts smoke-test 1`] = ` + +`; diff --git a/src/components/Select/index.css b/src/components/Select/index.css new file mode 100644 index 0000000..aabe133 --- /dev/null +++ b/src/components/Select/index.css @@ -0,0 +1,55 @@ +.cmpui_select__root { + align-items: center; + background-color: var(--cmpui-bg-color); + border-radius: 4px; + border: 1px solid var(--cmpui-border-color); + box-sizing: border-box; + color: var(--cmpui-text-color); + cursor: pointer; + display: flex; + font-family: unset; + font-size: 14px; + gap: 8px; + height: 32px; + justify-content: space-between; + line-height: 16px; + padding: 0px 8px; + position: relative; + text-decoration: none; +} + +.cmpui_select__root[aria-disabled="true"] { + cursor: default; + opacity: 0.5; +} + +.cmpui_select__root:hover { + border: 1px solid var(--cmpui-border-hover-color); +} + +.cmpui_select__label { + background-image: linear-gradient( + to bottom, + transparent 0%, + var(--cmpui-bg-color) 25%, + var(--cmpui-bg-color) 75%, + transparent 100% + ); + color: var(--cmpui-text2-color); + + font-size: 12px; + line-height: 14px; + padding: 0 4px; + position: absolute; + transform: translate(0, -16px); +} + +.cmpui_select__root:focus-visible { + outline: var(--cmpui-primary-color) solid 1px; + outline-offset: 1px; +} + +.cmpui_select__root:disabled { + cursor: default; + opacity: 0.5; +} diff --git a/src/components/Select/index.stories.tsx b/src/components/Select/index.stories.tsx new file mode 100644 index 0000000..c830061 --- /dev/null +++ b/src/components/Select/index.stories.tsx @@ -0,0 +1,155 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useEffect, useState } from "react"; +import { Select } from "."; +import { SelectItem } from "./SelectItem"; + +const meta: Meta = { + title: "Components/Form/Select", + component: Select, +}; + +export default meta; + +type Story = StoryObj; + +const options = [ + { + label: "Option 1", + value: "1", + }, + { + label: "Option 2", + value: "2", + }, + { + label: "Option 3", + value: "3", + }, + { + label: "Option 4", + value: "4", + }, +]; + +export const Basic: Story = { + render: function Render() { + const [value, setValue] = useState("1"); + return ( + + ); + }, +}; + +export const Disabled: Story = { + render: function Render() { + const [value, setValue] = useState("1"); + return ( + + ); + }, +}; + +export const DisabledItem: Story = { + render: function Render() { + const [value, setValue] = useState("1"); + return ( + + ); + }, +}; + +const fontList = [ + "Roboto", + "Sixtyfour", + "Wavefont", + "Gabarito", + "Agbalumo", + "Honk", + "Slackside One", + "Smooch", + "Chokokutai", + "Monomaniac One", + "Palette Mosaic", +].sort(); +export const Fonts: Story = { + render: function Render() { + const fonts = fontList.map((font) => ({ + label: font, + value: font, + family: font, + url: `https://fonts.googleapis.com/css2?family=${font}&display=swap`, + })); + const [value, setValue] = useState("Roboto"); + return ( + + ); + }, +}; + +const map = new Map(); +function loadFontFromCss(url: string) { + if (map.has(url)) return; + + const link = document.createElement("link"); + link.href = url; + link.rel = "stylesheet"; + document.head.appendChild(link); + + map.set(url, url); +} + +function FontRender(props: { + value: string; + url: string; + family: string; + children: React.ReactNode; +}) { + useEffect(() => { + loadFontFromCss(props.url); + }, [props.url]); + + return ( + +
+ {props.children} +
+
+ ); +} diff --git a/src/components/Select/index.tsx b/src/components/Select/index.tsx new file mode 100644 index 0000000..08e81d9 --- /dev/null +++ b/src/components/Select/index.tsx @@ -0,0 +1,62 @@ +import * as RadixSelect from "@radix-ui/react-select"; +import { classNames } from "../.."; +import { FloatBox } from "../FloatBox"; + +import "./index.css"; + +export type SelectProps = { + children?: React.ReactNode; + disabled?: boolean; + label?: React.ReactNode; + onChange?: (value: string) => void; + value?: string; + className?: string; +}; + +export function Select(props: SelectProps) { + return ( + + + + + + + + + + + + + + + + {props.children} + + + + + + ); +} diff --git a/src/components/SelectRect/__snapshots__/index.stories.tsx.snap b/src/components/SelectRect/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..b814322 --- /dev/null +++ b/src/components/SelectRect/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Controls/SelectRect Basic smoke-test 1`] = ` +
+
+`; + +exports[`Components/Controls/SelectRect Static smoke-test 1`] = ` +
+
+
+
+`; diff --git a/src/components/SelectRect/index.stories.tsx b/src/components/SelectRect/index.stories.tsx new file mode 100644 index 0000000..0476361 --- /dev/null +++ b/src/components/SelectRect/index.stories.tsx @@ -0,0 +1,48 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { SelectRect, useSelectRectHandler } from "."; + +const meta: Meta = { + title: "Components/Controls/SelectRect", + component: SelectRect, + parameters: { + layout: "fullscreen", + }, +}; + +export default meta; + +type Story = StoryObj; + +export const Basic: Story = { + render: function Render() { + const { rect, onPointerDown } = useSelectRectHandler(); + return ( +
+ {rect && } +
+ ); + }, +}; + +export const Static: Story = { + render: function Render() { + return ( +
+ {} +
+ ); + }, +}; diff --git a/src/components/SelectRect/index.tsx b/src/components/SelectRect/index.tsx new file mode 100644 index 0000000..c98c6e9 --- /dev/null +++ b/src/components/SelectRect/index.tsx @@ -0,0 +1,94 @@ +import { memo, useMemo, useState } from "react"; +import { createDragHandler } from "../.."; + +type SelectRectProps = { + x: number; + y: number; + width: number; + height: number; + + className?: string; + style?: React.CSSProperties; +}; + +type Rect = { + x: number; + y: number; + width: number; + height: number; +}; + +export function useSelectRectHandler() { + const [rect, setRect] = useState(null); + + const onPointerDown = useMemo( + () => + createDragHandler({ + onDown: (e) => { + const el = e.currentTarget as HTMLElement; + const rect = el.getBoundingClientRect(); + return { + x: e.clientX - rect.left, + y: e.clientY - rect.top, + }; + }, + onMove: (_, ctx, move) => { + if (!ctx) return; + + let x = ctx.x; + let y = ctx.y; + let width = move.dx; + let height = move.dy; + if (move.dx < 0) { + x += move.dx; + width = -move.dx; + } + if (move.dy < 0) { + y += move.dy; + height = -move.dy; + } + + setRect({ + x, + y, + width, + height, + }); + }, + onUp: () => { + setRect(null); + }, + options: { + disableCapture: true, + }, + }), + [], + ); + + return { + rect, + onPointerDown, + }; +} + +export const SelectRect = memo(function SelectRect(props: SelectRectProps) { + return ( +
+ ); +}); diff --git a/src/components/Slider/__snapshots__/index.stories.tsx.snap b/src/components/Slider/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..e4342d0 --- /dev/null +++ b/src/components/Slider/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,120 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Form/Slider Basic smoke-test 1`] = ` +
+
+
+
+
+
+
+
+`; + +exports[`Components/Form/Slider Disabled smoke-test 1`] = ` +
+
+
+
+
+
+
+
+`; + +exports[`Components/Form/Slider MinMax smoke-test 1`] = ` +
+
+
+
+
+
+
+
+`; + +exports[`Components/Form/Slider RtoL smoke-test 1`] = ` +
+
+
+
+
+
+
+
+`; + +exports[`Components/Form/Slider Vertical smoke-test 1`] = ` +
+
+
+
+
+
+
+
+`; + +exports[`Components/Form/Slider VerticalR2L smoke-test 1`] = ` +
+
+
+
+
+
+
+
+`; diff --git a/src/components/Slider/index.css b/src/components/Slider/index.css new file mode 100644 index 0000000..fe30bce --- /dev/null +++ b/src/components/Slider/index.css @@ -0,0 +1,108 @@ +.cmpui_slider__root { + align-items: center; + border-radius: 8px; + box-sizing: border-box; + display: flex; + position: relative; + width: 200px; + cursor: pointer; +} + +.cmpui_slider__root[aria-disabled="true"] { + opacity: 0.5; +} + +.cmpui_slider__root[data-orientation="vertical"] { + flex-direction: column; + height: 100px; + width: 4px; +} + +.cmpui_slider__input { + appearance: none; + background: transparent; + border-radius: 8px; + border: none; + box-sizing: border-box; + display: flex; + height: 100%; + margin: 0; + padding: 0; +} + +.cmpui_slider__input::-webkit-slider-thumb { + appearance: none; +} + +.cmpui_slider__root:hover > .cmpui_slider-track { + border: 1px solid var(--cmpui-border-hover-color); +} + +.cmpui_slider__root[aria-disabled="true"]:hover > .cmpui_slider-track { + border: 1px solid var(--cmpui-border-color); +} + +.cmpui_slider__input:focus > .cmpui_slider-track { + box-shadow: 0 0 0 1px var(--cmpui-primary-color); + outline: none; +} + +.cmpui_slider__nob { + background-color: var(--cmpui-primary-color); + border-radius: 50%; + box-shadow: var(--cmpui-float-shadow); + cursor: grab; + display: block; + height: 16px; + width: 16px; + position: absolute; +} + +.cmpui_slider__nob:active { + cursor: grabbing; +} + +.cmpui_slider__nob[data-disabled] { + cursor: default; +} + +.cmpui_slider__nob[data-orientation="vertical"] { + top: unset; +} + +.cmpui_slider__nob:focus { + outline: none; +} + +.cmpui_slider__nob:focus-visible { + outline: var(--cmpui-primary-color) solid 1px; + outline-offset: 1px; +} + +.cmpui_slider__track { + background-color: var(--cmpui-bg-color); + border-radius: 8px; + border: 1px solid var(--cmpui-border-color); + height: 4px; + position: relative; + top: 0; + width: 100%; +} + +.cmpui_slider__track[data-orientation="vertical"] { + height: 100%; + width: 4px; +} + +.cmpui_slider__range { + background-color: var(--cmpui-primary-color); + border-radius: 8px; + height: 100%; + position: absolute; + top: 0; +} + +.cmpui_slider__range[data-orientation="vertical"] { + height: unset; + width: 100%; +} diff --git a/src/components/Slider/index.stories.tsx b/src/components/Slider/index.stories.tsx new file mode 100644 index 0000000..a9f3035 --- /dev/null +++ b/src/components/Slider/index.stories.tsx @@ -0,0 +1,82 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { Slider } from "."; + +const meta: Meta = { + title: "Components/Form/Slider", + component: Slider, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = { + render: () => { + const [value, setValue] = useState(0.5); + return ( + <> + + + ); + }, +}; + +export const MinMax: Story = { + render: () => { + const [value, setValue] = useState(50); + return ( + <> + + + ); + }, +}; + +export const RtoL: Story = { + render: () => { + const [value, setValue] = useState(0.5); + return ( + <> + + + ); + }, +}; + +export const Vertical: Story = { + render: () => { + const [value, setValue] = useState(0.5); + return ( + <> + + + ); + }, +}; + +export const VerticalR2L: Story = { + render: () => { + const [value, setValue] = useState(0.5); + return ( + <> + + + ); + }, +}; + +export const Disabled: Story = { + render: () => { + const [value, setValue] = useState(0.5); + return ( + <> + + + ); + }, +}; diff --git a/src/components/Slider/index.tsx b/src/components/Slider/index.tsx new file mode 100644 index 0000000..d5abbfe --- /dev/null +++ b/src/components/Slider/index.tsx @@ -0,0 +1,178 @@ +import { useMemo, useRef } from "react"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { clamp } from "../../utils/math/clamp"; +import "./index.css"; + +export type SliderProps = { + value: number; + min?: number; + max?: number; + step?: number; + disabled?: boolean; + orientation?: "horizontal" | "vertical"; + direction?: "ltr" | "rtl"; + + onChange: (value: number) => void; +}; + +export function Slider({ + min = 0, + max = 1, + step = 0.01, + ...props +}: SliderProps) { + const ref = useRef(null); + + const length = max - min; + + const handleKeyDown = useMemo(() => { + return (e: React.KeyboardEvent) => { + let sign = 0; + if (e.key === "ArrowLeft" || e.key === "ArrowDown") { + sign = -1; + } else if (e.key === "ArrowRight" || e.key === "ArrowUp") { + sign = 1; + } + + if (props.orientation === "vertical") { + sign *= -1; + } + + if (sign !== 0) { + const signedStep = step * sign; + const value = clamp(props.value + signedStep, min, max); + props.onChange(value); + e.preventDefault(); + } + }; + }, [props.onChange, props.orientation, props.value, step, min, max]); + + const handlePointerDownNob = useMemo( + () => + createDragHandler({ + onDown: (e) => { + e.stopPropagation(); + const rect = e.currentTarget.getBoundingClientRect(); + const offsetX = e.clientX - rect.left; + const offsetY = e.clientY - rect.top; + + return { + offsetX, + offsetY, + startX: e.clientX, + startY: e.clientY, + value: props.value, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + const dx = e.clientX - ctx.startX; + const dy = e.clientY - ctx.startY; + + if (!ref.current) return; + const rect = ref.current.getBoundingClientRect(); + + let value: number; + if (props.orientation === "vertical") { + value = ctx.value + (dy / rect.height) * length; + } else { + value = ctx.value + (dx / rect.width) * length; + } + props.onChange(clamp(value, min, max)); + }, + }), + [props.onChange, props.orientation, min, max, length, props.value], + ); + + const handlePointerDown = useMemo( + () => + createDragHandler({ + onDown: (e) => { + const rect = e.currentTarget.getBoundingClientRect(); + + const value = ((e.clientX - rect.left) / rect.width) * length + min; + + props.onChange(clamp(value, min, max)); + + return { + startX: e.clientX, + startY: e.clientY, + }; + }, + onMove: (e, ctx) => { + if (!ctx) return; + + if (!ref.current) return; + const rect = ref.current.getBoundingClientRect(); + + let value: number; + if (props.orientation === "vertical") { + value = ((e.clientY - rect.top) / rect.height) * length + min; + } else { + value = ((e.clientX - rect.left) / rect.width) * length + min; + } + props.onChange(clamp(value, min, max)); + }, + }), + [props.onChange, props.orientation, min, max, length], + ); + + const leftRatio = ((props.value - min) / length) * 100; + + const rangeStyle = useMemo(() => { + return { + width: + props.orientation === "vertical" + ? "100%" + : `${props.direction === "rtl" ? 100 - leftRatio : leftRatio}%`, + height: + props.orientation === "vertical" + ? `${props.direction === "rtl" ? 100 - leftRatio : leftRatio}%` + : "100%", + top: + props.orientation === "vertical" && props.direction === "rtl" + ? `${leftRatio}%` + : "", + }; + }, [props.orientation, props.direction, leftRatio]); + + const nobStyle = useMemo(() => { + return { + left: props.orientation === "vertical" ? "" : `calc(${leftRatio}% - 8px)`, + top: props.orientation === "vertical" ? `calc(${leftRatio}% - 8px)` : "", + }; + }, [props.orientation, leftRatio]); + + return ( + <> +
+
+
+
+
+
+ + ); +} diff --git a/src/components/SliderNumberField/__snapshots__/index.stories.tsx.snap b/src/components/SliderNumberField/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..7725403 --- /dev/null +++ b/src/components/SliderNumberField/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,53 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Form/SliderNumberField Basic smoke-test 1`] = ` +
+ + +
+`; + +exports[`Components/Form/SliderNumberField Mixed smoke-test 1`] = ` +
+
+ + +
+
+
+ +
+
+ +
+
+ +
+
+
+`; diff --git a/src/components/SliderNumberField/index.css b/src/components/SliderNumberField/index.css new file mode 100644 index 0000000..75a170b --- /dev/null +++ b/src/components/SliderNumberField/index.css @@ -0,0 +1,9 @@ +.cmpui_slider-number-input__root:focus { + cursor: text; +} + +.cmpui_slider-number-input__label { + cursor: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iMjQiPgogICAgPGRlZnM+CiAgICAgICAgPGZpbHRlciBpZD0ic2hhZG93Ij4KICAgICAgICAgICAgPGZlRHJvcFNoYWRvdyBkeD0iMCIgZHk9IjAiIHN0ZERldmlhdGlvbj0iMzIiCiAgICAgICAgICAgICAgICBmbG9vZC1jb2xvcj0iYmxhY2siCiAgICAgICAgICAgICAgICBmbG9vZC1vcGFjaXR5PSIxIgogICAgICAgICAgICAvPgogICAgICAgIDwvZmlsdGVyPgogICAgPC9kZWZzPgogICAgPHBhdGgKICAgICAgICBzdHlsZT0iZmlsdGVyOnVybCgjc2hhZG93KTsiCiAgICAgICAgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI0OCIKICAgICAgICBkPSJNMjkwLjc0LTI5MC4wNDIgMTAwLjc4Mi00ODAgMjkwLjc0LTY2OS45NThsNzQuNTIyIDc0LjY1My02MS43MzkgNjIuMzA0aDM1Mi45NTRsLTYxLjMwNS02Mi44NjkgNzQuMDg4LTc0LjA4OEw4NTkuMjE4LTQ4MCA2NjkuODI2LTI5MC42MDdsLTc0LjY1NC03NC4wODggNjEuMzA1LTYyLjMwNEgzMDIuOTU4bDYyLjQzNSA2Mi4zMDQtNzQuNjUzIDc0LjY1M1oiIC8+Cjwvc3ZnPg==) + 8 8, + ew-resize; +} diff --git a/src/components/SliderNumberField/index.stories.tsx b/src/components/SliderNumberField/index.stories.tsx new file mode 100644 index 0000000..af8f588 --- /dev/null +++ b/src/components/SliderNumberField/index.stories.tsx @@ -0,0 +1,68 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { SliderNumberField } from "."; +import { TextInput } from "../TextInput"; + +const meta: Meta = { + title: "Components/Form/SliderNumberField", + component: SliderNumberField, +}; + +export default meta; + +type Story = StoryObj; + +export const Basic: Story = { + render: function Render(props) { + const [value, setValue] = useState([0]); + return ( + + ); + }, +}; + +export const Mixed: Story = { + render: function Render(props) { + const [values, setValues] = useState([1, 2, 3]); + return ( +
+ { + if (!Array.isArray(values)) throw new Error("values is not array"); + setValues(values); + }} + /> +
+ {values.map((value, index) => ( + { + const newValues = [...values]; + newValues[index] = Number(e.target.value); + setValues(newValues); + }} + /> + ))} +
+
+ ); + }, +}; diff --git a/src/components/SliderNumberField/index.tsx b/src/components/SliderNumberField/index.tsx new file mode 100644 index 0000000..b29b475 --- /dev/null +++ b/src/components/SliderNumberField/index.tsx @@ -0,0 +1,283 @@ +import { forwardRef, memo, useCallback, useMemo, useState } from "react"; +import { classNames } from "../.."; +import { TextInput } from "../TextInput"; +import { createWindowDragHandler } from "../TreeView/lib/createWindowDragHandler"; +import { inputEval } from "./lib/inputEval"; +import { parseCursorStyle } from "./lib/parseCursorStyle"; + +import "./index.css"; + +export type SliderNumberField = { + label: string; + step?: number; + value?: number[]; + onChangeValue?: (value: number[]) => void; + numToString?: (value: number) => string; + evalFunc?: (str: string, mixed?: number) => number; + suffix?: React.ReactNode; + onStart?: () => void; + onEnd?: () => void; +} & Omit, "value">; + +export const SliderNumberField = memo( + forwardRef(function SliderNumberField( + { + label, + value, + step = 1, + suffix, + className, + numToString = (value) => value.toString(), + onChangeValue, + evalFunc = inputEval, + onStart, + onEnd, + ...props + }, + ref, + ) { + const isMixed = + Array.isArray(value) && + value.reduce((acc, v) => { + return acc || v !== value[0]; + }, false); + + const [_value, set_value] = useState( + isMixed ? "mixed" : typeof value === "number" ? numToString(value) : "", + ); + + const [isFocused, setIsFocused] = useState(false); + + const down = useMemo( + () => + createWindowDragHandler< + | { + startValue: number | number[]; + startX?: number; + el?: HTMLImageElement; + input?: HTMLInputElement; + } + | undefined, + | { + value?: number | number[]; + } + | undefined + >({ + onDown: (e) => { + if (isFocused && e.currentTarget instanceof HTMLInputElement) + return; + document.body.requestPointerLock(); + + const el = document.createElement("img"); + el.style.position = "fixed"; + document.body.appendChild(el); + + if (e.currentTarget instanceof HTMLElement) { + const cursor = getComputedStyle(e.currentTarget).cursor; + const result = parseCursorStyle(cursor); + if (result) { + el.src = result.src; + // 0.5 for visual adjustment + el.style.left = `${e.clientX - Number(result.x) - 0.5}px`; + el.style.top = `${e.clientY - Number(result.y) - 0.5}px`; + document.body.appendChild(el); + } + } + + onStart?.(); + return { + startValue: value ?? 0, + startX: e.clientX, + el, + input: e.currentTarget as HTMLInputElement, + }; + }, + onMove: (e, ctx, prev) => { + if (!ctx) return; + const diff = e.movementX; + const diffY = e.movementY; + const el = ctx.el; + if (!el) return; + const left = Number(el.style.left.replace("px", "")); + const offset = 12; + if (left + diff < -offset) { + el.style.left = `${window.innerWidth + diff - offset}px`; + } else if (left + diff > window.innerWidth - offset) { + el.style.left = `${diff - offset}px`; + } else { + el.style.left = `${left + diff}px`; + } + + const top = Number(el.style.top.replace("px", "")); + if (top + diffY < -offset) { + el.style.top = `${window.innerHeight + diffY - offset}px`; + } else if (top + diffY > window.innerHeight - offset) { + el.style.top = `${diffY - offset}px`; + } else { + el.style.top = `${top + diffY}px`; + } + + if (value !== undefined) { + let v: number[] = value; + if (prev?.value !== undefined && Array.isArray(prev.value)) { + v = prev.value; + } + const newValues = v.map((value) => { + return value + Math.round(diff) * step; + }); + onChangeValue?.(newValues); + return { + value: newValues, + }; + } + }, + onUp: (_, ctx) => { + if (!ctx) return; + ctx.el?.remove(); + document.exitPointerLock(); + onEnd?.(); + }, + }), + [isFocused, onChangeValue, onStart, onEnd, step, value], + ); + + const handleCommit = useCallback( + (rawValue: string) => { + if (value !== undefined) { + const newValues = value.map((value) => { + return evalFunc(rawValue, value); + }); + if (newValues.some((value) => Number.isNaN(value))) return value; + onChangeValue?.(newValues); + return newValues; + } + }, + [evalFunc, onChangeValue, value], + ); + + const handleBlur = useCallback( + (e: React.FocusEvent) => { + handleCommit(e.currentTarget.value); + setIsFocused(false); + }, + [handleCommit], + ); + + const handleChange = useCallback( + (e: React.ChangeEvent) => { + const rawValue = e.currentTarget.value; + set_value(rawValue); + }, + [], + ); + + const handleClick = useCallback( + (e: React.MouseEvent) => { + e.currentTarget.select(); + }, + [], + ); + + const getValue = useMemo(() => { + if (isFocused) { + return _value; + } + if (isMixed) { + return "mixed"; + } + if (value === undefined) { + return ""; + } + if (typeof value === "number") { + return numToString(value); + } + return numToString(value[0]); + }, [_value, isFocused, isMixed, numToString, value]); + + const handleFocus = useCallback( + (e: React.FocusEvent) => { + e.currentTarget.select(); + set_value(getValue); + setIsFocused(true); + }, + [getValue], + ); + + const handleKeyDown = useCallback( + (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + const newValues = handleCommit(e.currentTarget.value); + if (newValues === undefined) { + return; + } + if (typeof newValues === "number") { + set_value(newValues ? numToString(newValues) : ""); + } else { + const isMixed = newValues.reduce((acc, value) => { + return acc || value !== newValues[0]; + }, false); + if (isMixed) { + set_value("mixed"); + } else { + set_value(numToString(newValues[0])); + } + } + } else if (e.key === "Escape") { + set_value(getValue); + } else if (e.key === "ArrowUp") { + if (value === undefined) { + return; + } + + const isMixed = value.reduce((acc, v) => { + return acc || v !== value[0]; + }, false); + if (isMixed) { + onChangeValue?.(value.map((value) => value + step)); + } else { + set_value(numToString(value[0] + step)); + } + e.preventDefault(); + } else if (e.key === "ArrowDown") { + if (value === undefined) { + return; + } + + const isMixed = value.reduce((acc, v) => { + return acc || v !== value[0]; + }, false); + if (isMixed) { + onChangeValue?.(value.map((value) => value - step)); + } else { + set_value(numToString(value[0] - step)); + } + e.preventDefault(); + } + }, + [getValue, handleCommit, numToString, onChangeValue, step, value], + ); + + return ( + + {label} + + } + /> + ); + }), +); diff --git a/src/components/SliderNumberField/lib/inputEval.test.ts b/src/components/SliderNumberField/lib/inputEval.test.ts new file mode 100644 index 0000000..e326db9 --- /dev/null +++ b/src/components/SliderNumberField/lib/inputEval.test.ts @@ -0,0 +1,14 @@ +import { expect, test } from "vitest"; +import { inputEval } from "./inputEval"; + +test("inputEval correctly evaluates mathematical expression", () => { + expect(inputEval("1 + 2")).toEqual(3); + expect(inputEval("1.2 + 2")).toEqual(1.2 + 2); + expect(inputEval("(1 + 2) * 3")).toEqual((1 + 2) * 3); + expect(inputEval("mixed + 3", 3)).toEqual(3 + 3); + expect(inputEval("Math.sin(2)")).toEqual(Math.sin(2)); + expect(inputEval("Math.PI")).toEqual(Math.PI); + + expect(inputEval("Math.PI2")).toEqual(Number.NaN); + expect(inputEval("123mixed + 123", 3)).toEqual(Number.NaN); +}); diff --git a/src/components/SliderNumberField/lib/inputEval.ts b/src/components/SliderNumberField/lib/inputEval.ts new file mode 100644 index 0000000..8e26e22 --- /dev/null +++ b/src/components/SliderNumberField/lib/inputEval.ts @@ -0,0 +1,20 @@ +import { isEvalSafe } from "./isEvalSafe"; + +export function inputEval(str: string, mixed?: number): number { + try { + if (!isEvalSafe(str)) { + return Number.NaN; + } + if (mixed) { + return new Function("mixed", `return ${str}`)(mixed); + } + + const result = new Function(`return ${str}`)(); + if (typeof result === "number") { + return result; + } + return Number.NaN; + } catch { + return Number.NaN; + } +} diff --git a/src/components/SliderNumberField/lib/isEvalSafe.test.ts b/src/components/SliderNumberField/lib/isEvalSafe.test.ts new file mode 100644 index 0000000..543bba3 --- /dev/null +++ b/src/components/SliderNumberField/lib/isEvalSafe.test.ts @@ -0,0 +1,24 @@ +import { expect, test } from "vitest"; +import { isEvalSafe } from "./isEvalSafe"; + +test("sEvalSafe returns true for safe expressions", () => { + expect(isEvalSafe("1 + 2")).true; + expect(isEvalSafe("1.1 + 2")).true; + expect(isEvalSafe("1 - 2")).true; + expect(isEvalSafe("1 / 2")).true; + expect(isEvalSafe("1 * 2")).true; + expect(isEvalSafe("123 * 345 + 123")).true; + expect(isEvalSafe("(1 + 2) * 3")).true; + expect(isEvalSafe("mixed + 123")).true; + expect(isEvalSafe("Math.sin(5) + 123")).true; + expect(isEvalSafe("Math.floor(5) + 123")).true; +}); + +test("isEvalSafe returns false for unsafe expressions", () => { + expect(isEvalSafe("hoge")).false; + expect(isEvalSafe("1 = 2")).false; + expect(isEvalSafe("unmixed + 123")).false; + expect(isEvalSafe("123mixed + 123")).false; + expect(isEvalSafe("alart(1)")).false; + expect(isEvalSafe("Math.undefined(5)")).false; +}); diff --git a/src/components/SliderNumberField/lib/isEvalSafe.ts b/src/components/SliderNumberField/lib/isEvalSafe.ts new file mode 100644 index 0000000..40a95e2 --- /dev/null +++ b/src/components/SliderNumberField/lib/isEvalSafe.ts @@ -0,0 +1,9 @@ +const mathProps = Object.getOwnPropertyNames(Math); + +export function isEvalSafe(str: string) { + return new RegExp( + `^(\\b(mixed|${mathProps + .map((prop) => `Math.${prop}`) + .join("|")})\\b|[\\(\\)0-9. \\-+/*])+$`, + ).test(str); +} diff --git a/src/components/SliderNumberField/lib/parseCursorStyle.ts b/src/components/SliderNumberField/lib/parseCursorStyle.ts new file mode 100644 index 0000000..7286d64 --- /dev/null +++ b/src/components/SliderNumberField/lib/parseCursorStyle.ts @@ -0,0 +1,12 @@ +export function parseCursorStyle(cursor: string) { + const match = new RegExp(/^url\("(.*)"\) ([0-9]+) ([0-9]+)/); + const result = match.exec(cursor); + if (result) { + return { + src: result[1], + x: Number(result[2]), + y: Number(result[3]), + }; + } + return null; +} diff --git a/src/components/SplitPane/__snapshots__/index.stories.tsx.snap b/src/components/SplitPane/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..8cfca75 --- /dev/null +++ b/src/components/SplitPane/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,237 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Layout/SplitPane Horizontal smoke-test 1`] = ` +
+
+
+
+
+ A +
+
+
+
+
+
+
+
+
+
+ B +
+
+
+
+
+
+
+
+
+
+ C +
+
+
+
+
+`; + +exports[`Components/Layout/SplitPane MinMax smoke-test 1`] = ` +
+
+
+
+
+ A +
+
+
+
+
+
+
+
+
+
+ B +
+
+
+
+
+
+
+
+
+
+ C +
+
+
+
+
+`; + +exports[`Components/Layout/SplitPane Readonly smoke-test 1`] = ` +
+
+
+
+
+ A +
+
+
+
+
+
+
+
+
+
+ B +
+
+
+
+
+
+
+
+
+
+ C +
+
+
+
+
+`; + +exports[`Components/Layout/SplitPane Vertical smoke-test 1`] = ` +
+
+
+
+
+ A +
+
+
+
+
+
+
+
+
+
+ B +
+
+
+
+
+
+
+
+
+
+ C +
+
+
+
+
+`; diff --git a/src/components/SplitPane/index.css b/src/components/SplitPane/index.css new file mode 100644 index 0000000..0777b6d --- /dev/null +++ b/src/components/SplitPane/index.css @@ -0,0 +1,62 @@ +.cmpui_split-pane__root { + display: flex; + height: 100%; + overflow: hidden; + width: 100%; +} + +.cmpui_split-pane__root[data-orientation="vertical"] { + flex-direction: column; +} + +.cmpui_split-pane__child { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; + width: 100%; +} + +.cmpui_split-pane__divider { + align-items: center; + display: flex; + justify-content: center; + min-width: 4px; +} + +.cmpui_split-pane__divider[data-resizable="true"] { + cursor: col-resize; +} + +.cmpui_split-pane__divider[data-orientation="vertical"] { + min-height: 4px; + width: 100%; +} + +.cmpui_split-pane__divider[data-resizable="true"][data-orientation="vertical"] { + cursor: row-resize; +} + +.cmpui_split-pane__divider > div { + height: 100%; + transition: width 0.1s ease-in-out; + width: 0px; +} + +.cmpui_split-pane__divider[data-orientation="vertical"] > div { + height: 0px; + transition: height 0.1s ease-in-out; + width: 100%; +} + +.cmpui_split-pane__divider[data-resizable="true"]:hover > div { + background-color: var(--cmpui-primary-color); + width: 4px; +} + +.cmpui_split-pane__divider[data-resizable="true"][data-orientation="vertical"]:hover + > div { + background-color: var(--cmpui-primary-color); + height: 4px; + width: 100%; +} diff --git a/src/components/SplitPane/index.stories.tsx b/src/components/SplitPane/index.stories.tsx new file mode 100644 index 0000000..c0ea656 --- /dev/null +++ b/src/components/SplitPane/index.stories.tsx @@ -0,0 +1,88 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { SplitPane } from "."; +import { Panel } from "../../__stories__/Panel"; +import { Root } from "../../__stories__/Root"; + +const meta: Meta = { + title: "Components/Layout/SplitPane", + component: SplitPane, + parameters: { + layout: "fullscreen", + }, +}; + +export default meta; +type Story = StoryObj; + +export const Horizontal: Story = { + render: function Render() { + const [sizes, setSizes] = useState( + Array(3).fill(`${(1 / 3) * 100}%`), + ); + return ( + + + + + + + + ); + }, +}; + +export const Readonly: Story = { + render: function Render() { + const [sizes] = useState(Array(3).fill(`${(1 / 3) * 100}%`)); + return ( + + + + + + + + ); + }, +}; + +export const MinMax: Story = { + render: function Render() { + const [sizes, setSizes] = useState( + Array(3).fill(`${(1 / 3) * 100}%`), + ); + return ( + + + + + + + + ); + }, +}; + +export const Vertical: Story = { + render: function Render() { + const [sizes, setSizes] = useState( + Array(3).fill(`${(1 / 3) * 100}%`), + ); + return ( + + + + + + + + ); + }, +}; diff --git a/src/components/SplitPane/index.tsx b/src/components/SplitPane/index.tsx new file mode 100644 index 0000000..9d0cf17 --- /dev/null +++ b/src/components/SplitPane/index.tsx @@ -0,0 +1,79 @@ +import React, { forwardRef } from "react"; +import { mergeRefs } from "../../utils/mergeRefs"; +import { useSplitPane } from "./useSplitPane"; + +import "./index.css"; + +export type SplitPaneProps = { + children?: React.ReactNode[]; + maxSizes?: string[]; + minSizes?: string[]; + onChangeRates?: (rates: string[]) => void; + sizes?: string[]; + type: "horizontal" | "vertical"; +}; + +export const SplitPane = forwardRef( + function HSplitPane({ children, type, onChangeRates, ...props }, ref) { + let sizes = props.sizes ?? Array(children?.length ?? 0).fill("100%"); + if (sizes.length < (children?.length ?? 0)) { + sizes = sizes.concat( + Array((children?.length ?? 0) - sizes.length).fill("100%"), + ); + } + + const minSizes = props.minSizes ?? Array(sizes.length).fill("auto"); + const maxSizes = props.maxSizes ?? Array(sizes.length).fill("auto"); + const { rootRef, refs, handlePointerDownForRef } = useSplitPane( + type, + sizes, + maxSizes, + minSizes, + (sizes) => { + onChangeRates?.(sizes); + }, + ); + + return ( + <> +
+ {children?.map((child, i) => ( + +
{ + if (el !== null) { + refs.current[i] = el; + } + }} + className="cmpui_split-pane__child" + style={{ + width: type === "horizontal" ? sizes[i] : "100%", + height: type === "vertical" ? sizes[i] : "100%", + minWidth: type === "horizontal" ? minSizes[i] : undefined, + minHeight: type === "vertical" ? minSizes[i] : undefined, + maxWidth: type === "horizontal" ? maxSizes[i] : undefined, + maxHeight: type === "vertical" ? maxSizes[i] : undefined, + }} + > + {child} +
+ {i !== children.length - 1 && ( +
+
+
+ )} + + )) ?? null} +
+ + ); + }, +); diff --git a/src/components/SplitPane/useSplitPane.ts b/src/components/SplitPane/useSplitPane.ts new file mode 100644 index 0000000..bb8f721 --- /dev/null +++ b/src/components/SplitPane/useSplitPane.ts @@ -0,0 +1,144 @@ +import React, { useCallback, useRef } from "react"; +import { createDragHandler } from "../../utils/interactions/createDragHandler"; +import { px } from "../../utils/px"; + +export function useSplitPane( + type: "horizontal" | "vertical", + sizes: string[], + maxSizes: string[], + minSizes: string[], + onChangeRates?: (rates: string[]) => void, +) { + const rootRef = useRef(null); + const refs = useRef([]); + + const iRef = useRef(0); + const handlePointerDown = createDragHandler({ + onDown: (e) => { + const i = iRef.current; + const root = rootRef.current; + const left = refs.current[i]; + const right = refs.current[i + 1]; + if (root == null || left == null || right == null) { + return; + } + const leftRect = left.getBoundingClientRect(); + const rightRect = right.getBoundingClientRect(); + const startX = e.clientX; + + return { + i, + startX, + startY: e.clientY, + leftRect, + rightRect, + }; + }, + onMove: (e, ctx) => { + if (ctx === undefined) return; + const i = ctx.i; + const diff = + type === "horizontal" ? e.clientX - ctx.startX : e.clientY - ctx.startY; + + const left = refs.current[i]; + const right = refs.current[i + 1]; + + let parentSize = 0; + let leftSize = 0; + let rightSize = 0; + if (left === undefined || right === undefined) return; + if (type === "horizontal") { + parentSize = rootRef.current?.getBoundingClientRect().width ?? 0; + leftSize = ctx.leftRect.width; + rightSize = ctx.rightRect.width; + } else { + parentSize = rootRef.current?.getBoundingClientRect().height ?? 0; + leftSize = ctx.leftRect.height; + rightSize = ctx.rightRect.height; + } + + // left + + let minLeft = -Number.MAX_SAFE_INTEGER; + if (minSizes[i].includes("px")) { + minLeft = parseInt(minSizes[i]); + } else if (minSizes[i].includes("%")) { + minLeft = (parseInt(minSizes[i]) / 100) * parentSize; + } + + let maxLeft = Number.MAX_SAFE_INTEGER; + if (maxSizes[i].includes("px")) { + maxLeft = parseInt(maxSizes[i]); + } else if (maxSizes[i].includes("%")) { + maxLeft = (parseInt(maxSizes[i]) / 100) * parentSize; + } + + const newRates = [...sizes]; + + const newLeft = leftSize + diff; + let newLeftDiff = diff; + if (newLeft < minLeft) { + newLeftDiff = minLeft - leftSize; + newRates[i] = px(leftSize + newLeftDiff); + newRates[i + 1] = px(rightSize - newLeftDiff); + onChangeRates?.(newRates); + return; + } + if (newLeft > maxLeft) { + newLeftDiff = maxLeft - leftSize; + newRates[i] = px(leftSize + newLeftDiff); + newRates[i + 1] = px(rightSize - newLeftDiff); + onChangeRates?.(newRates); + return; + } + + // right + let minRight = -Number.MAX_SAFE_INTEGER; + if (minSizes[i + 1].includes("px")) { + minRight = parseInt(minSizes[i + 1]); + } else if (minSizes[i + 1].includes("%")) { + minRight = (parseInt(minSizes[i + 1]) / 100) * parentSize; + } + + let maxRight = Number.MAX_SAFE_INTEGER; + if (maxSizes[i + 1].includes("px")) { + maxRight = parseInt(maxSizes[i + 1]); + } else if (maxSizes[i + 1].includes("%")) { + maxRight = (parseInt(maxSizes[i + 1]) / 100) * parentSize; + } + + const newRight = rightSize - diff; + let newRightDiff = -diff; + if (newRight < minRight) { + newRightDiff = rightSize - minRight; + newRates[i] = px(leftSize + newRightDiff); + newRates[i + 1] = px(rightSize - newRightDiff); + onChangeRates?.(newRates); + return; + } + if (newRight > maxRight) { + newRightDiff = rightSize - maxRight; + newRates[i] = px(leftSize + newRightDiff); + newRates[i + 1] = px(rightSize - newRightDiff); + onChangeRates?.(newRates); + return; + } + newRates[i] = px(leftSize + diff); + newRates[i + 1] = px(rightSize - diff); + onChangeRates?.(newRates); + }, + }); + const handlePointerDownForRef = useCallback( + (i: number) => (e: React.PointerEvent) => { + iRef.current = i; + handlePointerDown(e); + }, + [handlePointerDown], + ); + + return { + rootRef, + refs, + handlePointerDownForRef, + }; +} diff --git a/src/components/Switch/__snapshots__/index.stories.tsx.snap b/src/components/Switch/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..982fc7d --- /dev/null +++ b/src/components/Switch/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,94 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Form/Switch Basic smoke-test 1`] = ` +
+
+ +
+
+
+ +
+`; + +exports[`Components/Form/Switch Checked smoke-test 1`] = ` +
+
+ +
+
+
+ +
+`; + +exports[`Components/Form/Switch Disabled smoke-test 1`] = ` +
+
+ +
+
+
+ +
+`; + +exports[`Components/Form/Switch Label smoke-test 1`] = ` +
+
+ +
+
+
+ +
+`; diff --git a/src/components/Switch/index.css b/src/components/Switch/index.css new file mode 100644 index 0000000..a115aba --- /dev/null +++ b/src/components/Switch/index.css @@ -0,0 +1,73 @@ +.cmpui_switch__root { + align-items: center; + display: flex; + gap: 8px; +} + +.cmpui_switch__root[aria-disabled="true"] { + cursor: default; + opacity: 0.5; +} + +.cmpui_switch__box { + align-items: center; + display: flex; + height: 24px; + min-width: 40px; + padding: 0 2px; + position: relative; + width: 40px; +} + +.cmpui_switch__input { + background-color: var(--cmpui-bg-color); + border: 1px solid var(--cmpui-border-color); + + appearance: none; + border-radius: 9999px; + box-sizing: border-box; + cursor: pointer; + display: flex; + height: 100%; + margin: 0; + width: 100%; +} + +.cmpui_switch__input:focus-visible { + outline: var(--cmpui-primary-color) solid 1px; + + outline-offset: 1px; +} + +.cmpui_switch__input:checked { + background-color: var(--cmpui-primary-color); +} + +.cmpui_switch__input:disabled { + cursor: default; + opacity: 0.5; +} + +.cmpui_switch__nob { + background-color: gray; + border-radius: 9999px; + display: block; + height: 18px; + left: 5px; + pointer-events: none; + position: absolute; + transition: transform 100ms; + width: 18px; + will-change: transform; +} + +.cmpui_switch__nob[data-checked="true"] { + background-color: white; + transform: translateX(16px); +} + +.cmpui_switch__label { + color: var(--cmpui-text-color); + + font-size: 14px; +} diff --git a/src/components/Switch/index.stories.tsx b/src/components/Switch/index.stories.tsx new file mode 100644 index 0000000..0b667f5 --- /dev/null +++ b/src/components/Switch/index.stories.tsx @@ -0,0 +1,80 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { Switch } from "."; +import { Icon } from "../../__stories__/Icon"; + +const meta: Meta = { + title: "Components/Form/Switch", + component: Switch, +}; + +export default meta; + +type Story = StoryObj; + +export const Basic: Story = { + render: function Render() { + const [checked, setChecked] = useState(false); + return ( + + ); + }, +}; + +export const Label: Story = { + render: function Render() { + const [checked, setChecked] = useState(false); + return ( + + +
Custom Label
+
+ } + id="switch-label" + checked={checked} + onChange={setChecked} + /> + ); + }, +}; + +export const Disabled: Story = { + render: function Render() { + const [checked, setChecked] = useState(false); + return ( + + ); + }, +}; + +export const Checked: Story = { + render: function Render() { + const [checked, setChecked] = useState(true); + return ( + + ); + }, +}; diff --git a/src/components/Switch/index.tsx b/src/components/Switch/index.tsx new file mode 100644 index 0000000..44712ae --- /dev/null +++ b/src/components/Switch/index.tsx @@ -0,0 +1,40 @@ +import { useCallback } from "react"; + +import "./index.css"; + +export type SwitchProps = { + checked?: boolean; + disabled?: boolean; + id?: string; + label?: React.ReactNode; + onChange?: (checked: boolean) => void; +}; + +export function Switch(props: SwitchProps) { + const handleChange = useCallback( + (e: React.ChangeEvent) => { + props.onChange?.(e.target.checked); + }, + [props.onChange], + ); + return ( +
+
+ +
+
+ {props.label && ( + + )} +
+ ); +} diff --git a/src/components/TextArea/__snapshots__/index.stories.tsx.snap b/src/components/TextArea/__snapshots__/index.stories.tsx.snap new file mode 100644 index 0000000..55a6199 --- /dev/null +++ b/src/components/TextArea/__snapshots__/index.stories.tsx.snap @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Components/Form/TextArea Basic smoke-test 1`] = ` +
+ + +
+`; + +exports[`Components/Form/TextArea Disabled smoke-test 1`] = ` +
+ + +
+`; + +exports[`Components/Form/TextArea Label smoke-test 1`] = ` +
+ + +
+`; + +exports[`Components/Form/TextArea Placeholder smoke-test 1`] = ` +
+ + +
+`; diff --git a/src/components/TextArea/index.css b/src/components/TextArea/index.css new file mode 100644 index 0000000..7385447 --- /dev/null +++ b/src/components/TextArea/index.css @@ -0,0 +1,60 @@ +.cmpui_textarea__root { + border: 1px solid var(--cmpui-border-color); + background-color: var(--cmpui-bg-color); + + border-radius: 4px; + box-sizing: border-box; + overflow: hidden; + padding: 0; +} + +.cmpui_textarea__root:focus-within { + outline: var(--cmpui-primary-color) solid 1px; + outline-offset: 1px; +} + +.cmpui_textarea__root:hover { + border: 1px solid var(--cmpui-border-hover-color); +} + +.cmpui_textarea__root[aria-disabled="true"] { + cursor: default; + opacity: 0.5; +} + +.cmpui_textarea__root[aria-disabled="true"]:hover { + border: 1px solid var(--cmpui-border-color); +} + +.cmpui_textarea__textarea { + color: var(--cmpui-text-color); + + background: transparent; + border-radius: 4px; + border: none; + box-sizing: border-box; + font-family: "Roboto", sans-serif; + font-size: 16px; + height: 100%; + outline: none; + overflow: auto; + padding: 8px; + resize: none; + white-space: none; + width: 100%; +} + +.cmpui_textarea__textarea::placeholder { + color: var(--cmpui-text3-color); +} + +.cmpui_textarea__label { + background-color: var(--cmpui-bg-color); + color: var(--cmpui-text2-color); + + font-size: 12px; + line-height: 14px; + padding: 0 4px; + position: absolute; + transform: translate(8px, -8px); +} diff --git a/src/components/TextArea/index.stories.tsx b/src/components/TextArea/index.stories.tsx new file mode 100644 index 0000000..114c441 --- /dev/null +++ b/src/components/TextArea/index.stories.tsx @@ -0,0 +1,62 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { TextArea } from "."; + +const meta: Meta = { + title: "Components/Form/TextArea", + component: TextArea, + args: { + label: "Label", + }, +}; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = { + render: function Render() { + const [value, setValue] = useState(""); + return ( +