@deephaven/file-explorer 0.43.0 → 0.44.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/FileExistsError.js +14 -0
  2. package/dist/FileExistsError.js.map +1 -0
  3. package/dist/FileExplorer.css +26 -0
  4. package/dist/FileExplorer.css.map +1 -0
  5. package/dist/FileExplorer.js +153 -0
  6. package/dist/FileExplorer.js.map +1 -0
  7. package/dist/FileExplorerShortcuts.js +20 -0
  8. package/dist/FileExplorerShortcuts.js.map +1 -0
  9. package/dist/FileExplorerToolbar.css +37 -0
  10. package/dist/FileExplorerToolbar.css.map +1 -0
  11. package/dist/FileExplorerToolbar.js +37 -0
  12. package/dist/FileExplorerToolbar.js.map +1 -0
  13. package/dist/FileList.css +93 -0
  14. package/dist/FileList.css.map +1 -0
  15. package/dist/FileList.js +309 -0
  16. package/dist/FileList.js.map +1 -0
  17. package/dist/FileListContainer.js +167 -0
  18. package/dist/FileListContainer.js.map +1 -0
  19. package/dist/FileListItem.js +118 -0
  20. package/dist/FileListItem.js.map +1 -0
  21. package/dist/FileListItemEditor.css +33 -0
  22. package/dist/FileListItemEditor.css.map +1 -0
  23. package/dist/FileListItemEditor.js +92 -0
  24. package/dist/FileListItemEditor.js.map +1 -0
  25. package/dist/FileListUtils.js +34 -0
  26. package/dist/FileListUtils.js.map +1 -0
  27. package/dist/FileNotFoundError.js +11 -0
  28. package/dist/FileNotFoundError.js.map +1 -0
  29. package/dist/FileStorage.js +12 -0
  30. package/dist/FileStorage.js.map +1 -0
  31. package/dist/FileTestUtils.js +103 -0
  32. package/dist/FileTestUtils.js.map +1 -0
  33. package/dist/FileUtils.js +243 -0
  34. package/dist/FileUtils.js.map +1 -0
  35. package/dist/NewItemModal.css +17 -0
  36. package/dist/NewItemModal.css.map +1 -0
  37. package/dist/NewItemModal.js +467 -0
  38. package/dist/NewItemModal.js.map +1 -0
  39. package/dist/index.js +15 -0
  40. package/dist/index.js.map +1 -0
  41. package/package.json +8 -8
@@ -0,0 +1,118 @@
1
+ import React from 'react';
2
+ import { Tooltip } from '@deephaven/components';
3
+ import { dhPython, vsCode, vsFolder, vsFolderOpened } from '@deephaven/icons';
4
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5
+ import classNames from 'classnames';
6
+ import { isDirectory } from "./FileStorage.js";
7
+ import "./FileList.css";
8
+ import FileUtils, { MIME_TYPE } from "./FileUtils.js";
9
+ import { getPathFromItem } from "./FileListUtils.js";
10
+ /**
11
+ * Get the icon definition for a file or folder item
12
+ * @param item Item to get the icon for
13
+ * @returns Icon definition to pass in the FontAwesomeIcon icon prop
14
+ */
15
+ function getItemIcon(item) {
16
+ if (isDirectory(item)) {
17
+ return item.isExpanded ? vsFolderOpened : vsFolder;
18
+ }
19
+ var mimeType = FileUtils.getMimeType(item.basename);
20
+ switch (mimeType) {
21
+ case MIME_TYPE.PYTHON:
22
+ return dhPython;
23
+ default:
24
+ return vsCode;
25
+ }
26
+ }
27
+ export function FileListItem(props) {
28
+ var _draggedItems$some;
29
+ var {
30
+ children,
31
+ draggedItems,
32
+ isDragInProgress,
33
+ isDropTargetValid,
34
+ isSelected,
35
+ item,
36
+ itemIndex,
37
+ dropTargetItem,
38
+ onDragStart,
39
+ onDragOver,
40
+ onDragEnd,
41
+ onDrop
42
+ } = props;
43
+ var isDragged = (_draggedItems$some = draggedItems === null || draggedItems === void 0 ? void 0 : draggedItems.some(draggedItem => draggedItem.id === item.id)) !== null && _draggedItems$some !== void 0 ? _draggedItems$some : false;
44
+ var itemPath = getPathFromItem(item);
45
+ var dropTargetPath = isDragInProgress && dropTargetItem ? getPathFromItem(dropTargetItem) : null;
46
+ var isExactDropTarget = isDragInProgress && isDropTargetValid && isDirectory(item) && dropTargetPath === itemPath;
47
+ var isInDropTarget = isDragInProgress && isDropTargetValid && dropTargetPath === itemPath;
48
+ var isInvalidDropTarget = isDragInProgress && !isDropTargetValid && dropTargetPath === itemPath;
49
+ var icon = getItemIcon(item);
50
+ var depth = FileUtils.getDepth(item.filename);
51
+ var depthLines = Array(depth).fill(null).map((value, index) =>
52
+ /*#__PURE__*/
53
+ // eslint-disable-next-line react/no-array-index-key
54
+ React.createElement("span", {
55
+ className: "file-list-depth-line",
56
+ key: index
57
+ }));
58
+ return /*#__PURE__*/React.createElement("div", {
59
+ className: classNames('d-flex w-100 align-items-center', 'file-list-item', {
60
+ 'is-dragged': isDragged,
61
+ 'is-exact-drop-target': isExactDropTarget,
62
+ 'is-in-drop-target': isInDropTarget,
63
+ 'is-invalid-drop-target': isInvalidDropTarget,
64
+ 'is-selected': isSelected
65
+ }),
66
+ onDragStart: function (_onDragStart) {
67
+ function onDragStart(_x) {
68
+ return _onDragStart.apply(this, arguments);
69
+ }
70
+ onDragStart.toString = function () {
71
+ return _onDragStart.toString();
72
+ };
73
+ return onDragStart;
74
+ }(e => onDragStart(itemIndex, e)),
75
+ onDragOver: function (_onDragOver) {
76
+ function onDragOver(_x2) {
77
+ return _onDragOver.apply(this, arguments);
78
+ }
79
+ onDragOver.toString = function () {
80
+ return _onDragOver.toString();
81
+ };
82
+ return onDragOver;
83
+ }(e => onDragOver(itemIndex, e)),
84
+ onDragEnd: function (_onDragEnd) {
85
+ function onDragEnd(_x3) {
86
+ return _onDragEnd.apply(this, arguments);
87
+ }
88
+ onDragEnd.toString = function () {
89
+ return _onDragEnd.toString();
90
+ };
91
+ return onDragEnd;
92
+ }(e => onDragEnd(itemIndex, e)),
93
+ onDrop: function (_onDrop) {
94
+ function onDrop(_x4) {
95
+ return _onDrop.apply(this, arguments);
96
+ }
97
+ onDrop.toString = function () {
98
+ return _onDrop.toString();
99
+ };
100
+ return onDrop;
101
+ }(e => onDrop(itemIndex, e)),
102
+ draggable: true,
103
+ role: "presentation",
104
+ "aria-label": item.basename
105
+ }, depthLines, ' ', /*#__PURE__*/React.createElement(FontAwesomeIcon, {
106
+ icon: icon,
107
+ className: "item-icon",
108
+ fixedWidth: true
109
+ }), ' ', /*#__PURE__*/React.createElement("span", {
110
+ className: "truncation-wrapper"
111
+ }, children !== null && children !== void 0 ? children : item.basename, /*#__PURE__*/React.createElement(Tooltip, {
112
+ options: {
113
+ placement: 'left'
114
+ }
115
+ }, children !== null && children !== void 0 ? children : item.basename)));
116
+ }
117
+ export default FileListItem;
118
+ //# sourceMappingURL=FileListItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileListItem.js","names":["React","Tooltip","dhPython","vsCode","vsFolder","vsFolderOpened","FontAwesomeIcon","classNames","isDirectory","FileUtils","MIME_TYPE","getPathFromItem","getItemIcon","item","isExpanded","mimeType","getMimeType","basename","PYTHON","FileListItem","props","children","draggedItems","isDragInProgress","isDropTargetValid","isSelected","itemIndex","dropTargetItem","onDragStart","onDragOver","onDragEnd","onDrop","isDragged","some","draggedItem","id","itemPath","dropTargetPath","isExactDropTarget","isInDropTarget","isInvalidDropTarget","icon","depth","getDepth","filename","depthLines","Array","fill","map","value","index","e","placement"],"sources":["../src/FileListItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Tooltip, RenderItemProps } from '@deephaven/components';\nimport { dhPython, vsCode, vsFolder, vsFolderOpened } from '@deephaven/icons';\nimport { IconDefinition } from '@fortawesome/fontawesome-svg-core';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport classNames from 'classnames';\nimport { FileStorageItem, isDirectory } from './FileStorage';\nimport './FileList.scss';\nimport FileUtils, { MIME_TYPE } from './FileUtils';\nimport { getPathFromItem } from './FileListUtils';\n\n/**\n * Get the icon definition for a file or folder item\n * @param item Item to get the icon for\n * @returns Icon definition to pass in the FontAwesomeIcon icon prop\n */\nfunction getItemIcon(item: FileStorageItem): IconDefinition {\n if (isDirectory(item)) {\n return item.isExpanded ? vsFolderOpened : vsFolder;\n }\n const mimeType = FileUtils.getMimeType(item.basename);\n switch (mimeType) {\n case MIME_TYPE.PYTHON:\n return dhPython;\n default:\n return vsCode;\n }\n}\n\nexport type FileListRenderItemProps = RenderItemProps<FileStorageItem> & {\n children?: JSX.Element;\n dropTargetItem?: FileStorageItem;\n draggedItems?: FileStorageItem[];\n isDragInProgress: boolean;\n isDropTargetValid: boolean;\n\n onDragStart(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDragOver(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDragEnd(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDrop(index: number, e: React.DragEvent<HTMLDivElement>): void;\n};\n\nexport function FileListItem(props: FileListRenderItemProps): JSX.Element {\n const {\n children,\n draggedItems,\n isDragInProgress,\n isDropTargetValid,\n isSelected,\n item,\n itemIndex,\n dropTargetItem,\n onDragStart,\n onDragOver,\n onDragEnd,\n onDrop,\n } = props;\n\n const isDragged =\n draggedItems?.some(draggedItem => draggedItem.id === item.id) ?? false;\n const itemPath = getPathFromItem(item);\n const dropTargetPath =\n isDragInProgress && dropTargetItem ? getPathFromItem(dropTargetItem) : null;\n\n const isExactDropTarget =\n isDragInProgress &&\n isDropTargetValid &&\n isDirectory(item) &&\n dropTargetPath === itemPath;\n const isInDropTarget =\n isDragInProgress && isDropTargetValid && dropTargetPath === itemPath;\n const isInvalidDropTarget =\n isDragInProgress && !isDropTargetValid && dropTargetPath === itemPath;\n\n const icon = getItemIcon(item);\n const depth = FileUtils.getDepth(item.filename);\n const depthLines = Array(depth)\n .fill(null)\n .map((value, index) => (\n // eslint-disable-next-line react/no-array-index-key\n <span className=\"file-list-depth-line\" key={index} />\n ));\n\n return (\n <div\n className={classNames(\n 'd-flex w-100 align-items-center',\n 'file-list-item',\n {\n 'is-dragged': isDragged,\n 'is-exact-drop-target': isExactDropTarget,\n 'is-in-drop-target': isInDropTarget,\n 'is-invalid-drop-target': isInvalidDropTarget,\n 'is-selected': isSelected,\n }\n )}\n onDragStart={e => onDragStart(itemIndex, e)}\n onDragOver={e => onDragOver(itemIndex, e)}\n onDragEnd={e => onDragEnd(itemIndex, e)}\n onDrop={e => onDrop(itemIndex, e)}\n draggable\n role=\"presentation\"\n aria-label={item.basename}\n >\n {depthLines}{' '}\n <FontAwesomeIcon icon={icon} className=\"item-icon\" fixedWidth />{' '}\n <span className=\"truncation-wrapper\">\n {children ?? item.basename}\n <Tooltip\n options={{\n placement: 'left',\n }}\n >\n {children ?? item.basename}\n </Tooltip>\n </span>\n </div>\n );\n}\n\nexport default FileListItem;\n"],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /* stylelint-disable scss/at-import-no-partial-leading-underscore */
2
+ .file-list-item-editor {
3
+ z-index: 1;
4
+ width: 100%;
5
+ display: inline-block;
6
+ position: relative;
7
+ }
8
+ .file-list-item-editor .file-list-item-editor-input {
9
+ padding: 0;
10
+ border: none;
11
+ border-radius: 0;
12
+ height: 26px;
13
+ line-height: 26px;
14
+ }
15
+ .file-list-item-editor .file-list-item-editor-input.is-invalid {
16
+ border-bottom-left-radius: 0;
17
+ border-bottom-right-radius: 0;
18
+ padding-right: 2rem;
19
+ }
20
+ .file-list-item-editor .invalid-feedback {
21
+ color: #f0f0ee;
22
+ background-color: #f95d84;
23
+ font-size: 0.9rem;
24
+ margin-top: 0;
25
+ padding: 0.25rem 0.5rem;
26
+ border-bottom-left-radius: 4px;
27
+ border-bottom-right-radius: 4px;
28
+ position: absolute;
29
+ top: 100%;
30
+ left: 0;
31
+ }
32
+
33
+ /*# sourceMappingURL=FileListItemEditor.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sourceRoot":"","sources":["../../../node_modules/@deephaven/components/scss/custom.scss","../src/FileListItemEditor.scss","../../../node_modules/@deephaven/components/scss/bootstrap_overrides.scss"],"names":[],"mappings":"AAAA;ACIA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,QAZoB;EAapB,aAboB;;AAepB;EACE;EACA;EAEA;;AAGJ;EACE,OCZa;EDab,kBCvBE;EDwBF;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"FileListItemEditor.css","sourcesContent":["/* stylelint-disable scss/at-import-no-partial-leading-underscore */\n// Consumers should be able to resolve bootstrap/ to node_modules/bootstrap\n\n//Make bootstrap functions available for use in overrides\n@import 'bootstrap/scss/_functions.scss';\n@import './bootstrap_overrides.scss';\n\n//_variable imports come after bootstrap default overrides,\n// makes all other variables and mixins from bootstrap available\n/// with just importing customer.scss\n@import 'bootstrap/scss/_variables.scss';\n@import 'bootstrap/scss/_mixins.scss';\n\n//New variables come after imports\n@import './new_variables.scss';\n","@import '@deephaven/components/scss/custom.scss';\n\n$item-list-item-height: 26px;\n\n.file-list-item-editor {\n z-index: 1;\n width: 100%;\n display: inline-block;\n position: relative;\n\n .file-list-item-editor-input {\n padding: 0;\n border: none;\n border-radius: 0;\n height: $item-list-item-height;\n line-height: $item-list-item-height;\n\n &.is-invalid {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n // Don't overlap the error icon\n padding-right: 2rem;\n }\n }\n .invalid-feedback {\n color: $foreground;\n background-color: $danger;\n font-size: 0.9rem;\n margin-top: 0;\n padding: $spacer-1 $spacer-2;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n position: absolute;\n top: 100%;\n left: 0;\n }\n}\n","// Styling overrides for bootstrap\n\n// Override / set color variables\n$red: #f95d84;\n$orange: #f37e3f;\n$yellow: #fcd65b;\n$green: #9edc6f;\n$blue: #76d9e4;\n$purple: #aa9af4;\n\n//Define some UI colors\n$interfacegray: #2d2a2e;\n$interfaceblue: #4878ea;\n$interfacewhite: #f0f0ee; //same as gray-200\n$interfaceblack: #1a171a;\n\n//Define our Gray scale\n$white: $interfacewhite;\n$gray-100: #fcfcfa;\n$gray-200: $interfacewhite;\n$gray-300: #c0bfbf;\n$gray-400: #929192;\n$gray-500: #5b5a5c;\n$gray-600: #555356;\n$gray-700: #403e41;\n$gray-800: #373438;\n$gray-850: #322f33;\n$gray-900: #211f22;\n$black: $interfaceblack;\n$content-bg: $interfacegray;\n$background: $interfaceblack;\n$foreground: $interfacewhite;\n\n//Load colors into map\n$colors: ();\n$colors: map-merge(\n (\n 'red': $red,\n 'orange': $orange,\n 'yellow': $yellow,\n 'green': $green,\n 'blue': $blue,\n 'purple': $purple,\n 'white': $white,\n 'black': $black,\n ),\n $colors\n);\n\n//Set default colors\n$body-bg: $black;\n$body-color: $interfacewhite;\n\n// Set brand colors\n$primary: $interfaceblue;\n$primary-hover: darken($primary, 8%);\n$primary-dark: mix($primary, $content-bg, 25%);\n$primary-light: scale-color($primary, $lightness: -25%);\n$secondary: $gray-500;\n$secondary-hover: darken($secondary, 8%);\n$success: $green;\n$info: $yellow;\n$warning: $orange;\n$danger: $red;\n$danger-hover: darken($danger, 8%);\n$light: $gray-100;\n$mid: $gray-400; //Added a mid color, useful for input styling\n$dark: $gray-800;\n$green-dark: scale-color($green, $lightness: -45%, $saturation: -10%);\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n 'primary': $primary,\n 'primary-hover': $primary-hover,\n 'primary-light': $primary-light,\n 'primary-dark': $primary-dark,\n 'secondary': $secondary,\n 'success': $success,\n 'info': $info,\n 'warning': $warning,\n 'danger': $danger,\n 'light': $light,\n 'dark': $dark,\n 'mid': $mid,\n 'content-bg': $interfacegray,\n 'background': $interfaceblack,\n 'foreground': $interfacewhite,\n ),\n $theme-colors\n);\n\n$component-active-bg: $primary;\n$theme-color-interval: 9%;\n$yiq-contrasted-threshold: 180;\n\n// Override fonts\n$font-family-sans-serif: 'Fira Sans', -apple-system, blinkmacsystemfont,\n 'Segoe UI', 'Roboto', 'Helvetica Neue', arial, sans-serif; //fira sans then native system ui fallbacks\n$font-family-monospace: 'Fira Mono', menlo, monaco, consolas, 'Liberation Mono',\n 'Courier New', monospace;\n$font-family-base: $font-family-sans-serif;\n\n$headings-font-weight: 400;\n\n//Text overides\n$text-muted: $gray-400;\n\n//Style Selection highlight color\n//so browsers add alpha to your color by default, ignoring opacity 1\n//by setting rgba with 0.99 it tricks browser into thinking there is alpha applied\n$text-select-color: $primary-hover;\n$text-select-color-editor: lighten(\n $gray-700,\n 15%\n); //we lighten it abit to account for that 0.01 loss, and because it needs some anyways.\n\n//Grid variables, same value as default just making easily accessible\n$grid-gutter-width: 30px;\n\n//Visual Overrides\n$border-radius: 4px;\n$box-shadow: 0 0.1rem 1rem rgba($black, 45%); //because our UI is so dark, we need darker default shadows\n$box-shadow-900: 0 0.1rem 1rem rgba(0, 0, 0, 45%); //darkest shadow for $black popups over $black UI\n\n//Override Btn\n$btn-border-radius: 4rem;\n$btn-padding-x: 1.5rem;\n$btn-transition: color 0.12s ease-in-out, background-color 0.12s ease-in-out,\n border-color 0.12s ease-in-out, box-shadow 0.12s ease-in-out; //default 0.15 is too long\n$btn-border-width: 2px;\n\n//Override Inputs\n$input-bg: $gray-600;\n$input-disabled-bg: $gray-800;\n$input-color: $foreground;\n$input-border-color: $gray-400;\n$input-placeholder-color: $gray-400;\n$input-focus-border-color: rgba($primary, 85%);\n\n$input-btn-focus-width: 0.2rem;\n$input-btn-focus-color: rgba($component-active-bg, 35%);\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color;\n\n//checkbox\n$custom-control-indicator-bg: $gray-600;\n$custom-control-indicator-bg-size: 75% 75%;\n$custom-control-indicator-disabled-bg: $gray-800;\n$custom-control-indicator-checked-disabled-bg: $gray-800;\n$custom-control-label-disabled-color: $gray-400;\n\n//Custom Select\n$custom-select-indicator-color: $gray-400;\n$custom-select-bg-size: 16px 16px;\n//dhSort icon encoded\n$custom-select-indicator: str-replace(\n url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M4 7l-.4-.8 4-3.7h.8l4 3.7-.4.8H4zm0 2l-.4.8 4 3.7h.8l4-3.7L12 9H4z'/%3E%3C/svg%3E\"),\n '#',\n '%23'\n);\n$custom-select-focus-box-shadow: $input-btn-focus-box-shadow;\n$custom-select-disabled-color: darken($gray-400, 5%);\n$custom-select-disabled-bg: $gray-800;\n\n//modal\n$modal-content-bg: $gray-200;\n$modal-content-border-width: 0;\n$modal-md: 550px;\n\n// Toast notification\n$toast-bg: $primary-dark;\n$toast-color: $foreground;\n$toast-error-bg: mix($danger, $content-bg, 15%);\n$toast-error-color: $foreground;\n\n//tooltips\n$tooltip-bg: $gray-700;\n$tooltip-color: $foreground;\n$tooltip-box-shadow: 0 0.1rem 1.5rem 0.1rem rgba($black, 80%);\n\n//drowdowns\n$dropdown-bg: $gray-600;\n$dropdown-link-color: $foreground;\n$dropdown-link-hover-color: $foreground;\n$dropdown-link-hover-bg: $primary;\n$dropdown-divider-bg: $gray-700;\n\n//context menus\n$contextmenu-bg: $gray-600;\n$contextmenu-color: $foreground;\n$contextmenu-disabled-color: $text-muted;\n$contextmenu-keyboard-selected-bg: rgba($primary, 50%);\n$contextmenu-selected-bg: $primary;\n$contextmenu-selected-color: $foreground;\n\n//links\n$link-color: $gray-400;\n$link-hover-color: $foreground;\n\n//progress-bar\n$progress-bg: $gray-600;\n$progress-border-radius: 1rem;\n\n// Set global options\n$enable-shadows: false;\n$enable-gradients: false;\n$enable-print-styles: false; //I don't think anyone should expect to \"print\" this app.\n\n// Transition times\n$transition: 0.15s;\n$transition-mid: 0.2s;\n$transition-long: 0.3s;\n$transition-slow: 0.6s;\n\n//form-validation icon, uses vsWarning icon encoded here as svg\n$form-feedback-icon-invalid-color: theme-color('danger');\n$form-feedback-icon-invalid: str-replace(\n url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cg fill='none'%3E%3Cg fill='#{$form-feedback-icon-invalid-color}'%3E%3Cpath d='M7.56 1h.88l6.54 12.26-.44.74H1.44L1 13.26 7.56 1zM8 2.28 2.28 13H13.7L8 2.28zM8.625 12v-1h-1.25v1h1.25zm-1.25-2V6h1.25v4h-1.25z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E \"),\n '#',\n '%23'\n);\n"]}
@@ -0,0 +1,92 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import classNames from 'classnames';
3
+ import Log from '@deephaven/log';
4
+ import { PromiseUtils } from '@deephaven/utils';
5
+ import "./FileListItemEditor.css";
6
+ var log = Log.module('FileListItemEditor');
7
+ var DEFAULT_VALIDATE = () => Promise.resolve();
8
+ export function FileListItemEditor(_ref) {
9
+ var {
10
+ item,
11
+ onCancel,
12
+ onSubmit,
13
+ validate = DEFAULT_VALIDATE
14
+ } = _ref;
15
+ var input = useRef(null);
16
+ var [value, setValue] = useState(item.basename);
17
+ var [validationError, setValidationError] = useState();
18
+ var [validationPromise, setValidationPromise] = useState(Promise.resolve());
19
+ var focus = useCallback(() => {
20
+ var _input$current;
21
+ (_input$current = input.current) === null || _input$current === void 0 ? void 0 : _input$current.focus();
22
+ // Select the proper range based on the type...
23
+ }, [input]);
24
+ var stopPropagation = useCallback(e => e.stopPropagation(), []);
25
+ var validateAndSubmit = useCallback(() => {
26
+ validationPromise.then(() => {
27
+ onSubmit(value);
28
+ }).catch(e => log.info('Unable to validate name', e));
29
+ }, [onSubmit, value, validationPromise]);
30
+ useEffect(function validateValueAndSetPromise() {
31
+ var validatePromise = PromiseUtils.makeCancelable(validate(value));
32
+ validatePromise.then(() => setValidationError(undefined)).catch(e => {
33
+ if (!PromiseUtils.isCanceled(e)) {
34
+ setValidationError(e);
35
+ }
36
+ });
37
+ setValidationPromise(validatePromise);
38
+ return () => validatePromise.cancel();
39
+ }, [validate, value]);
40
+ useEffect(function selectRange() {
41
+ focus();
42
+ }, [focus]);
43
+ var handleBlur = useCallback(() => {
44
+ log.debug2('handleBlur');
45
+ validateAndSubmit();
46
+ }, [validateAndSubmit]);
47
+ var handleChange = useCallback(e => {
48
+ var {
49
+ value: newValue
50
+ } = e.target;
51
+ setValue(newValue);
52
+ }, []);
53
+ var handleKeyDown = useCallback(e => {
54
+ e.stopPropagation();
55
+ var {
56
+ key
57
+ } = e;
58
+ switch (key) {
59
+ case 'Enter':
60
+ {
61
+ validateAndSubmit();
62
+ break;
63
+ }
64
+ case 'Escape':
65
+ {
66
+ onCancel();
67
+ break;
68
+ }
69
+ default:
70
+ }
71
+ }, [onCancel, validateAndSubmit]);
72
+ return /*#__PURE__*/React.createElement("div", {
73
+ className: "file-list-item-editor"
74
+ }, /*#__PURE__*/React.createElement("input", {
75
+ type: "text",
76
+ className: classNames('form-control file-list-item-editor-input', {
77
+ 'is-invalid': validationError
78
+ }),
79
+ value: value,
80
+ ref: input,
81
+ onBlur: handleBlur,
82
+ onKeyDown: handleKeyDown,
83
+ onChange: handleChange,
84
+ onClick: stopPropagation,
85
+ onDoubleClick: stopPropagation,
86
+ onMouseDown: stopPropagation
87
+ }), validationError && /*#__PURE__*/React.createElement("div", {
88
+ className: "invalid-feedback"
89
+ }, "".concat(validationError)));
90
+ }
91
+ export default FileListItemEditor;
92
+ //# sourceMappingURL=FileListItemEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileListItemEditor.js","names":["React","useCallback","useEffect","useRef","useState","classNames","Log","PromiseUtils","log","module","DEFAULT_VALIDATE","Promise","resolve","FileListItemEditor","item","onCancel","onSubmit","validate","input","value","setValue","basename","validationError","setValidationError","validationPromise","setValidationPromise","focus","current","stopPropagation","e","validateAndSubmit","then","catch","info","validateValueAndSetPromise","validatePromise","makeCancelable","undefined","isCanceled","cancel","selectRange","handleBlur","debug2","handleChange","newValue","target","handleKeyDown","key"],"sources":["../src/FileListItemEditor.tsx"],"sourcesContent":["import React, {\n ChangeEvent,\n KeyboardEvent,\n MouseEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport { PromiseUtils } from '@deephaven/utils';\nimport './FileListItemEditor.scss';\nimport { FileStorageItem } from './FileStorage';\n\nconst log = Log.module('FileListItemEditor');\n\nexport interface FileListItemEditorProps {\n item: FileStorageItem;\n onCancel: () => void;\n onSubmit: (newName: string) => void;\n validate?: (newName: string) => Promise<void>;\n}\n\nconst DEFAULT_VALIDATE = () => Promise.resolve();\n\nexport function FileListItemEditor({\n item,\n onCancel,\n onSubmit,\n validate = DEFAULT_VALIDATE,\n}: FileListItemEditorProps): JSX.Element {\n const input = useRef<HTMLInputElement>(null);\n const [value, setValue] = useState(item.basename);\n const [validationError, setValidationError] = useState<Error>();\n const [validationPromise, setValidationPromise] = useState<Promise<void>>(\n Promise.resolve()\n );\n\n const focus = useCallback(() => {\n input.current?.focus();\n // Select the proper range based on the type...\n }, [input]);\n\n const stopPropagation = useCallback(\n (e: MouseEvent) => e.stopPropagation(),\n []\n );\n\n const validateAndSubmit = useCallback(() => {\n validationPromise\n .then(() => {\n onSubmit(value);\n })\n .catch(e => log.info('Unable to validate name', e));\n }, [onSubmit, value, validationPromise]);\n\n useEffect(\n function validateValueAndSetPromise() {\n const validatePromise = PromiseUtils.makeCancelable(validate(value));\n validatePromise\n .then(() => setValidationError(undefined))\n .catch(e => {\n if (!PromiseUtils.isCanceled(e)) {\n setValidationError(e);\n }\n });\n setValidationPromise(validatePromise);\n return () => validatePromise.cancel();\n },\n [validate, value]\n );\n\n useEffect(\n function selectRange() {\n focus();\n },\n [focus]\n );\n\n const handleBlur = useCallback(() => {\n log.debug2('handleBlur');\n validateAndSubmit();\n }, [validateAndSubmit]);\n\n const handleChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = e.target;\n setValue(newValue);\n }, []);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n e.stopPropagation();\n\n const { key } = e;\n switch (key) {\n case 'Enter': {\n validateAndSubmit();\n break;\n }\n case 'Escape': {\n onCancel();\n break;\n }\n default:\n }\n },\n [onCancel, validateAndSubmit]\n );\n\n return (\n <div className=\"file-list-item-editor\">\n <input\n type=\"text\"\n className={classNames('form-control file-list-item-editor-input', {\n 'is-invalid': validationError,\n })}\n value={value}\n ref={input}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onChange={handleChange}\n onClick={stopPropagation}\n onDoubleClick={stopPropagation}\n onMouseDown={stopPropagation}\n />\n\n {validationError && (\n <div className=\"invalid-feedback\">{`${validationError}`}</div>\n )}\n </div>\n );\n}\n\nexport default FileListItemEditor;\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { isDirectory } from "./FileStorage.js";
2
+ import FileUtils from "./FileUtils.js";
3
+ export var DEFAULT_ROW_HEIGHT = 26;
4
+ export function getPathFromItem(file) {
5
+ return isDirectory(file) ? FileUtils.makePath(file.filename) : FileUtils.getPath(file.filename);
6
+ }
7
+
8
+ /**
9
+ * Get the move operation for the current selection and the given target. Throws if the operation is invalid.
10
+ */
11
+ export function getMoveOperation(draggedItems, targetItem) {
12
+ if (draggedItems.length === 0 || targetItem == null) {
13
+ throw new Error('No items to move');
14
+ }
15
+ var targetPath = getPathFromItem(targetItem);
16
+ if (draggedItems.some(_ref => {
17
+ var {
18
+ filename
19
+ } = _ref;
20
+ return FileUtils.getPath(filename) === targetPath;
21
+ })) {
22
+ // Cannot drop if target is one of the dragged items is already in the target folder
23
+ throw new Error('File already in the destination folder');
24
+ }
25
+ if (draggedItems.some(item => isDirectory(item) && targetPath.startsWith(FileUtils.makePath(item.filename)))) {
26
+ // Cannot drop if target is a child of one of the directories being moved
27
+ throw new Error('Destination folder cannot be a child of a dragged folder');
28
+ }
29
+ return {
30
+ files: draggedItems,
31
+ targetPath
32
+ };
33
+ }
34
+ //# sourceMappingURL=FileListUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileListUtils.js","names":["isDirectory","FileUtils","DEFAULT_ROW_HEIGHT","getPathFromItem","file","makePath","filename","getPath","getMoveOperation","draggedItems","targetItem","length","Error","targetPath","some","item","startsWith","files"],"sources":["../src/FileListUtils.ts"],"sourcesContent":["import { isDirectory } from './FileStorage';\nimport type { FileStorageItem } from './FileStorage';\nimport FileUtils from './FileUtils';\n\nexport const DEFAULT_ROW_HEIGHT = 26;\n\nexport function getPathFromItem(file: FileStorageItem): string {\n return isDirectory(file)\n ? FileUtils.makePath(file.filename)\n : FileUtils.getPath(file.filename);\n}\n\n/**\n * Get the move operation for the current selection and the given target. Throws if the operation is invalid.\n */\nexport function getMoveOperation(\n draggedItems: FileStorageItem[],\n targetItem: FileStorageItem\n): { files: FileStorageItem[]; targetPath: string } {\n if (draggedItems.length === 0 || targetItem == null) {\n throw new Error('No items to move');\n }\n\n const targetPath = getPathFromItem(targetItem);\n if (\n draggedItems.some(\n ({ filename }) => FileUtils.getPath(filename) === targetPath\n )\n ) {\n // Cannot drop if target is one of the dragged items is already in the target folder\n throw new Error('File already in the destination folder');\n }\n if (\n draggedItems.some(\n item =>\n isDirectory(item) &&\n targetPath.startsWith(FileUtils.makePath(item.filename))\n )\n ) {\n // Cannot drop if target is a child of one of the directories being moved\n throw new Error('Destination folder cannot be a child of a dragged folder');\n }\n return { files: draggedItems, targetPath };\n}\n"],"mappings":"SAASA,WAAW;AAAA,OAEbC,SAAS;AAEhB,OAAO,IAAMC,kBAAkB,GAAG,EAAE;AAEpC,OAAO,SAASC,eAAe,CAACC,IAAqB,EAAU;EAC7D,OAAOJ,WAAW,CAACI,IAAI,CAAC,GACpBH,SAAS,CAACI,QAAQ,CAACD,IAAI,CAACE,QAAQ,CAAC,GACjCL,SAAS,CAACM,OAAO,CAACH,IAAI,CAACE,QAAQ,CAAC;AACtC;;AAEA;AACA;AACA;AACA,OAAO,SAASE,gBAAgB,CAC9BC,YAA+B,EAC/BC,UAA2B,EACuB;EAClD,IAAID,YAAY,CAACE,MAAM,KAAK,CAAC,IAAID,UAAU,IAAI,IAAI,EAAE;IACnD,MAAM,IAAIE,KAAK,CAAC,kBAAkB,CAAC;EACrC;EAEA,IAAMC,UAAU,GAAGV,eAAe,CAACO,UAAU,CAAC;EAC9C,IACED,YAAY,CAACK,IAAI,CACf;IAAA,IAAC;MAAER;IAAS,CAAC;IAAA,OAAKL,SAAS,CAACM,OAAO,CAACD,QAAQ,CAAC,KAAKO,UAAU;EAAA,EAC7D,EACD;IACA;IACA,MAAM,IAAID,KAAK,CAAC,wCAAwC,CAAC;EAC3D;EACA,IACEH,YAAY,CAACK,IAAI,CACfC,IAAI,IACFf,WAAW,CAACe,IAAI,CAAC,IACjBF,UAAU,CAACG,UAAU,CAACf,SAAS,CAACI,QAAQ,CAACU,IAAI,CAACT,QAAQ,CAAC,CAAC,CAC3D,EACD;IACA;IACA,MAAM,IAAIM,KAAK,CAAC,0DAA0D,CAAC;EAC7E;EACA,OAAO;IAAEK,KAAK,EAAER,YAAY;IAAEI;EAAW,CAAC;AAC5C"}
@@ -0,0 +1,11 @@
1
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
+ class FileNotFoundError extends Error {
5
+ constructor() {
6
+ super('No file exists at the path specified');
7
+ _defineProperty(this, "isFileNotFound", true);
8
+ }
9
+ }
10
+ export default FileNotFoundError;
11
+ //# sourceMappingURL=FileNotFoundError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileNotFoundError.js","names":["FileNotFoundError","Error","constructor"],"sources":["../src/FileNotFoundError.ts"],"sourcesContent":["class FileNotFoundError extends Error {\n constructor() {\n super('No file exists at the path specified');\n }\n\n isFileNotFound = true;\n}\n\nexport default FileNotFoundError;\n"],"mappings":";;;AAAA,MAAMA,iBAAiB,SAASC,KAAK,CAAC;EACpCC,WAAW,GAAG;IACZ,KAAK,CAAC,sCAAsC,CAAC;IAAC,wCAG/B,IAAI;EAFrB;AAGF;AAEA,eAAeF,iBAAiB"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Basic metadata of the file
3
+ */
4
+
5
+ export function isDirectory(file) {
6
+ return file.type === 'directory';
7
+ }
8
+
9
+ /**
10
+ * A file including it's contents
11
+ */
12
+ //# sourceMappingURL=FileStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileStorage.js","names":["isDirectory","file","type"],"sources":["../src/FileStorage.ts"],"sourcesContent":["import { StorageTable, StorageItem } from '@deephaven/storage';\n\n/**\n * Basic metadata of the file\n */\nexport interface FileMetadata {\n /** Full path of the file */\n filename: string;\n\n /** Just the file name part of the file (no path) */\n basename: string;\n}\n\nexport type FileType = 'file' | 'directory';\n\nexport interface FileStorageItem extends StorageItem, FileMetadata {\n type: FileType;\n}\n\nexport interface DirectoryStorageItem extends FileStorageItem {\n type: 'directory';\n isExpanded: boolean;\n}\n\nexport function isDirectory(\n file: FileStorageItem\n): file is DirectoryStorageItem {\n return file.type === 'directory';\n}\n\n/**\n * A file including it's contents\n */\nexport interface File extends FileMetadata {\n content: string;\n}\n\nexport interface FileStorageTable extends StorageTable<FileStorageItem> {\n setSearch(search: string): void;\n\n /**\n * @param path The path to expand\n * @param expanded What expanded state to set\n */\n setExpanded(path: string, expanded: boolean): void;\n\n /**\n * Collapses all directories\n */\n collapseAll(): void;\n}\n\n/**\n * FileStorage abstraction. Has methods for managing files, and for retrieving a table to browse files.\n */\nexport interface FileStorage {\n /**\n * Retrieve a table to view the file list\n */\n getTable(): Promise<FileStorageTable>;\n\n /**\n * Save a file\n * @param file The file to save\n */\n saveFile(file: File): Promise<File>;\n\n /**\n * Load the contents of a file\n * @param name The file to load, including the full path\n */\n loadFile(name: string): Promise<File>;\n\n /**\n * Delete a file\n * @param name The full name of the file to delete\n */\n deleteFile(name: string): Promise<void>;\n\n /**\n * Move a file to a new location\n * @param name Source file name\n * @param newName The new file name, including path\n */\n moveFile(name: string, newName: string): Promise<void>;\n\n /**\n * Get the info for the file at the specified path.\n * If the file does not exists, rejects with a FileNotFoundError\n * @param name The file name to check, including path\n * @returns The FileStorageItem for the path specified, or reject with a FileNotFoundError if it does not exist.\n */\n info(name: string): Promise<FileStorageItem>;\n\n /**\n * Create the directory at the given path\n * @param name The full directory path\n */\n createDirectory(name: string): Promise<FileStorageItem>;\n}\n\nexport default FileStorage;\n"],"mappings":"AAEA;AACA;AACA;;AAoBA,OAAO,SAASA,WAAW,CACzBC,IAAqB,EACS;EAC9B,OAAOA,IAAI,CAACC,IAAI,KAAK,WAAW;AAClC;;AAEA;AACA;AACA"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Make a file name with prefix 'testfile'
3
+ * @param index Number of the file
4
+ * @returns A string with prefix 'testfile' followed by index
5
+ */
6
+ export function makeFileName() {
7
+ var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
8
+ return "testfile".concat(index);
9
+ }
10
+
11
+ /**
12
+ * Make a directory name with prefix 'testdir'
13
+ * @param index Number of the directory
14
+ * @returns A string with prefix 'testdir' followed by index
15
+ */
16
+ export function makeDirName() {
17
+ var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
18
+ return "testdir".concat(index);
19
+ }
20
+
21
+ /**
22
+ * Make a file object
23
+ * @param basename The basename of the file
24
+ * @param path The path of the file
25
+ * @returns A FileStorageItem object
26
+ */
27
+ export function makeFile(basename) {
28
+ var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '/';
29
+ var filename = "".concat(path).concat(basename);
30
+ return {
31
+ basename,
32
+ filename,
33
+ type: 'file',
34
+ id: filename
35
+ };
36
+ }
37
+
38
+ /**
39
+ * Make files from 0 to and not including count
40
+ * @param count The number of files to create (0 to count - 1). Defaults to 5
41
+ * @returns An array of FileStorageItems
42
+ */
43
+ export function makeFiles() {
44
+ var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 5;
45
+ var result = [];
46
+ for (var i = 0; i < count; i += 1) {
47
+ result.push(makeFile(makeFileName(i)));
48
+ }
49
+ return result;
50
+ }
51
+
52
+ /**
53
+ * Make a directory object
54
+ * @param basename The basename of the directory
55
+ * @param path The path of the directory
56
+ * @returns A DirectoryStorageItem object
57
+ */
58
+ export function makeDirectory(basename) {
59
+ var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '/';
60
+ var filename = "".concat(path).concat(basename);
61
+ return {
62
+ basename,
63
+ filename,
64
+ type: 'directory',
65
+ id: filename,
66
+ isExpanded: false
67
+ };
68
+ }
69
+
70
+ /**
71
+ * Make directories from 0 to and not including count
72
+ * @param count The number of directories to create (0 to count - 1). Defaults to 5
73
+ * @returns An array of DirectoryStorageItems
74
+ */
75
+ export function makeDirectories() {
76
+ var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 5;
77
+ var result = [];
78
+ for (var i = 0; i < count; i += 1) {
79
+ result.push(makeDirectory("testdir".concat(i)));
80
+ }
81
+ return result;
82
+ }
83
+
84
+ /**
85
+ * Make a nested file
86
+ * @param directories The nested directories in order
87
+ * @param fileNum Number of the file
88
+ * @returns A FileStorageItem
89
+ */
90
+ export function makeNested(directories, fileNum) {
91
+ var basename = "/".concat(directories.map(directory => makeDirName(directory)).join('/'), "/");
92
+ return makeFile(makeFileName(fileNum), basename);
93
+ }
94
+ export default {
95
+ makeFileName,
96
+ makeFile,
97
+ makeFiles,
98
+ makeDirName,
99
+ makeDirectory,
100
+ makeDirectories,
101
+ makeNested
102
+ };
103
+ //# sourceMappingURL=FileTestUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileTestUtils.js","names":["makeFileName","index","makeDirName","makeFile","basename","path","filename","type","id","makeFiles","count","result","i","push","makeDirectory","isExpanded","makeDirectories","makeNested","directories","fileNum","map","directory","join"],"sources":["../src/FileTestUtils.ts"],"sourcesContent":["import { DirectoryStorageItem, FileStorageItem } from './FileStorage';\n\n/**\n * Make a file name with prefix 'testfile'\n * @param index Number of the file\n * @returns A string with prefix 'testfile' followed by index\n */\nexport function makeFileName(index = 0): string {\n return `testfile${index}`;\n}\n\n/**\n * Make a directory name with prefix 'testdir'\n * @param index Number of the directory\n * @returns A string with prefix 'testdir' followed by index\n */\nexport function makeDirName(index = 0): string {\n return `testdir${index}`;\n}\n\n/**\n * Make a file object\n * @param basename The basename of the file\n * @param path The path of the file\n * @returns A FileStorageItem object\n */\nexport function makeFile(basename: string, path = '/'): FileStorageItem {\n const filename = `${path}${basename}`;\n return {\n basename,\n filename,\n type: 'file',\n id: filename,\n };\n}\n\n/**\n * Make files from 0 to and not including count\n * @param count The number of files to create (0 to count - 1). Defaults to 5\n * @returns An array of FileStorageItems\n */\nexport function makeFiles(count = 5) {\n const result: FileStorageItem[] = [];\n for (let i = 0; i < count; i += 1) {\n result.push(makeFile(makeFileName(i)));\n }\n return result;\n}\n\n/**\n * Make a directory object\n * @param basename The basename of the directory\n * @param path The path of the directory\n * @returns A DirectoryStorageItem object\n */\nexport function makeDirectory(\n basename: string,\n path = '/'\n): DirectoryStorageItem {\n const filename = `${path}${basename}`;\n return {\n basename,\n filename,\n type: 'directory',\n id: filename,\n isExpanded: false,\n };\n}\n\n/**\n * Make directories from 0 to and not including count\n * @param count The number of directories to create (0 to count - 1). Defaults to 5\n * @returns An array of DirectoryStorageItems\n */\nexport function makeDirectories(count = 5) {\n const result: DirectoryStorageItem[] = [];\n for (let i = 0; i < count; i += 1) {\n result.push(makeDirectory(`testdir${i}`));\n }\n return result;\n}\n\n/**\n * Make a nested file\n * @param directories The nested directories in order\n * @param fileNum Number of the file\n * @returns A FileStorageItem\n */\nexport function makeNested(\n directories: number[],\n fileNum: number\n): FileStorageItem {\n const basename = `/${directories\n .map(directory => makeDirName(directory))\n .join('/')}/`;\n return makeFile(makeFileName(fileNum), basename);\n}\n\nexport default {\n makeFileName,\n makeFile,\n makeFiles,\n makeDirName,\n makeDirectory,\n makeDirectories,\n makeNested,\n};\n"],"mappings":"AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,YAAY,GAAoB;EAAA,IAAnBC,KAAK,uEAAG,CAAC;EACpC,yBAAkBA,KAAK;AACzB;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,WAAW,GAAoB;EAAA,IAAnBD,KAAK,uEAAG,CAAC;EACnC,wBAAiBA,KAAK;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,QAAQ,CAACC,QAAgB,EAA+B;EAAA,IAA7BC,IAAI,uEAAG,GAAG;EACnD,IAAMC,QAAQ,aAAMD,IAAI,SAAGD,QAAQ,CAAE;EACrC,OAAO;IACLA,QAAQ;IACRE,QAAQ;IACRC,IAAI,EAAE,MAAM;IACZC,EAAE,EAAEF;EACN,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,SAAS,GAAY;EAAA,IAAXC,KAAK,uEAAG,CAAC;EACjC,IAAMC,MAAyB,GAAG,EAAE;EACpC,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,KAAK,EAAEE,CAAC,IAAI,CAAC,EAAE;IACjCD,MAAM,CAACE,IAAI,CAACV,QAAQ,CAACH,YAAY,CAACY,CAAC,CAAC,CAAC,CAAC;EACxC;EACA,OAAOD,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,aAAa,CAC3BV,QAAgB,EAEM;EAAA,IADtBC,IAAI,uEAAG,GAAG;EAEV,IAAMC,QAAQ,aAAMD,IAAI,SAAGD,QAAQ,CAAE;EACrC,OAAO;IACLA,QAAQ;IACRE,QAAQ;IACRC,IAAI,EAAE,WAAW;IACjBC,EAAE,EAAEF,QAAQ;IACZS,UAAU,EAAE;EACd,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAe,GAAY;EAAA,IAAXN,KAAK,uEAAG,CAAC;EACvC,IAAMC,MAA8B,GAAG,EAAE;EACzC,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,KAAK,EAAEE,CAAC,IAAI,CAAC,EAAE;IACjCD,MAAM,CAACE,IAAI,CAACC,aAAa,kBAAWF,CAAC,EAAG,CAAC;EAC3C;EACA,OAAOD,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASM,UAAU,CACxBC,WAAqB,EACrBC,OAAe,EACE;EACjB,IAAMf,QAAQ,cAAOc,WAAW,CAC7BE,GAAG,CAACC,SAAS,IAAInB,WAAW,CAACmB,SAAS,CAAC,CAAC,CACxCC,IAAI,CAAC,GAAG,CAAC,MAAG;EACf,OAAOnB,QAAQ,CAACH,YAAY,CAACmB,OAAO,CAAC,EAAEf,QAAQ,CAAC;AAClD;AAEA,eAAe;EACbJ,YAAY;EACZG,QAAQ;EACRM,SAAS;EACTP,WAAW;EACXY,aAAa;EACbE,eAAe;EACfC;AACF,CAAC"}