{"version":3,"sources":["jsdelivr-header.js","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/ModeController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/AuthControllerContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/navigation_utils.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/types/entities.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/objects.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/common.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/entities.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/enums.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/ErrorTooltip.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/ErrorView.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/collections.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/strings.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/dates.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/paths.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/regexp.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/useDebouncedCallback.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/property_utils.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/permissions.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/icon_synonyms.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/icon_list.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/icons.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/hash.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/references.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/join_collections.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/useTraceUpdate.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/DataSourceContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/data/useDataSource.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/NavigationContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useNavigationController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useAuthController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/SideDialogsControllerContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useSideDialogsController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/SideEntityControllerContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useSideEntityController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/StorageSourceContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useStorageSource.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useSnackbarController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/UserConfigurationPersistenceContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useUserConfigurationPersistence.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/DialogsProvider.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useDialogsController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/CustomizationControllerContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useCustomizationController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/AnalyticsContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useAnalyticsController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useFireCMSContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/data/useEntityFetch.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/data/save.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/data/delete.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useResolvedNavigationFrom.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useModeController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useClipboard.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useLargeLayout.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useReferenceDialog.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/parent_references_from_path.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useBuildNavigationController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/EmptyValue.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/util.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/ImagePreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/UrlComponentPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/SkeletonPropertyComponent.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/StorageThumbnail.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/EnumValuesChip.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/StringPropertyPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/ArrayPropertyPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/ReferencePreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/ArrayOfReferencesPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/ArrayEnumPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/ArrayPropertyEnumPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/ArrayOfStringsPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/ArrayOneOfPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/MapPropertyPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/DatePreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/BooleanPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/NumberPropertyPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/PropertyPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/components/AsyncPreviewComponent.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityView.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/fields/VirtualTableInput.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/fields/VirtualTableSelect.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/fields/VirtualTableSwitch.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/fields/VirtualTableDateField.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/ErrorBoundary.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/storage.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/useStorageUploadController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/components/StorageUploadProgress.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/fields/TableReferenceField.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/validation.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/common.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/internal/EntityTableCell.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/SelectableTable/SelectableTableContext.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/useClearRestoreValue.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/PropertyTableCell.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/internal/common.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/common/useColumnsIds.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/column_utils.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/CircularProgressCenter.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/VirtualTableHeader.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/VirtualTableHeaderRow.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/VirtualTableRow.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/VirtualTableCell.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/VirtualTable/VirtualTable.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/SelectableTable/filters/ReferenceFilterField.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/SelectableTable/filters/StringNumberFilterField.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/SelectableTable/filters/BooleanFilterField.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/SelectableTable/filters/DateTimeFilterField.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/SelectableTable/SelectableTable.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/EntityCollectionTable.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/common/useDebouncedData.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/common/useDataSourceEntityCollectionTableController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/data/useDataOrder.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionView/useSelectionController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/common/useTableSearchHelper.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/DeleteEntityDialog.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/common/default_entity_actions.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/ReferenceTable/ReferenceSelectionTable.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/arrays.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/HomePage/NavigationGroup.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/HomePage/NavigationCard.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/HomePage/SmallNavigationCard.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/HomePage/NavigationCardBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/HomePage/FavouritesView.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/internal/useRestoreScroll.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/HomePage/DefaultHomePage.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionView/EntityCollectionViewActions.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionTable/internal/popup_field/useWindowSize.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/ClearFilterSortButton.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/EntityCollectionView/EntityCollectionView.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/NotFoundPage.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/FireCMSLogo.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/FireCMSAppBar.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/ArrayContainer.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/components/FormikArrayContainer.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/components/FieldHelperText.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/components/LabelWithIcon.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/SelectFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/MultiSelectBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/components/StorageItemPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/SearchIconsView.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/StorageUploadFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/TextFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/SwitchFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/DateTimeFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/ReadOnlyFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/ReferenceFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/PropertyFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/MapFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/KeyValueFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/RepeatFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/BlockFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/MarkdownFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/components/ErrorFocus.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/components/CustomIdField.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/PropertyIdCopyTooltipContent.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/form/EntityForm.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/field_configs.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/resolutions.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/navigation_from_path.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/internal/common.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/EntityEditView.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/internal/useUnsavedChangesDialog.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/SideDialogs.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/EntitySidePanel.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/internal/useBuildSideEntityController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useProjectLog.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/FireCMS.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/DrawerNavigationItem.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/Drawer.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/Scaffold.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/core/NavigationRoutes.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/preview/property_previews/ArrayOfMapsPreview.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/DeleteConfirmationDialog.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/FieldCaption.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/internal/useBuildDataSource.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/internal/useBuildSideDialogsController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/PropertyConfigBadge.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/components/ReferenceWidget.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/contexts/SnackbarProvider.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/builders.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/flatten_object.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/make_properties_editable.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/util/plurals.ts","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useBrowserTitleAndIcon.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useBuildLocalConfigurationPersistence.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useBuildModeController.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/data/useCollectionFetch.tsx","/npm/@edumetz16/firecms_core@3.0.0-canary.53/src/hooks/useValidateAuthenticator.tsx"],"names":[],"mappings":"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","file":"/npm/@edumetz16/firecms_core@3.0.0-canary.53/dist/index.umd.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@edumetz16/firecms_core@3.0.0-canary.53/dist/index.umd.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import React from \"react\";\nimport { ModeController } from \"../hooks\";\n\nconst DEFAULT_MODE_STATE: ModeController = {\n    mode: \"light\",\n    setMode: (mode: \"light\" | \"dark\") => {\n    },\n    toggleMode: () => {\n    }\n};\nexport const ModeControllerContext = React.createContext<ModeController>(DEFAULT_MODE_STATE);\n\nexport const ModeControllerProvider = ModeControllerContext.Provider;\n","import React from \"react\";\nimport { AuthController } from \"../types\";\n\nexport const AuthControllerContext = React.createContext<AuthController<any, any>>({} as AuthController<any, any>);\n","import { EntityCollection } from \"../types\";\n\nexport function removeInitialAndTrailingSlashes(s: string): string {\n    return removeInitialSlash(removeTrailingSlash(s));\n}\n\nexport function removeInitialSlash(s: string) {\n    if (s.startsWith(\"/\"))\n        return s.slice(1);\n    else return s;\n}\n\nexport function removeTrailingSlash(s: string) {\n    if (s.endsWith(\"/\"))\n        return s.slice(0, -1);\n    else return s;\n}\n\nexport function addInitialSlash(s: string) {\n    if (s.startsWith(\"/\"))\n        return s;\n    else return `/${s}`;\n}\n\nexport function getLastSegment(path: string) {\n    const cleanPath = removeInitialAndTrailingSlashes(path);\n    if (cleanPath.includes(\"/\")) {\n        const segments = cleanPath.split(\"/\");\n        return segments[segments.length - 1];\n    }\n    return cleanPath;\n}\n\nexport function resolveCollectionPathIds(path: string, allCollections: EntityCollection[]): string {\n\n    const cleanPath = removeInitialAndTrailingSlashes(path);\n    const subpaths = cleanPath.split(\"/\");\n    if (subpaths.length % 2 === 0) {\n        throw Error(`resolveCollectionPathAliases: Collection paths must have an odd number of segments: ${path}`);\n    }\n\n    const aliasedCollection = allCollections.find((col) => col.id === subpaths[0]);\n    let resolvedAliased;\n    if (aliasedCollection) {\n        resolvedAliased = aliasedCollection.path;\n    }\n\n    if (subpaths.length > 1) {\n        const segmentCollection = getCollectionByPathOrId(resolvedAliased ?? subpaths[0], allCollections);\n        if (!segmentCollection?.subcollections) {\n            return cleanPath;\n        }\n        const restOfThePath = cleanPath.split(\"/\").slice(2).join(\"/\");\n        return (resolvedAliased ?? subpaths[0]) + \"/\" + subpaths[1] + \"/\" + resolveCollectionPathIds(restOfThePath, segmentCollection.subcollections);\n    } else {\n        return resolvedAliased ?? cleanPath;\n    }\n}\n\n/**\n * Find the corresponding view at any depth for a given path.\n * Note that path or segments of the paths can be collection aliases.\n * @param pathOrId\n * @param collections\n */\nexport function getCollectionByPathOrId(pathOrId: string, collections: EntityCollection[]): EntityCollection | undefined {\n\n    const subpaths = removeInitialAndTrailingSlashes(pathOrId).split(\"/\");\n    if (subpaths.length % 2 === 0) {\n        throw Error(`getCollectionByPathOrId: Collection paths must have an odd number of segments: ${pathOrId}`);\n    }\n\n    const subpathCombinations = getCollectionPathsCombinations(subpaths);\n    let result: EntityCollection | undefined;\n    for (let i = 0; i < subpathCombinations.length; i++) {\n        const subpathCombination = subpathCombinations[i];\n        const navigationEntry = collections && collections\n            .sort((a, b) => (a.id ?? \"\").localeCompare(b.id ?? \"\"))\n            .find((entry) => entry.id === subpathCombination || entry.path === subpathCombination);\n\n        if (navigationEntry) {\n\n            if (subpathCombination === pathOrId) {\n                result = navigationEntry;\n            } else if (navigationEntry.subcollections) {\n                const newPath = pathOrId.replace(subpathCombination, \"\").split(\"/\").slice(2).join(\"/\");\n                if (newPath.length > 0)\n                    result = getCollectionByPathOrId(newPath, navigationEntry.subcollections);\n            }\n        }\n        if (result) break;\n    }\n    return result;\n}\n\n/**\n * Get the subcollection combinations from a path:\n * \"sites/es/locales\" => [\"sites/es/locales\", \"sites\"]\n * @param subpaths\n */\nexport function getCollectionPathsCombinations(subpaths: string[]): string[] {\n    const entries = subpaths.length > 0 && subpaths.length % 2 === 0 ? subpaths.splice(0, subpaths.length - 1) : subpaths;\n\n    const length = entries.length;\n    const result: string[] = [];\n    for (let i = length; i > 0; i = i - 2) {\n        result.push(entries.slice(0, i).join(\"/\"));\n    }\n    return result;\n\n}\n","/**\n * New or existing status\n * @group Models\n */\nexport type EntityStatus = \"new\" | \"existing\" | \"copy\";\n\n/**\n * Representation of an entity fetched from the datasource\n * @group Models\n */\nexport interface Entity<M extends object> {\n\n    /**\n     * ID of the entity\n     */\n    id: string;\n\n    /**\n     * A string representing the path of the referenced document (relative\n     * to the root of the database).\n     */\n    path: string;\n\n    /**\n     * Current values\n     */\n    values: EntityValues<M>;\n}\n\n/**\n * This type represents a record of key value pairs as described in an\n * entity collection.\n * @group Models\n */\nexport type EntityValues<M extends object> = M;\n\n/**\n * Class used to create a reference to an entity in a different path\n */\nexport class EntityReference {\n    /**\n     * ID of the entity\n     */\n    readonly id: string;\n    /**\n     * A string representing the path of the referenced document (relative\n     * to the root of the database).\n     */\n    readonly path: string;\n\n    constructor(id: string, path: string) {\n        this.id = id;\n        this.path = path;\n    }\n\n    get pathWithId() {\n        return `${this.path}/${this.id}`;\n    }\n\n    isEntityReference() {\n        return true;\n    }\n}\n\nexport class GeoPoint {\n\n    /**\n     * The latitude of this GeoPoint instance.\n     */\n    readonly latitude: number;\n    /**\n     * The longitude of this GeoPoint instance.\n     */\n    readonly longitude: number;\n\n    constructor(latitude: number, longitude: number) {\n        this.latitude = latitude;\n        this.longitude = longitude;\n    }\n}\n\nexport class Vector {\n    readonly value: number[];\n\n    constructor(value: number[]) {\n        this.value = value;\n    }\n}\n","import hash from \"object-hash\";\nimport { GeoPoint } from \"../types\";\n\nexport const pick: <T>(obj: T, ...args: any[]) => T = (obj: any, ...args: any[]) => ({\n    ...args.reduce((res, key) => ({\n        ...res,\n        [key]: obj[key]\n    }), {})\n});\n\nexport function isObject(item: any) {\n    return item && typeof item === \"object\" && !Array.isArray(item);\n}\n\nexport function mergeDeep<T extends object>(target: T, source: any): T {\n    const targetIsObject = isObject(target);\n    const output: T = targetIsObject ? { ...target } : target;\n    if (targetIsObject && isObject(source)) {\n        Object.keys(source).forEach(key => {\n            if (isObject(source[key])) {\n                if (!(key in target))\n                    Object.assign(output, { [key]: source[key] });\n                else\n                    (output as any)[key] = mergeDeep((target as any)[key], source[key]);\n            } else {\n                Object.assign(output, { [key]: source[key] });\n            }\n        });\n    }\n    return output;\n}\n\nexport function getValueInPath(o: object | undefined, path: string): any {\n    if (!o) return undefined;\n    if (typeof o === \"object\") {\n        if (path in o) {\n            return (o as any)[path];\n        }\n        if (path.includes(\".\") || path.includes(\"[\")) {\n            let pathSegments = path.split(/[.[]/);\n            if (path.includes(\"[\")) {\n                pathSegments = pathSegments.map(segment => segment.replace(\"]\", \"\"));\n            }\n            const firstSegment = pathSegments[0];\n            const isArrayAndIndexExists = Array.isArray((o as any)[firstSegment]) && !isNaN(parseInt(pathSegments[1]));\n            const nextObject = isArrayAndIndexExists\n                ? (o as any)[firstSegment][parseInt(pathSegments[1])]\n                : (o as any)[firstSegment];\n\n            const nextPath = pathSegments.slice(isArrayAndIndexExists ? 2 : 1).join(\".\");\n            if (nextPath === \"\")\n                return nextObject;\n            return getValueInPath(nextObject, nextPath)\n        }\n    }\n    return undefined;\n}\n\nexport function removeInPath(o: object, path: string): object | undefined {\n    let currentObject = { ...o };\n    const parts = path.split(\".\");\n    const last = parts.pop();\n    for (const part of parts) {\n        currentObject = (currentObject as any)[part]\n    }\n    if (last)\n        delete (currentObject as any)[last];\n    return currentObject;\n}\n\nexport function removeFunctions(o: object | undefined): any {\n    if (o === undefined) return undefined;\n    if (o === null) return null;\n    if (typeof o === \"object\") {\n        return Object.entries(o)\n            .filter(([_, value]) => typeof value !== \"function\")\n            .map(([key, value]) => {\n                if (Array.isArray(value)) {\n                    return { [key]: value.map(v => removeFunctions(v)) };\n                } else if (typeof value === \"object\") {\n                    return { [key]: removeFunctions(value) };\n                } else return { [key]: value };\n            })\n            .reduce((a, b) => ({ ...a, ...b }), {});\n    }\n    return o;\n}\n\nexport function getHashValue<T>(v: T) {\n    if (!v) return null;\n    if (typeof v === \"object\") {\n        if (\"id\" in v)\n            return (v as any).id;\n        else if (v instanceof Date)\n            return v.toLocaleString();\n        else if (v instanceof GeoPoint)\n            return hash(v as Record<string, unknown>);\n    }\n    return hash(v, { ignoreUnknown: true });\n}\n\nexport function removeUndefined(value: any, removeEmptyStrings?: boolean): any {\n    if (typeof value === \"function\") {\n        return value;\n    }\n    if (Array.isArray(value)) {\n        return value.map((v: any) => removeUndefined(v, removeEmptyStrings));\n    }\n    if (typeof value === \"object\") {\n        const res: object = {};\n        if (value === null)\n            return value;\n        Object.keys(value).forEach((key) => {\n            if (!isEmptyObject(value)) {\n                const childRes = removeUndefined(value[key], removeEmptyStrings);\n                const isString = typeof childRes === \"string\";\n                const shouldKeepIfString = !removeEmptyStrings || (removeEmptyStrings && !isString) || (removeEmptyStrings && isString && childRes !== \"\");\n                if (childRes !== undefined && !isEmptyObject(childRes) && shouldKeepIfString)\n                    (res as any)[key] = childRes;\n            }\n        });\n        return res;\n    }\n    return value;\n}\n\nexport function isEmptyObject(obj: object) {\n    return obj &&\n        Object.getPrototypeOf(obj) === Object.prototype &&\n        Object.keys(obj).length === 0\n}\n\nexport function removePropsIfExisting(source: any, comparison: any) {\n    const isObject = (val: any) => typeof val === \"object\" && val !== null;\n    const isArray = (val: any) => Array.isArray(val);\n\n    if (!isObject(source) || !isObject(comparison)) {\n        return source;\n    }\n\n    const res = isArray(source) ? [...source] : { ...source };\n\n    Object.keys(comparison).forEach(key => {\n        if (key in res) {\n            if (isObject(res[key]) && isObject(comparison[key])) {\n                res[key] = removePropsIfExisting(res[key], comparison[key]);\n            } else if (res[key] === comparison[key]) {\n                isArray(res) ? res.splice(key, 1) : delete res[key];\n            }\n        }\n    });\n\n    return res;\n}\n","export const DEFAULT_ONE_OF_TYPE = \"type\"\nexport const DEFAULT_ONE_OF_VALUE = \"value\"\n","import {\n    CMSType,\n    DataType,\n    Entity,\n    EntityReference,\n    EntityStatus,\n    EntityValues,\n    Properties,\n    PropertiesOrBuilders,\n    Property,\n    PropertyBuilder,\n    PropertyOrBuilder,\n    ResolvedProperties,\n    ResolvedProperty\n} from \"../types\";\nimport { DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE } from \"./common\";\n\nexport function isReadOnly(property: Property | ResolvedProperty): boolean {\n    if (property.readOnly)\n        return true;\n    if (property.dataType === \"date\") {\n        if (property.autoValue)\n            return true;\n    }\n    if (property.dataType === \"reference\") {\n        return !property.path;\n    }\n    return false;\n}\n\nexport function isHidden(property: Property | ResolvedProperty): boolean {\n    return typeof property.disabled === \"object\" && Boolean(property.disabled.hidden);\n}\n\nexport function isPropertyBuilder<T extends CMSType, M extends Record<string, any>>(propertyOrBuilder?: PropertyOrBuilder<T, M> | Property<T> | ResolvedProperty<T>): propertyOrBuilder is PropertyBuilder<T, M> {\n    return typeof propertyOrBuilder === \"function\";\n}\n\nexport function getDefaultValuesFor<M extends Record<string, any>>(properties: PropertiesOrBuilders<M> | ResolvedProperties<M>): Partial<EntityValues<M>> {\n    if (!properties) return {};\n    return Object.entries(properties)\n        .map(([key, property]) => {\n            const value = getDefaultValueFor(property as PropertyOrBuilder);\n            return value === undefined ? {} : { [key]: value };\n        })\n        .reduce((a, b) => ({ ...a, ...b }), {}) as EntityValues<M>;\n}\n\nexport function getDefaultValueFor(property: PropertyOrBuilder) {\n    if (isPropertyBuilder(property)) return undefined;\n    if (property.dataType === \"map\" && property.properties) {\n        const defaultValuesFor = getDefaultValuesFor(property.properties as Properties);\n        if (Object.keys(defaultValuesFor).length === 0) return undefined;\n        return defaultValuesFor;\n    } else if (property.defaultValue) {\n        return property.defaultValue;\n    } else {\n        return getDefaultValueForDataType(property.dataType);\n    }\n}\n\nexport function getDefaultValueForDataType(dataType: DataType) {\n    if (dataType === \"string\") {\n        return null;\n    } else if (dataType === \"number\") {\n        return null;\n    } else if (dataType === \"boolean\") {\n        return false;\n    } else if (dataType === \"date\") {\n        return null;\n    } else if (dataType === \"array\") {\n        return [];\n    } else if (dataType === \"map\") {\n        return {};\n    } else {\n        return null;\n    }\n}\n\n/**\n * Update the automatic values in an entity before save\n * @group Datasource\n */\nexport function updateDateAutoValues<M extends Record<string, any>>({\n                                                                        inputValues,\n                                                                        properties,\n                                                                        status,\n                                                                        timestampNowValue,\n                                                                        setDateToMidnight\n                                                                    }:\n                                                                        {\n                                                                            inputValues: Partial<EntityValues<M>>,\n                                                                            properties: ResolvedProperties<M>,\n                                                                            status: EntityStatus,\n                                                                            timestampNowValue: any,\n                                                                            setDateToMidnight: (input?: any) => any | undefined\n                                                                        }): EntityValues<M> {\n    return traverseValuesProperties(\n        inputValues,\n        properties,\n        (inputValue, property) => {\n            if (property.dataType === \"date\") {\n                let resultDate;\n                if (status === \"existing\" && property.autoValue === \"on_update\") {\n                    resultDate = timestampNowValue;\n                } else if ((status === \"new\" || status === \"copy\") &&\n                    (property.autoValue === \"on_update\" || property.autoValue === \"on_create\")) {\n                    resultDate = timestampNowValue;\n                } else {\n                    resultDate = inputValue;\n                }\n                if (property.mode === \"date\")\n                    resultDate = setDateToMidnight(resultDate);\n                return resultDate;\n            } else {\n                return inputValue;\n            }\n        }\n    ) ?? {} as M;\n}\n\n/**\n * Add missing required fields, expected in the collection, to the values of an entity\n * @param values\n * @param properties\n * @group Datasource\n */\nexport function sanitizeData<M extends Record<string, any>>\n(\n    values: EntityValues<M>,\n    properties: ResolvedProperties<M>\n) {\n    const result: any = values;\n    Object.entries(properties)\n        .forEach(([key, property]) => {\n            if (values && values[key] !== undefined) result[key] = values[key];\n            else if ((property as Property).validation?.required) result[key] = null;\n        });\n    return result;\n}\n\nexport function getReferenceFrom<M extends Record<string, any>>(entity: Entity<M>): EntityReference {\n    return new EntityReference(entity.id, entity.path);\n}\n\nexport function traverseValuesProperties<M extends Record<string, any>>(\n    inputValues: Partial<EntityValues<M>>,\n    properties: ResolvedProperties<M>,\n    operation: (value: any, property: Property) => any\n): EntityValues<M> | undefined {\n    const updatedValues = Object.entries(properties)\n        .map(([key, property]) => {\n            const inputValue = inputValues && (inputValues)[key];\n            const updatedValue = traverseValueProperty(inputValue, property as Property, operation);\n            if (updatedValue === undefined) return undefined;\n            return ({ [key]: updatedValue });\n        })\n        .reduce((a, b) => ({ ...a, ...b }), {}) as EntityValues<M>;\n    const result = { ...inputValues, ...updatedValues };\n    if (Object.keys(result).length === 0) return undefined;\n    return result;\n}\n\nexport function traverseValueProperty(inputValue: any,\n                                      property: Property,\n                                      operation: (value: any, property: Property) => any): any {\n\n    let value;\n    if (property.dataType === \"map\" && property.properties) {\n        value = traverseValuesProperties(inputValue, property.properties as ResolvedProperties, operation);\n    } else if (property.dataType === \"array\") {\n        if (property.of && Array.isArray(inputValue)) {\n            value = inputValue.map((e) => traverseValueProperty(e, property.of as Property, operation));\n        } else if (property.oneOf && Array.isArray(inputValue)) {\n            const typeField = property.oneOf?.typeField ?? DEFAULT_ONE_OF_TYPE;\n            const valueField = property.oneOf?.valueField ?? DEFAULT_ONE_OF_VALUE;\n            value = inputValue.map((e) => {\n                if (e === null) return null;\n                if (typeof e !== \"object\") return e;\n                const type = e[typeField];\n                const childProperty = property.oneOf?.properties[type];\n                if (!type || !childProperty) return e;\n                return {\n                    [typeField]: type,\n                    [valueField]: traverseValueProperty(e[valueField], childProperty, operation)\n                };\n            });\n        } else {\n            value = inputValue;\n        }\n    } else {\n        value = operation(inputValue, property);\n    }\n\n    return value;\n}\n","import { EnumValueConfig, EnumValues } from \"../types\";\nimport { CHIP_COLORS, ChipColorScheme, getColorSchemeForSeed } from \"@firecms/ui\";\n\nexport function enumToObjectEntries(enumValues: EnumValues): EnumValueConfig[] {\n    if (Array.isArray(enumValues)) {\n        return enumValues;\n    } else {\n        return Object.entries(enumValues).map(([id, value]) => {\n            if (typeof value === \"string\") {\n                return {\n                    id,\n                    label: value\n                }\n            } else {\n                return {\n                    ...value,\n                    id\n                }\n            }\n        });\n    }\n}\n\nexport function getLabelOrConfigFrom(enumValues: EnumValueConfig[], key?: string | number): EnumValueConfig | undefined {\n    if (key === null || key === undefined) return undefined;\n    return enumValues.find((entry) => String(entry.id) === String(key));\n}\n\nexport function getColorScheme(enumValues: EnumValueConfig[], key: string | number): ChipColorScheme | undefined {\n    const labelOrConfig = getLabelOrConfigFrom(enumValues, key);\n    if (!labelOrConfig?.color)\n        return getColorSchemeForSeed(key.toString());\n    if (typeof labelOrConfig === \"object\" && \"color\" in labelOrConfig) {\n        if (typeof labelOrConfig.color === \"string\")\n            return CHIP_COLORS[labelOrConfig.color];\n        if (typeof labelOrConfig.color === \"object\")\n            return labelOrConfig.color;\n    }\n    return undefined;\n}\n\nexport function isEnumValueDisabled(labelOrConfig?: string | EnumValueConfig) {\n    return typeof labelOrConfig === \"object\" && (labelOrConfig as EnumValueConfig).disabled;\n}\n\nexport function buildEnumLabel(\n    labelOrConfig?: string | EnumValueConfig\n): string | undefined {\n    if (labelOrConfig === undefined)\n        return undefined;\n    if (typeof labelOrConfig === \"object\") {\n        return labelOrConfig.label;\n    } else {\n        return labelOrConfig;\n    }\n}\n","import React from \"react\";\nimport { Tooltip, TooltipProps } from \"@firecms/ui\";\n\nexport function ErrorTooltip(props: TooltipProps) {\n    return (\n        <Tooltip {...props}\n                 tooltipClassName={\"!text-red-500 bg-red-50\"}>\n            {props.children}\n        </Tooltip>\n    );\n}\n","import React from \"react\";\nimport { ErrorTooltip } from \"./ErrorTooltip\";\nimport { ErrorIcon, Typography } from \"@firecms/ui\";\n\n/**\n * @group Components\n */\nexport interface ErrorViewProps {\n    title?: string;\n    error: Error | React.ReactElement | string,\n    tooltip?: string\n}\n\n/**\n * Generic error view. Displayed for example when an unexpected value comes\n * from the datasource in a collection view.\n * @param title\n * @param error\n * @param tooltip\n * @constructor\n * @group Components\n */\nexport function ErrorView({\n                              title,\n                              error,\n                              tooltip\n                          }: ErrorViewProps): React.ReactElement {\n    const component = error instanceof Error ? error.message : error;\n    console.error(\"ErrorView\", error)\n\n    const body = (\n        <div\n            className=\"flex items-center m-2\">\n            <ErrorIcon size={\"small\"} color={\"error\"}/>\n            <div className=\"pl-2\">\n                {title && <Typography\n                    variant={\"body2\"}\n                    className=\"font-medium\">{title}</Typography>}\n                <Typography variant={\"body2\"}>{component}</Typography>\n            </div>\n        </div>\n    );\n\n    if (tooltip) {\n        return (\n            <ErrorTooltip title={tooltip}>\n                {body}\n            </ErrorTooltip>\n        );\n    }\n    return body;\n}\n","import {\n    DefaultSelectedViewBuilder,\n    DefaultSelectedViewParams,\n    EntityCollection,\n    PermissionsBuilder,\n    PropertiesOrBuilders,\n    PropertyOrBuilder\n} from \"../types\";\nimport { isPropertyBuilder } from \"./entities\";\n\nexport function sortProperties<M extends Record<string, any>>(properties: PropertiesOrBuilders<M>, propertiesOrder?: (keyof M)[]): PropertiesOrBuilders<M> {\n    try {\n        const propertiesKeys = Object.keys(properties);\n        const allPropertiesOrder = propertiesOrder ?? propertiesKeys;\n        return allPropertiesOrder\n            .map((key) => {\n                if (properties[key as keyof M]) {\n                    const property = properties[key] as PropertyOrBuilder;\n                    if (!isPropertyBuilder(property) && property?.dataType === \"map\" && property.properties) {\n                        return ({\n                            [key]: {\n                                ...property,\n                                properties: sortProperties(property.properties, property.propertiesOrder)\n                            }\n                        });\n                    } else {\n                        return ({ [key]: property });\n                    }\n                } else {\n                    return undefined;\n                }\n            })\n            .filter((a) => a !== undefined)\n            .reduce((a: any, b: any) => ({ ...a, ...b }), {}) as PropertiesOrBuilders<M>;\n    } catch (e) {\n        console.error(\"Error sorting properties\", e);\n        return properties;\n    }\n}\n\nexport function resolveDefaultSelectedView(\n    defaultSelectedView: string | DefaultSelectedViewBuilder | undefined,\n    params: DefaultSelectedViewParams\n) {\n    if (!defaultSelectedView) {\n        return undefined;\n    } else if (typeof defaultSelectedView === \"string\") {\n        return defaultSelectedView;\n    } else {\n        return defaultSelectedView(params);\n    }\n}\n\n/**\n * If a collection is not applying permissions, we apply the given permissionsBuilder.\n * This is used to apply the role permissions to the collections, unless they are already\n * applying permissions.\n * @param collections\n * @param permissionsBuilder\n */\nexport const applyPermissionsFunctionIfEmpty = (collections: EntityCollection[], permissionsBuilder?: PermissionsBuilder<any, any>): EntityCollection[] => {\n\n    return collections.map(collection => {\n        if (collection.permissions) {\n            return collection;\n        }\n        return ({\n            ...collection,\n            permissions: permissionsBuilder\n        });\n    });\n}\n","const kebabCaseRegex = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g;\n\nexport const toKebabCase = (str: string) => {\n    const regExpMatchArray = str.match(kebabCaseRegex);\n    if (!regExpMatchArray) return \"\";\n    return regExpMatchArray\n        .map(x => x.toLowerCase())\n        .join(\"-\");\n};\n\nconst snakeCaseRegex = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g;\n\nexport const toSnakeCase = (str: string) => {\n    const regExpMatchArray = str.match(snakeCaseRegex);\n    if (!regExpMatchArray) return \"\";\n    return regExpMatchArray\n        .map(x => x.toLowerCase())\n        .join(\"_\");\n};\n\nexport function randomString(strLength = 5) {\n    return Math.random().toString(36).slice(2, 2 + strLength);\n}\n\nexport function randomColor() {\n    return Math.floor(Math.random() * 16777215).toString(16);\n}\n\nexport function slugify(text?: string, separator = \"_\", lowercase = true) {\n    if (!text) return \"\";\n    const from = \"ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;-\"\n    const to = `aaaaaeeeeeiiiiooooouuuunc${separator}${separator}${separator}${separator}${separator}${separator}${separator}`;\n\n    for (let i = 0, l = from.length; i < l; i++) {\n        text = text.replace(new RegExp(from.charAt(i), \"g\"), to.charAt(i));\n    }\n\n    text = text\n        .toString() // Cast to string\n        .replace(/\\s+/g, separator) // Replace spaces with separator\n        .replace(/&/g, separator) // Replace & with separator\n        .replace(/[^\\w\\\\-]+/g, \"\") // Remove all non-word chars\n        .replace(new RegExp(\"\\\\\" + separator + \"\\\\\" + separator + \"+\", \"g\"),\n            separator) // Replace multiple separators with single one\n        .trim() // Remove whitespace from both sides of a string\n        .replace(/^\\s+|\\s+$/g, \"\");\n\n    return lowercase\n        ? text.toLowerCase() // Convert the string to lowercase letters\n        : text;\n}\n\nexport function unslugify(slug?: string): string {\n    if (!slug) return \"\";\n    if (slug.includes(\"-\") || slug.includes(\"_\") || !slug.includes(\" \")) {\n        const result = slug.replace(/[-_]/g, \" \");\n        return result.replace(/\\w\\S*/g, function (txt) {\n            return txt.charAt(0).toUpperCase() + txt.substr(1);\n        }).trim();\n    } else {\n        return slug.trim();\n    }\n}\n","export const defaultDateFormat = \"MMMM dd, yyyy, HH:mm:ss\";\n","export const COLLECTION_PATH_SEPARATOR = \"::\";\n\n/**\n * Remove the entity ids from a given path\n * `products/B44RG6APH/locales` => `products::locales`\n * @param path\n */\nexport function stripCollectionPath(path: string): string {\n    return segmentsToStrippedPath(fullPathToCollectionSegments(path));\n}\n\nexport function segmentsToStrippedPath(paths: string[]) {\n    if (paths.length === 1)\n        return paths[0];\n    return paths.reduce((a, b) => `${a}${COLLECTION_PATH_SEPARATOR}${b}`);\n}\n\n/**\n * Extract the collection path routes\n * `products/B44RG6APH/locales` => [`products`, `locales`]\n * @param path\n */\nexport function fullPathToCollectionSegments(path: string): string[] {\n    return path\n        .split(\"/\")\n        .filter((e, i) => i % 2 === 0);\n}\n","export function serializeRegExp(input: RegExp): string {\n    if (!input) return \"\";\n    // const fragments = input.toString().match(/\\/(.*?)\\/([a-z]*)?$/i);\n    // if (fragments) {\n    //     if (fragments[2])\n    //         return input.toString();\n    //     return fragments[1];\n    // }\n    return input.toString();\n}\n\n/**\n * Get a RegExp out of a serialized string\n * @param input\n */\nexport function hydrateRegExp(input?: string): RegExp | undefined {\n    if (!input) return undefined;\n    const fragments = input.match(/\\/(.*?)\\/([a-z]*)?$/i);\n    if (fragments) {\n        return new RegExp(fragments[1], fragments[2] || \"\");\n    } else {\n        return new RegExp(input, \"\");\n    }\n}\n\nexport function isValidRegExp(input: string): boolean {\n    const fullRegexp = input.match(/\\/((?![*+?])(?:[^\\r\\n[/\\\\]|\\\\.|\\[(?:[^\\r\\n\\]\\\\]|\\\\.)*])+)\\/((?:g(?:im?|mi?)?|i(?:gm?|mg?)?|m(?:gi?|ig?)?)?)/);\n    if (fullRegexp)\n        return true;\n    const simpleRegexp = input.match(/((?![*+?])(?:[^\\r\\n[/\\\\]|\\\\.|\\[(?:[^\\r\\n\\]\\\\]|\\\\.)*])+)/);\n    return !!simpleRegexp;\n}\n","import React from \"react\";\n\nexport function useDebouncedCallback<T>(value: T, callback: () => void, immediate: boolean, timeoutMs = 300) {\n\n    const pendingUpdate = React.useRef(false);\n    const performUpdate = () => {\n        callback();\n        pendingUpdate.current = false;\n    };\n\n    const handlerRef = React.useRef<number | undefined>(undefined);\n\n    React.useEffect(\n        () => {\n            pendingUpdate.current = true;\n            clearTimeout(handlerRef.current);\n            handlerRef.current = setTimeout(performUpdate, timeoutMs) as any;\n            return () => {\n                if (immediate)\n                    performUpdate();\n            };\n        },\n        [immediate, value]\n    );\n}\n","import React from \"react\";\n\nimport { EntityCollection, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedProperty } from \"../types\";\nimport { isPropertyBuilder } from \"./entities\";\nimport { resolveProperty } from \"./resolutions\";\nimport { CircleIcon, FunctionsIcon } from \"@firecms/ui\";\nimport { getFieldConfig } from \"../core\";\n\nexport function isReferenceProperty(propertyOrBuilder: PropertyOrBuilder,\n                                    fields: Record<string, PropertyConfig>) {\n    const resolvedProperty = resolveProperty({\n        propertyKey: \"ignore\", // TODO\n        propertyOrBuilder,\n        fields\n    });\n    if (!resolvedProperty) return null;\n    if (resolvedProperty.dataType === \"reference\") {\n        return true;\n    }\n    if (resolvedProperty.dataType === \"array\") {\n        if (Array.isArray(resolvedProperty.of)) return false;\n        else return resolvedProperty.of?.dataType === \"reference\"\n    }\n    return false;\n}\n\nexport function getIdIcon(size: \"small\" | \"medium\" | \"large\"): React.ReactNode {\n    return <CircleIcon size={size}/>;\n}\n\nexport function getIconForWidget(widget: PropertyConfig | undefined,\n                                 size: \"small\" | \"medium\" | \"large\") {\n    const Icon = widget?.Icon ?? CircleIcon;\n    return <Icon size={size}/>;\n}\n\nexport function getIconForProperty(\n    property: PropertyOrBuilder | ResolvedProperty,\n    size: \"small\" | \"medium\" | \"large\" = \"small\",\n    fields: Record<string, PropertyConfig> = {}\n): React.ReactNode {\n\n    if (isPropertyBuilder(property)) {\n        return <FunctionsIcon size={size}/>;\n    } else {\n        const widget = getFieldConfig(property, fields);\n        return getIconForWidget(widget, size);\n    }\n}\n\nexport function getColorForProperty(property: PropertyOrBuilder, fields: Record<string, PropertyConfig>): string {\n    if (isPropertyBuilder(property)) {\n        return \"#888\";\n    } else {\n        const widget = getFieldConfig(property, fields);\n        return widget?.color ?? \"#666\";\n    }\n}\n\n/**\n * Get a property in a property tree from a path like\n * `address.street`\n * @param properties\n * @param path\n */\nexport function getPropertyInPath<M extends Record<string, any>>(properties: PropertiesOrBuilders<M>, path: string): PropertyOrBuilder<any, M> | undefined {\n    if (typeof properties === \"object\") {\n        if (path in properties) {\n            return properties[path];\n        }\n        if (path.includes(\".\")) {\n            const pathSegments = path.split(\".\");\n            const childProperty = properties[pathSegments[0]];\n            if (typeof childProperty === \"object\" && childProperty.dataType === \"map\" && childProperty.properties) {\n                return getPropertyInPath(childProperty.properties, pathSegments.slice(1).join(\".\"))\n            }\n        }\n    }\n    return undefined;\n}\n\nexport function getResolvedPropertyInPath(properties: Record<string, ResolvedProperty>, path: string): ResolvedProperty | undefined {\n    if (typeof properties === \"object\") {\n        if (path in properties) {\n            return properties[path];\n        }\n        if (path.includes(\".\")) {\n            const pathSegments = path.split(\".\");\n            const childProperty = properties[pathSegments[0]];\n            if (childProperty.dataType === \"map\" && childProperty.properties) {\n                return getResolvedPropertyInPath(childProperty.properties, pathSegments.slice(1).join(\".\"))\n            }\n        }\n    }\n    return undefined;\n}\n\n// replace the dot notation with brackets\n// address.street => address[street]\nexport function getBracketNotation(path: string): string {\n    return path.replace(/\\.([^.]*)/g, \"[$1]\");\n}\n\n/**\n * Get properties exclusively indexed by their order\n * @param properties\n * @param propertiesOrder\n */\nexport function getPropertiesWithPropertiesOrder<M extends Record<string, any>>(properties: PropertiesOrBuilders<M>, propertiesOrder?: Extract<keyof M, string>[]): PropertiesOrBuilders<M> {\n    if (!propertiesOrder) return properties;\n    const result: PropertiesOrBuilders<any> = {};\n    propertiesOrder.filter(Boolean).forEach(path => {\n        const property = getPropertyInPath(properties, path);\n        if (typeof property === \"object\" && property.dataType === \"map\" && property.properties) {\n            result[path] = {\n                ...property,\n                properties: getPropertiesWithPropertiesOrder(property.properties, property.propertiesOrder ?? [])\n            }\n        }\n        if (property) {\n            result[path] = property;\n        }\n    });\n    return result;\n}\n\nexport function getDefaultPropertiesOrder(collection: EntityCollection<any>): string[] {\n    if (collection.propertiesOrder) return collection.propertiesOrder;\n    return [...Object.keys(collection.properties), ...(collection.additionalFields ?? []).map(field => field.key)];\n}\n","import { AuthController, Entity, EntityCollection, Permissions, User } from \"../types\";\nimport { fullPathToCollectionSegments } from \"./paths\";\n\nconst DEFAULT_PERMISSIONS = {\n    read: true,\n    edit: true,\n    create: true,\n    delete: true\n};\n\nexport function resolvePermissions<M extends Record<string, any>, UserType extends User>\n(collection: EntityCollection<M>,\n authController: AuthController<UserType>,\n path: string,\n entity: Entity<M> | null): Permissions | undefined {\n\n    const permission = collection.permissions;\n    if (permission === undefined) {\n        return DEFAULT_PERMISSIONS;\n    } else if (typeof permission === \"object\") {\n        return permission as Permissions;\n    } else if (typeof permission === \"function\") {\n        const pathSegments = fullPathToCollectionSegments(path);\n        return permission({\n            entity,\n            path,\n            user: authController.user,\n            authController,\n            collection,\n            pathSegments\n        });\n    }\n    console.error(\"Permissions:\", permission);\n    throw Error(\"New type of permission added and not mapped\");\n}\n\nexport function canEditEntity<M extends Record<string, any>, UserType extends User>\n(\n    collection: EntityCollection<M>,\n    authController: AuthController<UserType>,\n    path: string,\n    entity: Entity<M> | null): boolean {\n    return resolvePermissions(collection, authController, path, entity)?.edit ?? DEFAULT_PERMISSIONS.edit;\n}\n\nexport function canCreateEntity<M extends Record<string, any>, UserType extends User>\n(\n    collection: EntityCollection<M>,\n    authController: AuthController<UserType>,\n    path: string,\n    entity: Entity<M> | null): boolean {\n    return resolvePermissions(collection, authController, path, entity)?.create ?? DEFAULT_PERMISSIONS.create;\n}\n\nexport function canDeleteEntity<M extends Record<string, any>, UserType extends User>\n(\n    collection: EntityCollection<M>,\n    authController: AuthController<UserType>,\n    path: string,\n    entity: Entity<M> | null): boolean {\n    return resolvePermissions(collection, authController, path, entity)?.delete ?? DEFAULT_PERMISSIONS.delete;\n}\n\n// export function resolveCollectionsPermissions(roles: Role[]): Record<string, Permissions> {\n//     const collectionIds = Array.from(new Set(roles.flatMap(role => Object.keys(role.collections))));\n//     return collectionIds\n//         .map((colId) => {\n//             const rolesWithCollection = roles.filter((role) => colId in Object.keys(role.collections));\n//             return {\n//                 [colId]: rolesWithCollection\n//                     .map(role => role.collections[colId])\n//                     .reduce((permA, permB) => {\n//                         return {\n//                             read: permA.read ?? permB.read ?? false,\n//                             create: permA.create ?? permB.create ?? false,\n//                             edit: permA.edit ?? permB.edit ?? false,\n//                             delete: permA.delete ?? permB.delete ?? false\n//                         };\n//                     })\n//             };\n//         })\n//         .reduce((a, b) => ({ ...a, ...b }), {});\n// }\n","export const iconSynonyms = {\n    abc: \"alphabet character font letter symbol text type\",\n    access_alarm: \"clock time\",\n    access_alarms: \"clock time\",\n    accessibility: \"accessible body handicap help human people person user\",\n    accessibility_new: \"accessible arms body handicap help human people person user\",\n    accessible: \"accessibility body handicap help human people person user wheelchair\",\n    accessible_forward: \"accessibility body handicap help human people person wheelchair\",\n    access_time: \"clock time\",\n    account_balance: \"bank bill building card cash coin commerce court credit currency dollars finance money online payment structure temple transaction\",\n    account_balance_wallet: \"bank bill card cash coin commerce credit currency dollars finance money online payment transaction\",\n    account_box: \"avatar face human people person profile square thumbnail user\",\n    account_circle: \"avatar face human people person profile thumbnail user\",\n    account_tree: \"analytics chart connect data diagram flow infographic measure metrics process project sitemap square statistics structure tracking\",\n    ac_unit: \"air cold conditioner freeze snowflake temperature weather winter\",\n    adb: \"android bridge debug\",\n    add: \"+ create item new plus symbol\",\n    add_alarm: \"clock plus time\",\n    add_alert: \"+ active alarm announcement bell callout chime information new notifications notify plus reminder ring sound symbol\",\n    add_a_photo: \"+ camera lens new photography picture plus symbol\",\n    add_box: \"create new plus square symbol\",\n    add_business: \"+ bill building card cash coin commerce company credit currency dollars market money new online payment plus retail shopping storefront symbol\",\n    add_card: \"+ bill cash coin commerce cost credit currency dollars finance money new online payment plus price shopping symbol\",\n    add_chart: \"+ analytics bars data diagram infographic measure metrics new plus statistics symbol tracking\",\n    add_circle: \"+ create new plus\",\n    add_circle_outline: \"+ create new plus\",\n    add_comment: \"+ bubble chat communicate feedback message new plus speech symbol\",\n    add_ic_call: \"+ cell contact device hardware mobile new plus symbol telephone\",\n    add_link: \"attach clip new plus symbol\",\n    add_location: \"+ destination direction gps maps new pin place plus stop symbol\",\n    add_location_alt: \"+ destination direction maps new pin place plus stop symbol\",\n    add_moderator: \"+ certified new plus privacy private protection security shield symbol verified\",\n    add_photo_alternate: \"+ image landscape mountains new photography picture plus symbol\",\n    add_road: \"+ destination direction highway maps new plus stop street symbol traffic\",\n    add_shopping_cart: \"card cash checkout coin commerce credit currency dollars money online payment plus\",\n    add_task: \"+ approve check circle completed increase mark ok plus select tick yes\",\n    add_to_drive: \"+ app backup cloud data files folders gdrive google plus recovery storage\",\n    add_to_home_screen: \"Android add arrow cell device hardware iOS mobile phone tablet to up\",\n    add_to_photos: \"collection image landscape mountains photography picture plus\",\n    add_to_queue: \"+ Android backlog chrome desktop device display hardware iOS lineup mac monitor new plus screen symbol television watch web window\",\n    adf_scanner: \"document feeder machine office\",\n    adjust: \"alter center circles control dot edit filter fix image mix move setting slider sort switch target tune\",\n    admin_panel_settings: \"account avatar certified face human people person privacy private profile protection security shield user verified\",\n    ad_units: \"Android banner cell device hardware iOS mobile notifications phone tablet top\",\n    agriculture: \"automobile cars cultivation farm harvest maps tractor transport travel truck vehicle\",\n    air: \"blowing breeze flow wave weather wind\",\n    airlines: \"airplane airport flight transportation travel trip\",\n    airline_seat_flat: \"bed body business class first human people person rest sleep travel\",\n    airline_seat_flat_angled: \"bed body business class first human people person rest sleep travel\",\n    airline_seat_individual_suite: \"bed body business class first human people person rest sleep travel\",\n    airline_seat_legroom_extra: \"body feet human people person sitting space travel\",\n    airline_seat_legroom_normal: \"body feet human people person sitting space travel\",\n    airline_seat_legroom_reduced: \"body feet human people person sitting space travel\",\n    airline_seat_recline_extra: \"body feet human legroom people person sitting space travel\",\n    airline_seat_recline_normal: \"body extra feet human legroom people person sitting space travel\",\n    airline_stops: \"arrow destination direction layover location maps place transportation travel trip\",\n    airplanemode_active: \"flight flying on signal\",\n    airplanemode_inactive: \"airport disabled enabled flight flying maps offline slash transportation travel\",\n    airplane_ticket: \"airport boarding flight fly maps pass transportation travel\",\n    airplay: \"apple arrow cast connect control desktop device display monitor screen signal television tv\",\n    airport_shuttle: \"automobile bus cars commercial delivery direction maps mini public transportation travel truck van vehicle\",\n    alarm: \"alart bell clock countdown date notification schedule time\",\n    alarm_add: \"+ alart bell clock countdown date new notification plus schedule symbol time\",\n    alarm_off: \"alart bell clock disabled duration enabled notification slash stop timer watch\",\n    alarm_on: \"alart bell checkmark clock disabled duration enabled notification off ready slash start timer watch\",\n    album: \"artist audio bvb cd computer data disk file music play record sound storage track vinyl\",\n    align_horizontal_center: \"alignment format layout lines paragraph rules style text\",\n    align_horizontal_left: \"alignment format layout lines paragraph rules style text\",\n    align_horizontal_right: \"alignment format layout lines paragraph rules style text\",\n    align_vertical_bottom: \"alignment format layout lines paragraph rules style text\",\n    align_vertical_center: \"alignment format layout lines paragraph rules style text\",\n    align_vertical_top: \"alignment format layout lines paragraph rules style text\",\n    all_inbox: \"Inbox delivered delivery email letter message post send\",\n    all_inclusive: \"endless forever infinite infinity loop mobius neverending strip sustainability sustainable\",\n    all_out: \"arrows circle directional expand shape\",\n    alternate_email: \"@ address contact tag\",\n    alt_route: \"alternate alternative arrows direction maps navigation options other routes split symbol\",\n    analytics: \"assessment bar chart data diagram infographic measure metrics statistics tracking\",\n    anchor: \"google logo\",\n    android: \"brand character logo mascot operating system toy\",\n    animation: \"circles film motion movement movie moving sequence video\",\n    announcement: \"! alert attention balloon bubble caution chat comment communicate danger error exclamation feedback important mark message news notification speech symbol warning\",\n    aod: \"Android always device display hardware homescreen iOS mobile phone tablet\",\n    apartment: \"accommodation architecture building city company estate flat home house office places real residence residential shelter units workplace\",\n    api: \"developer development enterprise software\",\n    app_blocking: \"Android applications cancel cell device hardware iOS mobile phone stopped tablet\",\n    app_registration: \"apps edit pencil register\",\n    approval: \"apply approvals approve certificate certification disapproval drive file impression ink mark postage stamp\",\n    apps: \"all applications circles collection components dots grid homescreen icons interface squares ui ux\",\n    app_settings_alt: \"Android applications cell device gear hardware iOS mobile phone tablet\",\n    app_shortcut: \"bookmarked favorite highlight important mobile saved software special star\",\n    apps_outage: \"all applications circles collection components dots grid interface squares ui ux\",\n    architecture: \"art compass design drawing engineering geometric tool\",\n    archive: \"inbox mail store\",\n    arrow_back: \"application components direction interface left navigation previous screen ui ux website\",\n    arrow_back_ios: \"application chevron components direction interface left navigation previous screen ui ux website\",\n    arrow_back_ios_new: \"application chevron components direction interface left navigation previous screen ui ux website\",\n    arrow_circle_down: \"direction navigation\",\n    arrow_circle_up: \"direction navigation\",\n    arrow_downward: \"application components direction interface navigation screen ui ux website\",\n    arrow_drop_down: \"application components direction interface navigation screen ui ux website\",\n    arrow_drop_down_circle: \"application components direction interface navigation screen ui ux website\",\n    arrow_drop_up: \"application components direction interface navigation screen ui ux website\",\n    arrow_forward: \"application arrows components direction interface navigation right screen ui ux website\",\n    arrow_forward_ios: \"application chevron components direction interface navigation next right screen ui ux website\",\n    arrow_left: \"application backstack backward components direction interface navigation previous screen ui ux website\",\n    arrow_right: \"application components continue direction forward interface navigation screen ui ux website\",\n    arrow_right_alt: \"arrows direction east navigation pointing shape\",\n    arrow_upward: \"application components direction interface navigation screen submit ui ux website\",\n    article: \"clarify document file news page paper text writing\",\n    art_track: \"album artist audio display format image insert music photography picture sound tracks\",\n    aspect_ratio: \"expand image monitor resize resolution scale screen square\",\n    assessment: \"analytics bars chart data diagram infographic measure metrics report statistics tracking\",\n    assignment: \"article clipboard document task text writing\",\n    assignment_ind: \"account clipboard document face people person profile task user\",\n    assignment_late: \"! alert announcement attention caution clipboard danger document error exclamation important mark notification symbol task warning\",\n    assignment_return: \"arrow back clipboard document left point retun task\",\n    assignment_returned: \"arrow clipboard document down point task\",\n    assignment_turned_in: \"approve checkmark clipboard complete document done finished ok select task tick validate verified yes\",\n    assistant: \"bubble chat comment communicate feedback message recommendation speech star suggestion twinkle\",\n    assistant_direction: \"destination location maps navigate navigation pin place right stop\",\n    assistant_photo: \"flag recommendation smart star suggestion\",\n    assured_workload: \"compliance confidential federal government regulatory secure sensitive\",\n    atm: \"alphabet automated bill card cart cash character coin commerce credit currency dollars font letter machine money online payment shopping symbol teller text type\",\n    attach_email: \"attachment clip compose envelop letter link message send\",\n    attach_file: \"add item link mail media paperclip\",\n    attachment: \"compose file image item link paperclip\",\n    attach_money: \"bill card cash coin commerce cost credit currency dollars finance online payment price profit sale symbol\",\n    attractions: \"amusement entertainment ferris fun maps park places wheel\",\n    attribution: \"attribute body copyright copywriter human people person\",\n    audio_file: \"document key music note sound track\",\n    audiotrack: \"key music note sound\",\n    auto_awesome: \"adjust editing enhance filter image photography photos setting stars\",\n    auto_awesome_mosaic: \"adjust collage editing enhance filter grid image layout photographs photography photos pictures setting\",\n    auto_awesome_motion: \"adjust animation collage editing enhance filter image live photographs photography photos pictures setting video\",\n    auto_delete: \"bin can clock date garbage remove schedule time trash\",\n    auto_fix_high: \"adjust editing enhance erase magic modify pen stars tool wand\",\n    auto_fix_normal: \"edit erase magic modify stars wand\",\n    auto_fix_off: \"disabled edit enabled erase magic modify on slash stars wand\",\n    autofps_select: \"A alphabet character font frame frequency letter per rate seconds symbol text type\",\n    auto_graph: \"analytics chart data diagram infographic line measure metrics stars statistics tracking\",\n    auto_mode: \"around arrows direction inprogress loading navigation nest refresh renew rotate turn\",\n    autorenew: \"around arrows cached direction inprogress loader loading navigation pending refresh rotate status turn\",\n    auto_stories: \"audiobook flipping pages reading story\",\n    av_timer: \"clock countdown duration minutes seconds stopwatch\",\n    baby_changing_station: \"babies bathroom body children father human infant kids mother newborn people person toddler wc young\",\n    backpack: \"bookbag knapsack storage travel\",\n    backspace: \"arrow cancel clear correct delete erase remove\",\n    backup: \"arrow cloud data drive files folders point storage submit upload\",\n    backup_table: \"drive files folders format layout stack storage\",\n    badge: \"account avatar card certified employee face human identification name people person profile security user work\",\n    bakery_dining: \"bread breakfast brunch croissant food\",\n    balance: \"equal equilibrium equity impartiality justice parity stability. steadiness symmetry\",\n    balcony: \"architecture doors estate home house maps outside place real residence residential stay terrace window\",\n    ballot: \"bullet bulllet election list point poll vote\",\n    bar_chart: \"analytics anlytics data diagram infographic measure metrics statistics tracking\",\n    batch_prediction: \"bulb idea light\",\n    bathroom: \"closet home house place plumbing shower sprinkler wash water wc\",\n    bathtub: \"bathing bathroom clean home hotel human person shower travel\",\n    battery_alert: \"! attention caution cell charge danger error exclamation important mark mobile notification power symbol warning\",\n    battery_charging_full: \"cell charge lightening lightning mobile power thunderbolt\",\n    battery_full: \"cell charge mobile power\",\n    battery_saver: \"+ add charge charging new plus power symbol\",\n    battery_std: \"cell charge mobile plus power standard\",\n    battery_unknown: \"? assistance cell charge help information mark mobile power punctuation question support symbol\",\n    beach_access: \"parasol places summer sunny umbrella\",\n    bed: \"bedroom double full furniture home hotel house king night pillows queen rest size sleep\",\n    bedroom_baby: \"babies children home horse house infant kid newborn rocking toddler young\",\n    bedroom_child: \"children furniture home hotel house kid night pillows rest size sleep twin young\",\n    bedroom_parent: \"double full furniture home hotel house king master night pillows queen rest sizem sleep\",\n    bedtime: \"nightime sleep\",\n    bedtime_off: \"nightime sleep\",\n    beenhere: \"approve archive bookmark checkmark complete done favorite label library reading remember ribbon save select tag tick validate verified yes\",\n    bento: \"box dinner food lunch meal restaurant takeout\",\n    bike_scooter: \"automobile cars maps transportation vehicle vespa\",\n    biotech: \"chemistry laboratory microscope research science technology test\",\n    blender: \"appliance cooking electric juicer kitchen machine vitamix\",\n    blinds_closed: \"cover curtains nest shutter sunshade\",\n    block: \"allowed avoid banned cancel close disable entry exit not prohibited quit remove stop\",\n    bloodtype: \"donate droplet emergency hospital medicine negative positive water\",\n    bluetooth: \"cast connection device network paring streaming symbol wireless\",\n    bluetooth_audio: \"connection device music signal sound symbol\",\n    bluetooth_connected: \"cast connection device network paring streaming symbol wireless\",\n    bluetooth_disabled: \"cast connection device enabled network offline paring slash streaming symbol wireless\",\n    bluetooth_drive: \"automobile cars cast connection device maps paring streaming symbol transportation travel vehicle wireless\",\n    bluetooth_searching: \"connection device network paring symbol wireless\",\n    blur_circular: \"circle dots editing effect enhance filter\",\n    blur_linear: \"dots editing effect enhance filter\",\n    blur_off: \"disabled dots editing effect enabled enhance on slash\",\n    blur_on: \"disabled dots editing effect enabled enhance filter off slash\",\n    bolt: \"electric energy fast flash lightning power thunderbolt\",\n    book: \"blog bookmark favorite label library reading remember ribbon save tag\",\n    bookmark: \"archive favorite follow label library reading remember ribbon save tag\",\n    bookmark_add: \"+ favorite plus remember ribbon save symbol\",\n    bookmark_added: \"approve check complete done favorite remember save select tick validate verified yes\",\n    bookmark_border: \"archive favorite label library outline reading remember ribbon save tag\",\n    bookmark_remove: \"delete favorite minus remember ribbon save subtract\",\n    bookmarks: \"favorite label layers library multiple reading remember ribbon save stack tag\",\n    book_online: \"Android admission appointment cell device event hardware iOS mobile pass phone reservation tablet ticket\",\n    border_all: \"doc editing editor spreadsheet stroke text type writing\",\n    border_bottom: \"doc editing editor spreadsheet stroke text type writing\",\n    border_clear: \"doc editing editor spreadsheet stroke text type writing\",\n    border_color: \"all create doc editing editor marker pencil spreadsheet stroke text type writing\",\n    border_horizontal: \"doc editing editor spreadsheet stroke text type writing\",\n    border_inner: \"doc editing editor spreadsheet stroke text type writing\",\n    border_left: \"doc editing editor spreadsheet stroke text type writing\",\n    border_outer: \"doc editing editor spreadsheet stroke text type writing\",\n    border_right: \"doc editing editor spreadsheet stroke text type writing\",\n    border_style: \"color doc editing editor spreadsheet stroke text type writing\",\n    border_top: \"doc editing editor spreadsheet stroke text type writing\",\n    border_vertical: \"doc editing editor spreadsheet stroke text type writing\",\n    boy: \"body gender human male people person social symbol\",\n    branding_watermark: \"components copyright design emblem format identity interface layout logo screen stamp ui ux website window\",\n    breakfast_dining: \"bakery bread butter food toast\",\n    brightness_1: \"circle control crescent cresent level moon screen\",\n    brightness_2: \"circle control crescent cresent level moon night screen\",\n    brightness_3: \"circle control crescent cresent level moon night screen\",\n    brightness_4: \"circle control crescent cresent dark level moon night screen sun\",\n    brightness_5: \"circle control crescent cresent level moon screen sun\",\n    brightness_6: \"circle control crescent cresent level moon screen sun\",\n    brightness_7: \"circle control crescent cresent level light moon screen sun\",\n    brightness_auto: \"A control display level mobile monitor phone screen\",\n    brightness_high: \"auto control mobile monitor phone\",\n    brightness_low: \"auto control mobile monitor phone\",\n    brightness_medium: \"auto control mobile monitor phone\",\n    broken_image: \"corrupt error landscape mountains photography picture torn\",\n    browser_not_supported: \"disabled enabled internet off on page screen slash website www\",\n    browser_updated: \"Android arrow chrome desktop device display download hardware iOS mac monitor screen web window\",\n    brunch_dining: \"breakfast champagne champaign drink food lunch meal\",\n    brush: \"art design draw editing painting tool\",\n    bubble_chart: \"analytics bars data diagram infographic measure metrics statistics tracking\",\n    bug_report: \"animal file fix insect issue problem testing ticket virus warning\",\n    build: \"adjust fix repair spanner tool wrench\",\n    build_circle: \"adjust fix repair tool wrench\",\n    bungalow: \"architecture cottage estate home house maps place real residence residential stay traveling\",\n    burst_mode: \"image landscape mountains multiple photography picture\",\n    bus_alert: \"! attention automobile cars caution danger error exclamation important maps mark notification symbol transportation vehicle warning\",\n    business: \"address apartment architecture building company estate flat home office place real residence residential shelter structure\",\n    business_center: \"baggage briefcase places purse suitcase work\",\n    cabin: \"architecture camping cottage estate home house log maps place real residence residential stay traveling wood\",\n    cable: \"connection device electronics usb wire\",\n    cached: \"around arrows inprogress loader loading refresh reload renew rotate\",\n    cake: \"baked birthday candles celebration dessert food frosting party pastries pastry pie social sweet\",\n    calculate: \"+ - = calculator count finance math\",\n    calendar_today: \"date event month remember reminder schedule week\",\n    calendar_view_day: \"date event format grid layout month remember reminder schedule today week\",\n    calendar_view_month: \"date event format grid layout schedule today\",\n    calendar_view_week: \"date event format grid layout month schedule today\",\n    call: \"cell contact device hardware mobile talk telephone\",\n    call_end: \"cell contact device hardware mobile talk telephone\",\n    call_made: \"arrow device mobile\",\n    call_merge: \"arrow device mobile\",\n    call_missed: \"arrow device mobile\",\n    call_missed_outgoing: \"arrow device mobile\",\n    call_received: \"arrow device mobile\",\n    call_split: \"arrow device mobile\",\n    call_to_action: \"alert bar components cta design information interface layout message notification screen ui ux website window\",\n    camera: \"album aperture lens photography picture record screenshot shutter\",\n    camera_alt: \"image photography picture\",\n    camera_enhance: \"important lens photography picture quality special star\",\n    camera_front: \"body human lens mobile person phone photography portrait selfie\",\n    camera_indoor: \"architecture building estate filming home house image inside motion nest picture place real residence residential shelter videography\",\n    camera_outdoor: \"architecture building estate filming home house image motion nest outside picture place real residence residential shelter videography\",\n    camera_rear: \"front lens mobile phone photography picture portrait selfie\",\n    camera_roll: \"film image library photography\",\n    cameraswitch: \"arrows flip rotate swap view\",\n    campaign: \"alert announcement loud megaphone microphone notification speaker\",\n    cancel: \"circle close cross disable exit status stop\",\n    cancel_presentation: \"close device exit no quit remove screen share slide stop website window\",\n    cancel_schedule_send: \"email no quit remove share stop x\",\n    candlestick_chart: \"analytics data diagram finance infographic measure metrics statistics tracking\",\n    card_giftcard: \"account balance bill cart cash certificate coin commerce creditcard currency dollars money online payment present shopping\",\n    card_membership: \"bill bookmark cash certificate coin commerce cost creditcard currency dollars finance loyalty money online payment shopping subscription\",\n    card_travel: \"bill cash coin commerce cost creditcard currency dollars finance membership miles money online payment trip\",\n    carpenter: \"building construction cutting handyman repair saw tool\",\n    car_rental: \"automobile cars key maps transportation vehicle\",\n    car_repair: \"automobile cars maps transportation vehicle\",\n    cases: \"baggage briefcase business purse suitcase\",\n    casino: \"dice dots entertainment gamble gambling games luck places\",\n    cast: \"Android airplay chromecast connect desktop device display hardware iOS mac monitor screencast streaming television tv web window wireless\",\n    cast_connected: \"Android airplay chromecast desktop device display hardware iOS mac monitor screencast streaming television tv web window wireless\",\n    cast_for_education: \"Android airplay chrome connect desktop device display hardware iOS learning lessons mac monitor screencast streaming teaching television tv web window wireless\",\n    category: \"categories circle collection items product sort square triangle\",\n    celebration: \"activity birthday event fun party\",\n    cell_tower: \"broadcast casting network signal transmitting wireless\",\n    cell_wifi: \"connection data internet mobile network phone service signal wireless\",\n    center_focus_strong: \"camera image lens photography zoom\",\n    center_focus_weak: \"camera image lens photography zoom\",\n    chair: \"comfort couch decoration furniture home house living lounging loveseat room seating sofa\",\n    chair_alt: \"cahir furniture home house kitchen lounging seating table\",\n    chalet: \"architecture cottage estate home house maps place real residence residential stay traveling\",\n    change_circle: \"around arrows direction navigation rotate\",\n    change_history: \"shape triangle\",\n    charging_station: \"Android battery cell device electric hardware iOS lightning mobile phone tablet thunderbolt\",\n    chat: \"bubble comment communicate feedback message speech talk text\",\n    chat_bubble: \"comment communicate feedback message speech talk text\",\n    chat_bubble_outline: \"comment communicate feedback message speech talk text\",\n    check: \"checkmark complete confirm correct done enter okay purchased select success tick yes\",\n    check_box: \"approved button checkmark component control form ok selected selection square success tick toggle ui yes\",\n    check_box_outline_blank: \"button checkmark component control deselected empty form selection square tick toggle ui\",\n    check_circle: \"approve checkmark complete done download finished ok select success tick upload validate verified yes\",\n    check_circle_outline: \"approve checkmark complete done finished ok select success tick validate verified yes\",\n    checkroom: \"check closet clothes coat hanger\",\n    chevron_left: \"arrows back direction triangle\",\n    chevron_right: \"arrows direction forward triangle\",\n    child_care: \"babies baby children face infant kids newborn toddler young\",\n    child_friendly: \"baby care carriage children infant kid newborn stroller toddler young\",\n    chrome_reader_mode: \"text\",\n    circle: \"bullet button dot full geometry moon period radio\",\n    circle_notifications: \"active alarm alert bell chime notify reminder ring sound\",\n    class: \"archive bookmark category favorite item label library reading remember ribbon save tag\",\n    clean_hands: \"bacteria disinfect germs gesture sanitizer\",\n    cleaning_services: \"dust sweep\",\n    clear: \"allowed back cancel correct cross delete disable erase exit not times\",\n    clear_all: \"delete document erase format lines list notifications wipe\",\n    close: \"allowed cancel cross disable exit not status stop times\",\n    closed_caption: \"accessible alphabet character decoder font language letter media movies subtitles symbol text tv type\",\n    closed_caption_disabled: \"accessible alphabet character decoder enabled font language letter media movies off slash subtitles symbol text tv type\",\n    closed_caption_off: \"accessible alphabet character decoder font language letter media movies outline subtitles symbol text tv type\",\n    close_fullscreen: \"action arrows collapse direction minimize\",\n    cloud: \"connection internet network sky upload weather\",\n    cloud_circle: \"application backup connection drive files folders internet network sky storage upload\",\n    cloud_done: \"application approve backup checkmark complete connection drive files folders internet network ok select sky storage tick upload validate verified yes\",\n    cloud_download: \"application arrow backup connection drive files folders internet network sky storage upload\",\n    cloud_off: \"application backup connection disabled drive enabled files folders internet network offline sky slash storage upload\",\n    cloud_queue: \"connection internet network sky upload\",\n    cloud_sync: \"application around backup connection drive files folders inprogress internet loading network refresh renew rotate sky storage turn upload\",\n    cloud_upload: \"application arrow backup connection download drive files folders internet network sky storage\",\n    co2: \"carbon dioxide gas\",\n    code: \"brackets css developer engineering html parenthesis platform\",\n    code_off: \"brackets css developer disabled enabled engineering html on platform slash\",\n    coffee: \"beverage cup drink mug plate set tea\",\n    coffee_maker: \"appliances beverage cup drink machine mug\",\n    collections: \"album gallery image landscape library mountains photography picture stack\",\n    collections_bookmark: \"album archive favorite gallery label library reading remember ribbon save stack tag\",\n    colorize: \"color dropper extract eye picker pipette tool\",\n    color_lens: \"art paint pallet\",\n    comment: \"bubble chat communicate document feedback message note outline speech\",\n    comment_bank: \"archive bookmark bubble cchat communicate favorite label library message remember ribbon save speech tag\",\n    comments_disabled: \"bubble chat communicate enabled feedback message offline on slash speech\",\n    commit: \"accomplish bind circle dedicate execute line perform pledge\",\n    commute: \"automobile car direction maps public train transportation trip vehicle\",\n    compare: \"adjustment editing edits enhance fix images photography photos scan settings\",\n    compare_arrows: \"collide directional facing left pointing pressure push right together\",\n    compass_calibration: \"connection internet location maps network refresh service signal wifi wireless\",\n    compress: \"arrows collide pressure push together\",\n    computer: \"Android chrome desktop device hardware iOS laptop mac monitor pc web window\",\n    confirmation_number: \"admission entertainment event ticket\",\n    connected_tv: \"Android airplay chrome desktop device display hardware iOS mac monitor screencast streaming television web window wireless\",\n    connecting_airports: \"airplanes flight transportation travel trip\",\n    connect_without_contact: \"communicating distance people signal socialize\",\n    construction: \"build carpenter equipment fix hammer improvement industrial industry repair tools wrench\",\n    contactless: \"applepay bluetooth cash connection connectivity credit device finance payment signal tap transaction wifi wireless\",\n    contact_mail: \"account address avatar communicate email face human information message people person profile user\",\n    contact_page: \"account avatar data document drive face folders human people person profile sheet slide storage user writing\",\n    contact_phone: \"account avatar call communicate face human information message mobile number people person profile user\",\n    contacts: \"account address avatar call cell face human information mobile number people person phone profile user\",\n    contact_support: \"? alert announcement bubble chat comment communicate help information mark message punctuation speech symbol vquestion\",\n    content_copy: \"copy document duplicate file multiple past\",\n    content_cut: \"cut document file past scissors trim\",\n    content_paste: \"clipboard copy cut document file multiple\",\n    content_paste_go: \"clipboard disabled document enabled file slash\",\n    content_paste_off: \"clipboard disabled document enabled file slash\",\n    content_paste_search: \"clipboard document file find trace track\",\n    contrast: \"black editing effect filter grayscale images photography pictures settings white\",\n    control_camera: \"adjust arrows center direction left move right\",\n    control_point: \"+ add circle plus\",\n    control_point_duplicate: \"+ add circle multiple new plus symbol\",\n    co_present: \"arrow co-present presentation screen share slides togather website\",\n    copy_all: \"content cut document file multiple page paper past\",\n    copyright: \"alphabet character circle emblem font legal letter owner symbol text\",\n    coronavirus: \"19 bacteria covid disease germs illness sick social\",\n    corporate_fare: \"architecture building business estate organization place real residence residential shelter\",\n    cottage: \"architecture beach estate home house lake lodge maps place real residence residential stay traveling\",\n    countertops: \"home house kitchen sink table\",\n    create: \"compose editing input item new pencil write writing\",\n    create_new_folder: \"+ add data directory document drive file plus sheet slide storage symbol\",\n    credit_card: \"bill cash charge coin commerce cost creditcard currency dollars finance information money online payment price shopping symbol\",\n    credit_card_off: \"charge commerce cost disabled enabled finance money online payment slash\",\n    credit_score: \"approve bill card cash check coin commerce complete cost currency dollars done finance loan mark money ok online payment select symbol tick validate verified yes\",\n    crib: \"babies baby bassinet bed children cradle infant kid newborn sleeping toddler\",\n    crop: \"adjustments area editing frame images photos rectangle settings size square\",\n    crop_din: \"adjustments area editing frame images photos picture rectangle settings size square\",\n    crop_free: \"adjustments barcode editing focus frame image photos qrcode settings size square zoom\",\n    crop_landscape: \"adjustments area editing frame images photos picture settings size square\",\n    crop_original: \"adjustments area editing frame images photos picture settings size square\",\n    crop_portrait: \"adjustments area editing frame images photos picture rectangle settings size square\",\n    crop_rotate: \"adjustments area arrows editing frame images photos settings size turn\",\n    crop_square: \"adjustments area editing frame images photos rectangle settings size\",\n    css: \"alphabet brackets character code developer engineering font html letter platform symbol text type\",\n    currency_exchange: \"360 around arrows cash coin commerce direction dollars inprogress money pay renew rotate sync turn universal\",\n    currency_franc: \"bill card cash coin commerce cost credit dollars finance money online payment price shopping symbol\",\n    currency_lira: \"bill card cash coin commerce cost credit dollars finance money online payment price shopping symbol\",\n    currency_pound: \"bill card cash coin commerce cost credit dollars finance money online payment price shopping symbol\",\n    currency_ruble: \"bill card cash coin commerce cost credit dollars finance money online payment price shopping symbol\",\n    currency_rupee: \"bill card cash coin commerce cost credit dollars finance money online payment price shopping symbol\",\n    currency_yen: \"bill card cash coin commerce cost credit dollars finance money online payment price shopping symbol\",\n    currency_yuan: \"bill card cash coin commerce cost credit dollars finance money online payment price shopping symbol\",\n    curtains: \"blinds cover nest open shutter sunshade\",\n    curtains_closed: \"blinds cover nest shutter sunshade\",\n    dangerous: \"broken fix no sign stop update warning wrong\",\n    dark_mode: \"application device interface moon night silent theme ui ux website\",\n    dashboard: \"cards format layout rectangle shapes square website\",\n    dashboard_customize: \"cards format layout rectangle shapes square website\",\n    data_saver_off: \"analytics bars chart diagram donut infographic measure metrics ring statistics tracking\",\n    data_saver_on: \"+ add analytics chart diagram infographic measure metrics new plus ring statistics symbol tracking\",\n    data_thresholding: \"hidden privacy thresold\",\n    data_usage: \"analytics chart circle diagram infographic measure metrics statistics tracking\",\n    date_range: \"agenda calendar event month remember reminder schedule time today week\",\n    deblur: \"adjust editing enhance face image lines photography sharpen\",\n    deck: \"chairs furniture garden home house outdoors outside patio social terrace umbrella yard\",\n    dehaze: \"adjust editing enhance image lines photography remove\",\n    delete: \"bin garbage junk recycle remove trashcan\",\n    delete_forever: \"bin cancel exit garbage junk recycle remove trashcan\",\n    delete_outline: \"bin can garbage remove trash\",\n    delete_sweep: \"bin garbage junk recycle remove trashcan\",\n    density_large: \"horizontal lines rules\",\n    density_medium: \"horizontal lines rules\",\n    density_small: \"horizontal lines rules\",\n    departure_board: \"automobile bus cars clock maps public schedule time transportation travel vehicle\",\n    description: \"article bill data document drive file folders invoice item notes page paper sheet slide text writing\",\n    desktop_access_disabled: \"Android apple chrome device display enabled hardware iOS mac monitor offline pc screen slash web window\",\n    desktop_mac: \"Android apple chrome device display hardware iOS monitor pc screen web window\",\n    desktop_windows: \"Android chrome device display hardware iOS mac monitor pc screen television tv web\",\n    details: \"editing enhance image photography sharpen triangle\",\n    developer_board: \"computer development devkit hardware microchip processor\",\n    developer_board_off: \"computer development disabled enabled hardware microchip on processor slash\",\n    developer_mode: \"Android bracket cell code development device engineer hardware iOS mobile phone tablet\",\n    device_hub: \"Android circle computer desktop hardware iOS laptop mobile monitor phone square tablet triangle watch wearable web\",\n    devices: \"Android computer desktop hardware iOS laptop mobile monitor phone tablet watch wearable web\",\n    devices_other: \"Android cell chrome desktop gadget hardware iOS ipad mac mobile monitor phone smartwatch tablet vr wearables window\",\n    device_thermostat: \"celsius fahrenheit temperature thermometer\",\n    device_unknown: \"? Android assistance cell hardware help iOS information mark mobile phone punctuation question support symbol tablet\",\n    dialer_sip: \"alphabet call cell character contact device font hardware initiation internet letter mobile over protocol routing session symbol telephone text type voice\",\n    dialpad: \"buttons call contact device dots mobile numbers phone\",\n    diamond: \"fashion gems jewelry logo retail valuables\",\n    difference: \"compare content copy cut document duplicate file multiple past\",\n    dining: \"cafeteria cutlery diner eating fork room spoon\",\n    dinner_dining: \"breakfast food fork lunch meal restaurant spaghetti utensils\",\n    directions: \"arrow maps naviate right route sign traffic\",\n    directions_bike: \"bicycle human maps person public route transportation\",\n    directions_boat: \"automobile cars ferry maps public transportation vehicle\",\n    directions_boat_filled: \"automobile cars ferry maps public transportation vehicle\",\n    directions_bus: \"automobile cars maps public transportation vehicle\",\n    directions_bus_filled: \"automobile cars maps public transportation vehicle\",\n    directions_car: \"automobile cars maps public transportation vehicle\",\n    directions_car_filled: \"automobile cars maps public transportation vehicle\",\n    directions_off: \"arrow disabled enabled maps right route sign slash traffic\",\n    directions_railway: \"automobile cars maps public train transportation vehicle\",\n    directions_railway_filled: \"automobile cars maps public train transportation vehicle\",\n    directions_run: \"body health human jogging maps people person route running walk\",\n    directions_subway: \"automobile cars maps public rail train transportation vehicle\",\n    directions_subway_filled: \"automobile cars maps public rail train transportation vehicle\",\n    directions_transit: \"automobile cars maps metro public rail subway train transportation vehicle\",\n    directions_transit_filled: \"automobile cars maps public rail subway train transportation vehicle\",\n    directions_walk: \"body human jogging maps people person route run\",\n    dirty_lens: \"camera photography picture splat\",\n    disabled_by_default: \"box cancel close exit no quit remove square stop\",\n    disc_full: \"! alert attention caution cd danger error exclamation important mark music notification storage symbol vinyl warning\",\n    display_settings: \"Android application change chrome desktop details device gear hardware iOS information mac monitor options personal screen service web window\",\n    dns: \"address bars domain information ip list lookup name network server system\",\n    dock: \"Android cell charger charging connector device hardware iOS mobile phone power station tablet\",\n    document_scanner: \"article data drive file folders notes page paper sheet slide text writing\",\n    do_disturb: \"cancel close denied deny remove silence stop\",\n    do_disturb_alt: \"cancel close denied deny remove silence stop\",\n    do_disturb_off: \"cancel close denied deny disabled enabled on remove silence slash stop\",\n    do_disturb_on: \"cancel close denied deny disabled enabled off remove silence slash stop\",\n    domain: \"apartment architecture building business estate home place real residence residential shelter web www\",\n    domain_add: \"+ apartment architecture building business estate home new place plus real residence residential shelter symbol web www\",\n    domain_disabled: \"apartment architecture building business company enabled estate home internet maps office offline on place real residence residential slash website\",\n    domain_verification: \"application approve check complete design desktop done interface internet layout mark ok screen select tick ui ux validate verified website window www yes\",\n    done: \"approve checkmark complete finished ok select success tick validate verified yes\",\n    done_all: \"approve checkmark complete finished layers multiple ok select stack success tick validate verified yes\",\n    done_outline: \"all approve checkmark complete finished ok select success tick validate verified yes\",\n    do_not_disturb: \"cancel close denied deny remove silence stop\",\n    do_not_disturb_alt: \"cancel close denied deny remove silence stop\",\n    do_not_disturb_off: \"cancel close denied deny disabled enabled on remove silence slash stop\",\n    do_not_disturb_on: \"cancel close denied deny disabled enabled off remove silence slash stop\",\n    do_not_disturb_on_total_silence: \"busy mute on quiet total\",\n    do_not_step: \"boot disabled enabled feet foot off on shoe slash sneaker\",\n    do_not_touch: \"disabled enabled fingers gesture hand off on slash\",\n    donut_large: \"analytics chart circle complete data diagram infographic inprogress, measure metrics pie statistics tracking\",\n    donut_small: \"analytics chart circle data diagram infographic inprogress measure metrics pie statistics tracking\",\n    door_back: \"closed doorway entrance exit home house\",\n    doorbell: \"alarm home house ringing\",\n    door_front: \"closed doorway entrance exit home house\",\n    door_sliding: \"automatic doorway double entrance exit glass home house two\",\n    double_arrow: \"arrows chevron direction multiple navigation right\",\n    downhill_skiing: \"athlete athletic body entertainment exercise hobby human people person ski snow social sports travel winter\",\n    download: \"arrow downloads drive install upload\",\n    download_done: \"arrows check downloads drive installed ok tick upload\",\n    download_for_offline: \"arrow circle for install offline upload\",\n    downloading: \"arrow circle downloads install pending progress upload\",\n    drafts: \"document email envelope file letter message read\",\n    drag_handle: \"application components design interface layout lines menu move screen ui ux website window\",\n    drag_indicator: \"application circles components design dots drop interface layout mobile monitor move phone screen shape shift tablet ui ux website window\",\n    drive_eta: \"automobile cars destination direction estimate maps public transportation travel trip vehicle\",\n    drive_file_move: \"arrows data direction document folders right sheet side slide storage\",\n    drive_file_rename_outline: \"compose create draft editing input pencil write writing\",\n    drive_folder_upload: \"arrow data document file sheet slide storage\",\n    dry: \"air bathroom dryer fingers gesture hand wc\",\n    dry_cleaning: \"hanger hotel laundry places service towel\",\n    duo: \"call chat conference device video\",\n    dvr: \"Android audio chrome computer desktop device display electronic hardware iOS laptop list mac monitor recorder screen tv video web window\",\n    dynamic_feed: \"layer live multiple post refresh update\",\n    dynamic_form: \"code electric fast lightning lists questionnaire thunderbolt\",\n    earbuds: \"accessory audio earphone headphone listen music sound\",\n    earbuds_battery: \"accessory audio charging earphone headphone listen music sound\",\n    east: \"arrow directional maps navigation right\",\n    edgesensor_high: \"Android cell device hardware iOS mobile move phone sensitivity tablet vibrate\",\n    edgesensor_low: \"Android cell device hardware iOS mobile move phone sensitivity tablet vibrate\",\n    edit: \"compose create editing input new pencil write writing\",\n    edit_attributes: \"approve attribution check complete done mark ok select tick validate verified yes\",\n    edit_location: \"destination direction gps maps pencil pin place stop write\",\n    edit_location_alt: \"pencil pin\",\n    edit_notifications: \"active alarm alert bell chime compose create draft editing input new notify pencil reminder ring sound write writing\",\n    edit_off: \"compose create disabled draft editing enabled input new offline on pencil slash write writing\",\n    edit_road: \"destination direction highway maps pencil street traffic\",\n    egg: \"breakfast brunch food\",\n    egg_alt: \"breakfast brunch food\",\n    eject: \"arrow disc drive dvd player remove triangle up usb\",\n    elderly: \"body cane human old people person senior\",\n    elderly_woman: \"body cane female gender girl human lady old people person senior social symbol women\",\n    electrical_services: \"charge cord plug power wire\",\n    electric_bike: \"automobile cars electricity maps scooter transportation travel vehicle vespa\",\n    electric_bolt: \"energy fast lightning nest thunderbolt\",\n    electric_car: \"automobile cars electricity maps transportation travel vehicle\",\n    electric_meter: \"energy fast lightning measure nest thunderbolt usage voltage volts\",\n    electric_moped: \"automobile bike cars maps scooter transportation travel vehicle vespa\",\n    electric_rickshaw: \"automobile cars india maps transportation truck vehicle\",\n    electric_scooter: \"automobile bike cars maps transportation vehicle vespa\",\n    elevator: \"body down human people person up\",\n    email: \"envelope letter message note post receive send write\",\n    e_mobiledata: \"alphabet font letter text type\",\n    emoji_emotions: \"emoticon expressions face feelings glad happiness happy like mood person pleased smiley smiling social survey\",\n    emoji_events: \"achievement award chalice champion cup first prize reward sport trophy winner\",\n    emoji_food_beverage: \"coffee cup dring drink mug plate set tea\",\n    emoji_nature: \"animal bee daisy flower honey insect ladybug petals spring summer\",\n    emoji_objects: \"creative idea lamp lightbulb solution thinking\",\n    emoji_people: \"arm body greeting human person social wave waving\",\n    emoji_symbols: \"ampersand character hieroglyph music note percent sign\",\n    emoji_transportation: \"architecture automobile building cars commute company direction estate maps office place public real residence residential shelter travel vehicle\",\n    energy_savings_leaf: \"eco leaves nest usage\",\n    engineering: \"body cogs cogwheel construction fixing gears hat helmet human maintenance people person setting worker\",\n    enhanced_encryption: \"+ add locked new password plus privacy private protection safety secure security symbol\",\n    equalizer: \"adjustment analytics chart data graph measure metrics music noise sound static statistics tracking volume\",\n    error: \"! alert announcement attention caution circle danger exclamation feedback important mark notification problem symbol warning\",\n    error_outline: \"! alert announcement attention caution circle danger exclamation feedback important mark notification problem symbol warning\",\n    escalator: \"down staircase up\",\n    escalator_warning: \"body child human kid parent people person\",\n    euro: \"bill card cash coin commerce cost credit currency dollars euros finance money online payment price profit shopping symbol\",\n    euro_symbol: \"bill card cash coin commerce cost credit currency dollars finance money online payment price profit\",\n    event: \"agenda calendar date item mark month range remember reminder today week\",\n    event_available: \"agenda approve calendar check complete done item mark ok schedule select tick time validate verified yes\",\n    event_busy: \"agenda calendar cancel close date exit item no remove schedule stop time unavailable\",\n    event_note: \"agenda calendar date item schedule text time writing\",\n    event_repeat: \"around calendar date day inprogress loading month refresh renew rotate schedule turn\",\n    event_seat: \"assigned bench chair furniture reservation row section sit\",\n    ev_station: \"automobile cars charge charging electricity filling fuel gasoline maps places power station transportation vehicle\",\n    exit_to_app: \"application arrow back components design export interface layout leave login logout mobile monitor move output phone pointing quit register right screen signin signout signup tablet ux website window\",\n    expand: \"arrows compress enlarge grow move push together\",\n    expand_circle_down: \"arrows chevron collapse direction expandable list more\",\n    expand_less: \"arrows chevron collapse direction expandable list up\",\n    expand_more: \"arrows chevron collapse direction down expandable list\",\n    explicit: \"adult alphabet character content font language letter media movies music parent rating supervision symbol text type\",\n    explore: \"compass destination direction east location maps needle north south travel west\",\n    explore_off: \"compass destination direction disabled east enabled location maps needle north slash south travel west\",\n    exposure: \"add brightness contrast editing effect image minus photography picture plus settings subtract\",\n    extension: \"add-ons app extended game item jigsaw piece plugin puzzle shape\",\n    extension_off: \"disabled enabled extended jigsaw piece puzzle shape slash\",\n    face: \"account avatar emoji eyes human login logout people person profile recognition security social thumbnail unlock user\",\n    face_retouching_natural: \"editing effect emoji emotion faces image photography settings star tag\",\n    face_retouching_off: \"disabled editing effect emoji emotion enabled faces image natural photography settings slash tag\",\n    fact_check: \"approve complete done list mark ok select tick validate verified yes\",\n    factory: \"industry manufacturing warehouse\",\n    family_restroom: \"bathroom children father kids mother parents wc\",\n    fastfood: \"drink hamburger maps meal places\",\n    fast_forward: \"control ff media music play speed time tv video\",\n    fast_rewind: \"back control media music play speed time tv video\",\n    favorite: \"appreciate health heart like love remember save shape success\",\n    favorite_border: \"health heart like love outline remember save shape success\",\n    fax: \"machine office phone send\",\n    featured_play_list: \"audio collection highlighted item music playlist recommended\",\n    featured_video: \"advertisement advertisment highlighted item play recommended watch,advertised\",\n    feed: \"article headline information newspaper public social timeline\",\n    feedback: \"! alert announcement attention bubble caution chat comment communicate danger error exclamation important mark message notification speech symbol warning\",\n    female: \"gender girl lady social symbol woman women\",\n    fence: \"backyard barrier boundaries boundary home house protection\",\n    festival: \"circus event local maps places tent tour travel\",\n    fiber_dvr: \"alphabet character digital electronics font letter network recorder symbol text tv type video\",\n    fiber_manual_record: \"circle dot play watch\",\n    fiber_new: \"alphabet character font letter network symbol text type\",\n    fiber_pin: \"alphabet character font letter network symbol text type\",\n    fiber_smart_record: \"circle dot play watch\",\n    file_copy: \"bill clone content cut document duplicate invoice item multiple page past\",\n    file_download: \"arrows downloads drive export install upload\",\n    file_download_done: \"arrows check downloads drive installed tick upload\",\n    file_download_off: \"arrow disabled drive enabled export install on save slash upload\",\n    file_open: \"arrow document drive left page paper\",\n    file_present: \"clip data document drive folders note paper reminder sheet slide storage writing\",\n    file_upload: \"arrows download drive export\",\n    filter: \"editing effect image landscape mountains photography picture settings\",\n    filter_1: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_2: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_3: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_4: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_5: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_6: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_7: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_8: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_9: \"digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_9_plus: \"+ digit editing effect images multiple number photography pictures settings stack symbol\",\n    filter_alt: \"edit funnel options refine sift\",\n    filter_alt_off: \"[offline] disabled edit funnel options refine sift slash\",\n    filter_b_and_w: \"black contrast editing effect grayscale images photography pictures settings white\",\n    filter_center_focus: \"camera dot edit image photography picture\",\n    filter_drama: \"camera cloud editing effect image photography picture sky\",\n    filter_frames: \"boarders border camera center editing effect filters focus image options photography picture\",\n    filter_hdr: \"camera editing effect image mountains photography picture\",\n    filter_list: \"lines organize sort\",\n    filter_list_off: \"[offline] alt disabled edit options refine sift slash\",\n    filter_none: \"multiple stack\",\n    filter_tilt_shift: \"blur center editing effect focus images photography pictures\",\n    filter_vintage: \"editing effect flower images photography pictures\",\n    find_in_page: \"data document drive file folders glass look magnifying paper search see sheet slide writing\",\n    find_replace: \"around arrows glass inprogress loading look magnifying refresh renew rotate search see\",\n    fingerprint: \"biometrics identification identity reader thumbprint touchid verification\",\n    fire_extinguisher: \"emergency water\",\n    fireplace: \"chimney flame home house living pit room warm winter\",\n    first_page: \"arrow back chevron left rewind\",\n    fitness_center: \"athlete dumbbell exercise gym health hobby places sport weights workout\",\n    fit_screen: \"enlarge format layout reduce scale size\",\n    flag: \"country goal mark nation report start\",\n    flag_circle: \"country goal mark nation report round start\",\n    flaky: \"approve check close complete contrast done exit mark no ok options select stop tick verified yes\",\n    flare: \"bright editing effect images lensflare light photography pictures shine sparkle star sun\",\n    flash_auto: \"camera electric fast lightning thunderbolt\",\n    flashlight_off: \"disabled enabled on slash\",\n    flashlight_on: \"disabled enabled off slash\",\n    flash_off: \"camera disabled electric enabled fast lightning on slash thunderbolt\",\n    flash_on: \"camera disabled electric enabled fast lightning off slash thunderbolt\",\n    flatware: \"cafeteria cutlery diner dining eating fork room spoon\",\n    flight: \"airplane airport flying transportation travel trip\",\n    flight_class: \"airplane business first seat transportation travel trip window\",\n    flight_land: \"airplane airport arrival arriving flying landing transportation travel\",\n    flight_takeoff: \"airplane airport departed departing flying landing transportation travel\",\n    flip: \"editing image orientation scanning\",\n    flip_camera_android: \"center editing front image mobile orientation rear reverse rotate turn\",\n    flip_camera_ios: \"android editing front image mobile orientation rear reverse rotate turn\",\n    flip_to_back: \"arrangement format front layout move order sort\",\n    flip_to_front: \"arrangement back format layout move order sort\",\n    flutter_dash: \"bird mascot\",\n    fmd_bad: \"! alert attention caution danger destination direction error exclamation important location maps mark notification pin place symbol warning\",\n    fmd_good: \"destination direction location maps pin place stop\",\n    folder: \"data directory document drive file folders sheet slide storage\",\n    folder_delete: \"bin can data document drive file folders garbage remove sheet slide storage trash\",\n    folder_off: \"[online] data disabled document drive enabled file folders sheet slash slide storage\",\n    folder_open: \"data directory document drive file folders sheet slide storage\",\n    folder_shared: \"account collaboration data directory document drive face human people person profile sheet slide storage team user\",\n    folder_special: \"bookmark data directory document drive favorite file highlight important marked saved shape sheet slide star storage\",\n    folder_zip: \"compress data document drive file folders open sheet slide storage\",\n    follow_the_signs: \"arrow body directional human people person right social\",\n    font_download: \"A alphabet character letter square symbol text type\",\n    font_download_off: \"alphabet character disabled enabled letter slash square symbol text type\",\n    food_bank: \"architecture building charity eat estate fork house knife meal place real residence residential shelter utensils\",\n    forest: \"jungle nature plantation plants trees woodland\",\n    fork_left: \"arrows directions maps navigation path route sign traffic\",\n    fork_right: \"arrows directions maps navigation path route sign traffic\",\n    format_align_center: \"alignment doc editing editor lines spreadsheet text type writing\",\n    format_align_justify: \"alignment density doc editing editor extra lines small spreadsheet text type writing\",\n    format_align_left: \"alignment doc editing editor lines spreadsheet text type writing\",\n    format_align_right: \"alignment doc editing editor lines spreadsheet text type writing\",\n    format_bold: \"B alphabet character doc editing editor font letter spreadsheet styles symbol text type writing\",\n    format_clear: \"T alphabet character disabled doc editing editor enabled font letter off slash spreadsheet style symbol text type writing\",\n    format_color_fill: \"bucket doc editing editor paint spreadsheet style text type writing\",\n    format_color_reset: \"clear disabled doc droplet editing editor enabled fill liquid off on paint slash spreadsheet style text type water writing\",\n    format_color_text: \"doc editing editor fill paint spreadsheet style type writing\",\n    format_indent_decrease: \"alignment doc editing editor indentation paragraph spreadsheet text type writing\",\n    format_indent_increase: \"alignment doc editing editor indentation paragraph spreadsheet text type writing\",\n    format_italic: \"alphabet character doc editing editor font letter spreadsheet style symbol text type writing\",\n    format_line_spacing: \"alignment doc editing editor spreadsheet text type writing\",\n    format_list_bulleted: \"alignment doc editing editor notes spreadsheet task text todo type writing\",\n    format_list_numbered: \"alignment digit doc editing editor notes spreadsheet symbol task text todo type writing\",\n    format_list_numbered_rtl: \"alignment digit doc editing editor notes spreadsheet symbol task text todo type writing\",\n    format_overline: \"alphabet character doc editing editor font letter spreadsheet style symbol text type under writing\",\n    format_paint: \"brush color doc editing editor fill paintroller spreadsheet style text type writing\",\n    format_quote: \"doc editing editor quotation spreadsheet text type writing\",\n    format_shapes: \"alphabet character color doc editing editor fill font letter paint spreadsheet style symbol text type writing\",\n    format_size: \"alphabet character color doc editing editor fill font letter paint spreadsheet style symbol text type writing\",\n    format_strikethrough: \"alphabet character doc editing editor font letter spreadsheet style symbol text type writing\",\n    format_textdirection_l_to_r: \"alignment doc editing editor ltr paragraph spreadsheet type writing\",\n    format_textdirection_r_to_l: \"alignment doc editing editor paragraph rtl spreadsheet type writing\",\n    format_underlined: \"alphabet character doc editing editor font letter spreadsheet style symbol text type writing\",\n    forum: \"bubble chat comment communicate community conversation feedback hub messages speech talk\",\n    forward: \"arrow mail message playback right sent\",\n    forward_10: \"arrow circle controls digit fast music number play rotate seconds speed symbol time video\",\n    forward_30: \"arrow circle controls digit fast music number rotate seconds speed symbol time video\",\n    forward_5: \"10 arrow circle controls digit fast music number rotate seconds speed symbol time video\",\n    forward_to_inbox: \"arrow email envelop letter message send\",\n    foundation: \"architecture base basis building construction estate home house real residential\",\n    free_breakfast: \"beverage cafe coffee cup drink mug tea\",\n    fullscreen: \"adjust application components interface size ui ux view website\",\n    fullscreen_exit: \"adjust application components interface size ui ux view website\",\n    functions: \"average calculate count doc editing editor math sigma spreadsheet style sum text type writing\",\n    gamepad: \"buttons console controller device gaming playstation video\",\n    games: \"adjust arrows controller direction dpad gaming left move nintendo playstation right xbox\",\n    garage: \"automobile automotive cars direction maps transportation travel vehicle\",\n    gas_meter: \"droplet energy measure nest usage water\",\n    gavel: \"agreement contract court document government hammer judge law mallet official police rules terms\",\n    gesture: \"drawing finger gestures hand line motion\",\n    get_app: \"arrows downloads export install play pointing retrieve upload\",\n    gif: \"alphabet animated animation bitmap character font format graphics interchange letter symbol text type\",\n    gif_box: \"alphabet animated animation bitmap character font format graphics interchange letter symbol text type\",\n    girl: \"body female gender human lady people person social symbol woman women\",\n    gite: \"architecture estate home hostel house maps place real residence residential stay traveling\",\n    g_mobiledata: \"alphabet character font letter network service symbol text type\",\n    golf_course: \"athlete athletic ball club entertainment flag golfer golfing hobby hole places putt sports\",\n    gpp_bad: \"cancel certified close error exit no privacy private protection remove security shield sim stop verified\",\n    gpp_good: \"certified check ok pass security shield sim tick\",\n    gpp_maybe: \"! alert attention caution certified danger error exclamation important mark notification privacy private protection security shield sim symbol verified warning\",\n    gps_fixed: \"destination direction location maps pin place pointer stop tracking\",\n    gps_not_fixed: \"destination direction disabled enabled fixed location maps not off online place pointer slash tracking\",\n    gps_off: \"destination direction disabled enabled fixed location maps not offline place pointer slash tracking\",\n    grade: \"achievement important likes marked rated rating reward saved shape special star\",\n    gradient: \"color editing effect filter images photography pictures\",\n    grading: \"approve check complete document done feedback grade mark ok reviewed select tick validate verified writing yes\",\n    grain: \"dots editing effect filter images photography pictures\",\n    graphic_eq: \"audio equalizer music recording sound voice\",\n    grass: \"backyard fodder ground home lawn plant turf\",\n    grid_goldenratio: \"layout lines space\",\n    grid_off: \"collage disabled enabled image layout on slash view\",\n    grid_on: \"collage disabled enabled image layout off sheet slash view\",\n    grid_view: \"application blocks components dashboard design interface layout screen square tiles ui ux website window\",\n    group: \"accounts committee face family friends humans network people persons profiles social team users\",\n    group_add: \"accounts committee face family friends humans increase more network people persons plus profiles social team users\",\n    group_remove: \"accounts committee face family friends humans network people persons profiles social team users\",\n    groups: \"body club collaboration crowd gathering human meeting people person social teams\",\n    group_work: \"alliance circle collaboration film partnership reel teamwork together\",\n    g_translate: \"emblem google language logo mark speaking speech translator words\",\n    hail: \"body human people person pick public stop taxi transportation\",\n    handyman: \"build construction fix hammer repair screwdriver tools\",\n    hardware: \"break construction hammer nail repair tool\",\n    hd: \"alphabet character definition display font high letter movies quality resolution screen symbol text tv type video\",\n    hdr_auto: \"A alphabet camera character circle dynamic font high letter photo range symbol text type\",\n    hdr_auto_select: \"+ A alphabet camera character circle dynamic font high letter photo range symbol text type\",\n    hdr_enhanced_select: \"add alphabet character dynamic font high letter plus range symbol text type\",\n    hdr_off: \"alphabet character disabled dynamic enabled enhance font high letter range select slash symbol text type\",\n    hdr_off_select: \"alphabet camera character circle disabled dynamic enabled font high letter photo range slash symbol text type\",\n    hdr_on: \"add alphabet character dynamic enhance font high letter plus range select symbol text type\",\n    hdr_on_select: \"+ alphabet camera character circle dynamic font high letter photo range symbol text type\",\n    hdr_plus: \"+ add alphabet character circle dynamic enhance font high letter range select symbol text type\",\n    hdr_strong: \"circles dots dynamic enhance high range\",\n    hdr_weak: \"circles dots dynamic enhance high range\",\n    headphones: \"accessory audio device earphone headset listen music sound\",\n    headphones_battery: \"accessory audio charging device earphone headset listen music sound\",\n    headset: \"accessory audio device earbuds earmuffs earphone headphones listen music sound\",\n    headset_mic: \"accessory audio chat device earphone headphones listen music sound talk\",\n    headset_off: \"accessory audio chat device disabled earphone enabled headphones listen mic music slash sound talk\",\n    healing: \"bandage bandaid editing emergency fix health hospital image medicine\",\n    health_and_safety: \"+ add certified plus privacy private protection security shield symbol verified\",\n    hearing: \"accessibility accessible aid handicap help impaired listen sound volume\",\n    hearing_disabled: \"accessibility accessible aid enabled handicap help impaired listen off on slash sound volume\",\n    heart_broken: \"break core crush health nucleus split\",\n    heat_pump: \"air conditioner cool energy furnance nest usage\",\n    height: \"arrows color doc down editing editor fill format paint resize spreadsheet stretch style text type up writing\",\n    help: \"? alert announcement assistance circle information mark punctuation question shape support symbol\",\n    help_center: \"? assistance information mark punctuation question support symbol\",\n    help_outline: \"? alert announcement assistance circle information mark punctuation question shape support symbol\",\n    hevc: \"alphabet character coding efficiency font high letter symbol text type video\",\n    hexagon: \"shape sides six\",\n    hide_image: \"disabled enabled landscape mountains off on photography picture slash\",\n    hide_source: \"circle disabled enabled offline on shape slash\",\n    highlight: \"color doc editing editor emphasize fill flashlight format marker paint spreadsheet style text type writing\",\n    highlight_off: \"cancel circle clear click close delete disable exit focus no quit remove stop target times\",\n    high_quality: \"alphabet character definition display font hq letter movies resolution screen symbol text tv type\",\n    hiking: \"backpacking bag climbing duffle mountain social sports stick trail travel walking\",\n    history: \"arrow backwards clock date refresh renew reverse revert rotate schedule time turn undo\",\n    history_edu: \"document education feather letter paper pen quill school tools write writing\",\n    history_toggle_off: \"clock date schedule time\",\n    hls: \"alphabet character developer engineering font letter platform symbol text type\",\n    hls_off: \"[offline] alphabet character developer disabled enabled engineering font letter platform slash symbol text type\",\n    h_mobiledata: \"alphabet character font letter network service symbol text type\",\n    holiday_village: \"architecture beach camping cottage estate home house lake lodge maps place real residence residential stay traveling vacation\",\n    home: \"address application--house architecture building components design estate homepage interface layout place real residence residential screen shelter structure unit ux website window\",\n    home_max: \"device gadget hardware internet iot nest smart things\",\n    home_mini: \"Internet device gadget hardware iot nest smart things\",\n    home_repair_service: \"equipment fix kit mechanic repairing toolbox tools workshop\",\n    home_work: \"architecture building estate house office place real residence residential shelter\",\n    horizontal_rule: \"gmail line novitas\",\n    horizontal_split: \"bars format layout lines stacked\",\n    hotel: \"bed body human people person sleep stay travel trip\",\n    hot_tub: \"bathing bathroom bathtub hotel human jacuzzi person shower spa steam travel water\",\n    hourglass_bottom: \"countdown half loading minutes time waiting\",\n    hourglass_disabled: \"clock countdown empty enabled loading minutes off on slash time waiting\",\n    hourglass_empty: \"countdown loading minutes start time waiting\",\n    hourglass_full: \"countdown loading minutes time waiting\",\n    hourglass_top: \"countdown half loading minutes time waiting\",\n    house: \"architecture building estate family homepage places real residence residential shelter\",\n    houseboat: \"architecture beach estate floating home maps place real residence residential sea stay traveling vacation\",\n    house_siding: \"architecture building construction estate exterior facade home real residential\",\n    how_to_reg: \"approve ballot check complete done election mark ok poll register registration select tick to validate verified vote yes\",\n    how_to_vote: \"ballot election poll\",\n    h_plus_mobiledata: \"+ alphabet character font letter network service symbol text type\",\n    html: \"alphabet brackets character code css developer engineering font letter platform symbol text type\",\n    http: \"alphabet character font internet letter network symbol text transfer type url website\",\n    https: \"connection encrypt internet key locked network password privacy private protection safety secure security ssl web\",\n    hub: \"center connection core focal network nucleus point topology\",\n    hvac: \"air conditioning heating ventilation\",\n    icecream: \"dessert food snack\",\n    ice_skating: \"athlete athletic entertainment exercise hobby shoe skates social sports travel\",\n    image: \"disabled enabled frame hide landscape mountains off on photography picture slash\",\n    image_aspect_ratio: \"photography picture rectangle square\",\n    image_not_supported: \"disabled enabled landscape mountains off on photography picture slash\",\n    image_search: \"find glass landscape look magnifying mountains photography picture see\",\n    imagesearch_roller: \"art paint\",\n    important_devices: \"Android cell computer desktop hardware iOS mobile monitor phone star tablet web\",\n    import_contacts: \"address book friends information magazine open\",\n    import_export: \"arrows direction down explort up\",\n    inbox: \"archive email incoming message\",\n    indeterminate_check_box: \"application button components control design form interface minus screen selected selection square toggle ui undetermined ux website\",\n    info: \"about alert announcement announcment assistance bubble circle details help information service support\",\n    input: \"arrow box download login move right\",\n    insert_chart: \"analytics barchart bars data diagram infographic measure metrics statistics tracking\",\n    insert_chart_outlined: \"analytics bars data diagram infographic measure metrics statistics tracking\",\n    insert_comment: \"add bubble chat feedback message\",\n    insert_drive_file: \"bill document format invoice item sheet slide\",\n    insert_emoticon: \"account emoji face happy human like people person profile sentiment smiley user\",\n    insert_invitation: \"agenda calendar date event mark month range remember reminder today week\",\n    insert_link: \"add anchor attach clip file mail media\",\n    insert_page_break: \"document file paper\",\n    insert_photo: \"image landscape mountains photography picture wallpaper\",\n    insights: \"analytics bars chart data diagram infographic measure metrics stars statistics tracking\",\n    install_desktop: \"Android chrome device display fix hardware iOS mac monitor place pwa screen web window\",\n    install_mobile: \"Android cell device hardware iOS phone pwa tablet\",\n    integration_instructions: \"brackets clipboard code css developer document engineering html platform\",\n    interests: \"circle heart shapes social square triangle\",\n    interpreter_mode: \"language microphone person speaking symbol\",\n    inventory: \"archive box buy check clipboard document e-commerce file list organize packages product purchase shop stock store supply\",\n    invert_colors: \"droplet editing hue inverted liquid palette tone water\",\n    invert_colors_off: \"disabled droplet enabled hue inverted liquid offline opacity palette slash tone water\",\n    ios_share: \"arrows button direction export internet link send sharing social up website\",\n    iron: \"appliance clothes electric ironing machine object\",\n    iso: \"add editing effect image minus photography picture plus sensor shutter speed subtract\",\n    javascript: \"alphabet brackets character code css developer engineering font html letter platform symbol text type\",\n    join_full: \"circle combine command left outter right sql\",\n    join_inner: \"circle command matching sql values\",\n    join_left: \"circle command matching sql values\",\n    join_right: \"circle command matching sql values\",\n    kayaking: \"athlete athletic body canoe entertainment exercise hobby human lake paddle paddling people person rafting river row social sports summer travel water\",\n    key: \"blackout password restricted secret unlock\",\n    keyboard: \"computer device hardware input keypad letter office text type\",\n    keyboard_alt: \"computer device hardware input keypad letter office text type\",\n    keyboard_arrow_down: \"arrows chevron open\",\n    keyboard_arrow_left: \"arrows chevron\",\n    keyboard_arrow_right: \"arrows chevron open start\",\n    keyboard_arrow_up: \"arrows chevron submit\",\n    keyboard_backspace: \"arrow left\",\n    keyboard_capslock: \"arrow up\",\n    keyboard_command_key: \"button command control key\",\n    keyboard_control_key: \"control key\",\n    keyboard_double_arrow_down: \"arrows direction multiple navigation\",\n    keyboard_double_arrow_left: \"arrows direction multiple navigation\",\n    keyboard_double_arrow_right: \"arrows direction multiple navigation\",\n    keyboard_double_arrow_up: \"arrows direction multiple navigation\",\n    keyboard_hide: \"arrow computer device down hardware input keypad text\",\n    keyboard_option_key: \"alt key modifier\",\n    keyboard_return: \"arrow back left\",\n    keyboard_tab: \"arrow next right\",\n    keyboard_voice: \"microphone noise recorder speaker\",\n    key_off: \"[offline] disabled enabled on password slash unlock\",\n    king_bed: \"bedroom double furniture home hotel house night pillows queen rest sleep\",\n    kitchen: \"appliance cabinet cold food freezer fridge home house ice places refrigerator storage\",\n    kitesurfing: \"athlete athletic beach body entertainment exercise hobby human people person social sports travel water\",\n    label: \"badge favorite indent item library mail remember save stamp sticker tag\",\n    label_important: \"badge favorite important. indent item library mail remember save stamp sticker tag wing\",\n    label_off: \"disabled enabled favorite indent library mail on remember save slash stamp sticker tag wing\",\n    lan: \"computer connection data internet network service\",\n    landscape: \"image mountains nature photography picture\",\n    language: \"country earth globe i18n internet l10n planet website world www\",\n    laptop: \"Android chrome computer connect desktop device display hardware iOS link mac monitor smart tv web windows\",\n    laptop_chromebook: \"Android chromebook device display hardware iOS mac monitor screen web window\",\n    laptop_mac: \"Android apple chrome device display hardware iOS monitor screen web window\",\n    laptop_windows: \"Android chrome device display hardware iOS mac monitor screen web\",\n    last_page: \"application arrow chevron components end forward interface right screen ui ux website\",\n    launch: \"application arrow box components core interface internal new open screen ui ux website window\",\n    layers: \"arrange disabled enabled interaction maps off overlay pages slash stack\",\n    layers_clear: \"arrange delete disabled enabled interaction maps off overlay pages slash\",\n    leaderboard: \"analytics bars chart data diagram infographic measure metrics statistics tracking\",\n    leak_add: \"connection data link network service signals synce wireless\",\n    leak_remove: \"connection data disabled enabled link network offline service signals slash synce wireless\",\n    legend_toggle: \"analytics chart data diagram infographic measure metrics monitoring stackdriver statistics tracking\",\n    lens: \"circle full geometry moon\",\n    lens_blur: \"camera dim dot effect foggy fuzzy image photo soften\",\n    library_add: \"+ collection layers multiple music new plus save stacked symbol video\",\n    library_add_check: \"approve collection complete done layers mark multiple music ok select stacked tick validate verified video yes\",\n    library_books: \"add album audio collection reading\",\n    library_music: \"add album audio collection song sounds\",\n    light: \"bulb ceiling hanging inside interior lamp lighting pendent room\",\n    lightbulb: \"alert announcement idea information learning mode\",\n    lightbulb_circle: \"alert announcement idea information\",\n    light_mode: \"brightness day device lighting morning mornng sky sunny\",\n    linear_scale: \"application components design interface layout measure menu screen slider ui ux website window\",\n    line_axis: \"dash horizontal stroke vertical\",\n    line_style: \"dash dotted editor rule spacing\",\n    line_weight: \"editor height size spacing style thickness\",\n    link: \"anchor chain clip connection external hyperlink linked links multimedia unlisted url\",\n    linked_camera: \"connection lens network photography picture signals sync wireless\",\n    link_off: \"anchor attached chain clip connection disabled enabled linked links multimedia slash unlink url\",\n    liquor: \"alcohol bar bottle club cocktail drink food party store wine\",\n    list: \"editor file format index menu options playlist task todo\",\n    list_alt: \"box contained editor format lines reorder sheet stacked task title todo\",\n    live_help: \"? alert announcement assistance bubble chat comment communicate faq information mark message punctuation question speech support symbol\",\n    live_tv: \"Android antennas chrome desktop device hardware iOS mac monitor movie play stream television web window\",\n    living: \"chair comfort couch decoration furniture home house lounging loveseat room seating sofa\",\n    local_activity: \"event star things ticket\",\n    local_airport: \"airplane flight flying transportation travel trip\",\n    local_atm: \"bill card cart cash coin commerce credit currency dollars financial money online payment price profit shopping symbol\",\n    local_bar: \"alcohol bottle club cocktail drink food liquor martini wine\",\n    local_cafe: \"bottle coffee cup drink food mug restaurant tea\",\n    local_car_wash: \"automobile cars maps transportation travel vehicle\",\n    local_convenience_store: \"-- 24 bill building business card cash coin commerce company credit currency dollars maps market money new online payment plus shopping storefront symbol\",\n    local_dining: \"cutlery eat food fork knife meal restaurant spoon\",\n    local_drink: \"cup droplet glass liquid park water\",\n    local_fire_department: \"911 firefighter flame hot\",\n    local_florist: \"flower shop\",\n    local_gas_station: \"auto car filling fuel gasoline oil station vehicle\",\n    local_grocery_store: \"market shop\",\n    local_hospital: \"911 aid cross doctor emergency first health medical medicine plus\",\n    local_hotel: \"bed body human people person sleep stay travel trip\",\n    local_laundry_service: \"cleaning clothing dryer hotel washer\",\n    local_library: \"book community learning person read\",\n    local_mall: \"bill building business buy card cart cash coin commerce credit currency dollars handbag money online payment shopping storefront\",\n    local_offer: \"deal discount price shopping store tag\",\n    local_parking: \"alphabet auto car character font garage letter symbol text type vehicle\",\n    local_pharmacy: \"911 aid cross emergency first food hospital medicine places\",\n    local_phone: \"booth call telecommunication\",\n    local_pizza: \"drink fastfood meal\",\n    local_police: \"911 badge law officer protection security shield\",\n    local_post_office: \"delivery email envelop letter message package parcel postal send stamp\",\n    local_printshop: \"draft fax ink machine office paper printer send\",\n    local_see: \"camera lens photography picture\",\n    local_shipping: \"automobile cars delivery letter mail maps office package parcel postal semi send shopping stamp transportation truck vehicle\",\n    local_taxi: \"automobile cab call cars direction lyft maps public transportation uber vehicle yellow\",\n    location_city: \"apartments architecture buildings business company estate home landscape place real residence residential shelter town urban\",\n    location_disabled: \"destination direction enabled maps off pin place pointer slash stop tracking\",\n    location_off: \"destination direction disabled enabled gps maps pin place room slash stop\",\n    location_on: \"destination direction disabled enabled gps maps off pin place room slash stop\",\n    location_searching: \"destination direction maps pin place pointer stop tracking\",\n    lock: \"connection key locked logout padlock password privacy private protection safety secure security signout\",\n    lock_clock: \"date locked password privacy private protection safety schedule secure security time\",\n    lock_open: \"connection key login padlock password privacy private protection register safety secure security signin signup unlocked\",\n    lock_reset: \"around inprogress loading locked password privacy private protection refresh renew rotate safety secure security turn\",\n    login: \"access application arrow components design enter interface left screen ui ux website\",\n    logo_dev: \"dev.to\",\n    logout: \"application arrow components design exit interface leave login right screen ui ux website\",\n    looks: \"circle half rainbow\",\n    looks_3: \"digit numbers square symbol\",\n    looks_4: \"digit numbers square symbol\",\n    looks_5: \"digit numbers square symbol\",\n    looks_6: \"digit numbers square symbol\",\n    looks_one: \"1 digit numbers square symbol\",\n    looks_two: \"2 digit numbers square symbol\",\n    loop: \"around arrows direction inprogress loader loading music navigation refresh renew repeat rotate turn\",\n    loupe: \"+ add details focus glass magnifying new plus symbol\",\n    low_priority: \"arrange arrow backward bottom list move order task todo\",\n    loyalty: \"badge card credit heart love membership miles points program sale subscription tag travel trip\",\n    lte_mobiledata: \"alphabet character font internet letter network speed symbol text type wifi wireless\",\n    lte_plus_mobiledata: \"+ alphabet character font internet letter network speed symbol text type wifi wireless\",\n    luggage: \"airport baggage carry flight hotel on suitcase travel trip\",\n    lunch_dining: \"breakfast dinner drink fastfood hamburger meal\",\n    lyrics: \"audio bubble chat comment communicate feedback key message music note song sound speech track\",\n    mail: \"email envelope inbox letter message send\",\n    mail_lock: \"email envelop letter locked message password privacy private protection safety secure security send\",\n    mail_outline: \"email envelope letter message note post receive send write\",\n    male: \"boy gender man social symbol\",\n    man: \"boy gender male social symbol\",\n    manage_accounts: \"change details face gear options people person profile service-human settings user\",\n    manage_search: \"glass history magnifying text\",\n    map: \"destination direction location maps pin place route stop travel\",\n    maps_home_work: \"building house office\",\n    maps_ugc: \"+ add bubble comment communicate feedback message new plus speech symbol\",\n    margin: \"design layout padding size square\",\n    mark_as_unread: \"envelop letter mail postal receive send\",\n    mark_chat_read: \"approve bubble check comment communicate complete done message ok select sent speech tick verified yes\",\n    mark_chat_unread: \"bubble circle comment communicate message notification speech\",\n    mark_email_read: \"approve check complete done envelop letter message note ok select send sent tick yes\",\n    mark_email_unread: \"check circle envelop letter message note notification send\",\n    markunread: \"email envelope letter message send\",\n    markunread_mailbox: \"deliver envelop letter postal postbox receive send\",\n    masks: \"air cover covid face hospital medical pollution protection respirator sick social\",\n    maximize: \"application components design interface line screen shape ui ux website\",\n    media_bluetooth_off: \"connection connectivity device disabled enabled music note offline paring signal slash symbol wireless\",\n    media_bluetooth_on: \"connection connectivity device disabled enabled music note off online paring signal slash symbol wireless\",\n    mediation: \"alternative arrows compromise direction dots negotiation party right structure\",\n    medical_services: \"aid bag briefcase emergency first kit medicine\",\n    medication: \"doctor drug emergency hospital medicine pharmacy pills prescription\",\n    meeting_room: \"building doorway entrance home house interior logout office open places signout\",\n    memory: \"card chip digital micro processor sd storage\",\n    menu: \"application components hamburger interface lines playlist screen ui ux website\",\n    menu_book: \"dining food meal page restaurant\",\n    menu_open: \"application arrow chevron components hamburger interface left lines screen ui ux website\",\n    merge: \"arrows directions maps navigation path route sign traffic\",\n    merge_type: \"arrow combine direction format text\",\n    message: \"bubble chat comment communicate feedback speech talk text\",\n    mic: \"hearing microphone noise record search sound speech voice\",\n    mic_external_off: \"audio disabled enabled microphone slash sound voice\",\n    mic_external_on: \"audio disabled enabled microphone off slash sound voice\",\n    mic_none: \"hearing microphone noise record sound voice\",\n    mic_off: \"audio disabled enabled hearing microphone noise recording slash sound voice\",\n    microwave: \"appliance cooking electric heat home house kitchen machine\",\n    military_tech: \"army award badge honor medal merit order privilege prize rank reward ribbon soldier star status trophy winner\",\n    minimize: \"application components design interface line screen shape ui ux website\",\n    missed_video_call: \"arrow camera filming hardware image motion picture record videography\",\n    mms: \"bubble chat comment communicate feedback image landscape message mountains multimedia photography picture speech\",\n    mobiledata_off: \"arrow disabled down enabled internet network on slash speed up wifi wireless\",\n    mobile_friendly: \"Android approve cell check complete device done hardware iOS mark ok phone select tablet tick validate verified yes\",\n    mobile_off: \"Android cell device disabled enabled hardware iOS phone silence slash tablet\",\n    mobile_screen_share: \"Android arrow cell device hardware iOS mirror monitor phone screencast streaming tablet tv wireless\",\n    mode: \"compose create draft draw edit pencil write\",\n    mode_comment: \"bubble chat comment communicate feedback message mode speech\",\n    mode_edit: \"compose create draft draw pencil write\",\n    mode_edit_outline: \"compose create draft draw pencil write\",\n    model_training: \"arrow bulb idea inprogress light loading refresh renew restore reverse rotate\",\n    mode_night: \"dark disturb moon sleep weather\",\n    mode_of_travel: \"arrow destination direction location maps pin place stop transportation trip\",\n    mode_standby: \"disturb power sleep target\",\n    monetization_on: \"bill card cash circle coin commerce cost credit currency dollars finance money online payment price profit sale shopping symbol\",\n    money: \"100 bill card cash coin commerce cost credit currency digit dollars finance number online payment price profit shopping symbol\",\n    money_off: \"bill card cart cash coin commerce credit currency disabled dollars enabled finance money online payment price profit shopping slash symbol\",\n    money_off_csred: \"bill card cart cash coin commerce credit currency disabled dollars enabled online payment shopping slash symbol\",\n    monitor: \"Android chrome device display hardware iOS mac screen web window\",\n    monitor_weight: \"body device diet health scale smart\",\n    monochrome_photos: \"black camera image photography picture white\",\n    mood: \"emoji emoticon emotions expressions face feelings glad happiness happy like person pleased smiley smiling social survey\",\n    mood_bad: \"disappointment dislike emoji emoticon emotions expressions face feelings person rating smiley social survey unhappiness unhappy unpleased unsmile unsmiling\",\n    more: \"3 archive badge bookmark dots etc favorite indent label remember save stamp sticker tab tag three\",\n    more_horiz: \"3 application components dots etc horizontal interface ios pending screen status three ui ux website\",\n    more_time: \"+ add clock date new plus schedule symbol\",\n    more_vert: \"3 android application components dots etc interface screen three ui ux vertical website\",\n    motion_photos_auto: \"A alphabet animation automatic character circle font gif letter live symbol text type video\",\n    motion_photos_off: \"animation circle disabled enabled slash video\",\n    mouse: \"click computer cursor device hardware wireless\",\n    move_down: \"arrow direction jump navigation transfer\",\n    move_to_inbox: \"archive arrow down email envelop incoming letter message move send to\",\n    move_up: \"arrow direction jump navigation transfer\",\n    movie: \"cinema film media screen show slate tv video watch\",\n    movie_creation: \"clapperboard film movies slate video\",\n    movie_filter: \"clapperboard creation film movies slate stars video\",\n    moving: \"arrow direction navigation travel up\",\n    mp: \"alphabet character font image letter megapixel photography pixels quality resolution symbol text type\",\n    multiline_chart: \"analytics bars data diagram infographic line measure metrics multiple statistics tracking\",\n    multiple_stop: \"arrows directions dots left maps navigation right\",\n    museum: \"architecture attraction building estate event exhibition explore local palces places real see shop store tour\",\n    music_note: \"audiotrack key sound\",\n    music_off: \"audiotrack disabled enabled key note on slash sound\",\n    music_video: \"band mv recording screen tv watch\",\n    my_location: \"destination direction maps navigation pin place point stop\",\n    nat: \"communication\",\n    nature: \"forest outdoor outside park tree wilderness\",\n    nature_people: \"activity body forest human outdoor outside park person tree wilderness\",\n    navigate_before: \"arrows direction left\",\n    navigate_next: \"arrows direction right\",\n    navigation: \"arrow destination direction location maps pin place point stop\",\n    nearby_error: \"! alert attention caution danger exclamation important mark notification symbol warning\",\n    nearby_off: \"disabled enabled on slash\",\n    near_me: \"arrow destination direction location maps navigation pin place point stop\",\n    near_me_disabled: \"destination direction enabled location maps navigation off pin place point slash\",\n    nest_cam_wired_stand: \"camera filming hardware image motion picture videography\",\n    network_cell: \"cellular data internet mobile phone speed wifi wireless\",\n    network_check: \"connection internet meter signal speed tick wifi wireless\",\n    network_locked: \"alert available cellular connection data error internet mobile not privacy private protection restricted safety secure security service signal warning wifi wireless\",\n    network_wifi: \"cellular data internet mobile phone speed wireless\",\n    new_releases: \"! alert announcement attention burst caution danger error exclamation important mark notification star symbol warning\",\n    newspaper: \"article data document drive file folders magazine media notes page sheet slide text writing\",\n    next_plan: \"arrow circle right\",\n    next_week: \"arrow baggage briefcase business suitcase\",\n    nfc: \"communication data field mobile near wireless\",\n    nightlife: \"alcohol bar bottle club cocktail dance drink food glass liquor music note wine\",\n    nightlight: \"dark disturb mode moon sleep weather\",\n    nightlight_round: \"dark half mode moon\",\n    night_shelter: \"architecture bed building estate homeless house place real sleep\",\n    nights_stay: \"cloud crescent dark mode moon phases silence silent sky time weather\",\n    no_accounts: \"avatar disabled enabled face human offline people person profile slash thumbnail unavailable unidentifiable unknown user\",\n    no_backpack: \"accessory bookbag knapsack travel\",\n    no_drinks: \"alcohol beverage bottle cocktail food liquor wine\",\n    no_encryption: \"disabled enabled lock off password safety security slash\",\n    no_encryption_gmailerrorred: \"disabled enabled locked off slash\",\n    no_flash: \"camera disabled enabled image lightning off on photography picture slash thunderbolt\",\n    no_food: \"disabled drink enabled fastfood hamburger meal off on slash\",\n    no_luggage: \"baggage carry disabled enabled off on slash suitcase travel\",\n    no_meals: \"dining disabled eat enabled food fork knife off restaurant slash spoon utensils\",\n    no_meeting_room: \"building disabled doorway enabled entrance home house interior office on open places slash\",\n    no_photography: \"camera disabled enabled image off on picture slash\",\n    nordic_walking: \"athlete athletic body entertainment exercise hiking hobby human people person social sports travel walker\",\n    north: \"arrow directional maps navigation up\",\n    north_east: \"arrow maps navigation noth right up\",\n    north_west: \"arrow directional left maps navigation up\",\n    no_sim: \"camera card device eject insert memory phone storage\",\n    no_stroller: \"baby care carriage children disabled enabled infant kid newborn off on parents slash toddler young\",\n    not_accessible: \"accessibility body handicap help human person wheelchair\",\n    note: \"bookmark message paper\",\n    note_add: \"+ -doc create data document drive file folders new page paper plus sheet slide symbol writing\",\n    note_alt: \"clipboard document file memo page paper writing\",\n    notes: \"comment document text write writing\",\n    notification_add: \"+ active alarm alert bell chime notifications notify plus reminder ring sound symbol\",\n    notification_important: \"! active alarm alert announcement attention bell caution chime danger error exclamation feedback mark notifications notify problem reminder ring sound symbol warning\",\n    notifications: \"active alarm alert bell chime notify reminder ring sound\",\n    notifications_active: \"alarm alert bell chime notify reminder ringing sound\",\n    notifications_none: \"alarm alert bell notify reminder ring sound\",\n    notifications_off: \"active alarm alert bell chime disabled enabled notify offline reminder ring slash sound\",\n    notifications_paused: \"--- active alarm aleet alert bell chime ignore notify pause quiet reminder ring sleep snooze sound zzz\",\n    not_interested: \"allowed banned cancel circle close disabled dislike exit interested not off prohibited quit remove stop\",\n    not_listed_location: \"? assistance destination direction help information maps pin place punctuation questionmark stop support symbol\",\n    no_transfer: \"automobile bus cars direction disabled enabled maps off public slash transportation vehicle\",\n    not_started: \"circle media pause play video\",\n    offline_bolt: \"circle electric fast flash lightning spark thunderbolt\",\n    offline_pin: \"approve checkmark circle complete done ok select tick validate verified yes\",\n    offline_share: \"Android arrow cell connect device direction hardware iOS link mobile multiple phone right tablet\",\n    oil_barrel: \"droplet gasoline nest water\",\n    ondemand_video: \"Android chrome desktop device hardware iOS mac monitor play television tv web window\",\n    on_device_training: \"arrow bulb call cell contact hardware idea inprogress light loading mobile model refresh renew restore reverse rotate telephone\",\n    online_prediction: \"bulb connection idea light network signal wireless\",\n    opacity: \"color droplet hue inverted liquid palette tone water\",\n    open_in_browser: \"arrow box new up website window\",\n    open_in_full: \"action arrows expand grow move\",\n    open_in_new: \"application arrow box components interface screen ui ux website window\",\n    open_in_new_off: \"arrow box disabled enabled export on slash window\",\n    open_with: \"arrows directional expand move\",\n    other_houses: \"architecture cottage estate home maps place real residence residential stay traveling\",\n    outbound: \"arrow circle directional right up\",\n    outbox: \"mail send sent\",\n    outdoor_grill: \"barbecue barbeque bbq charcoal cooking home house outside\",\n    outlet: \"connecter electricity plug power\",\n    outlined_flag: \"country goal mark nation report start\",\n    padding: \"design layout margin size square\",\n    pages: \"article gplus paper post star\",\n    pageview: \"document find glass magnifying paper search\",\n    paid: \"circle currency money payment transaction\",\n    palette: \"art colors filters paint\",\n    panorama: \"angle image mountains photography picture view wide\",\n    panorama_fish_eye: \"angle circle image photography picture wide\",\n    panorama_horizontal: \"angle image photography picture wide\",\n    panorama_photosphere: \"angle horizontal image photography picture wide\",\n    panorama_vertical: \"angle image photography picture wide\",\n    panorama_wide_angle: \"image photography picture\",\n    pan_tool: \"drag fingers gesture hands human move scan stop touch wait\",\n    paragliding: \"athlete athletic body entertainment exercise fly hobby human parachute people person skydiving social sports travel\",\n    park: \"attraction fresh local nature outside plant tree\",\n    party_mode: \"camera lens photography picture\",\n    password: \"key login pin security star unlock\",\n    pattern: \"key login password pin security star unlock\",\n    pause: \"controls media music pending player status video wait\",\n    pause_circle: \"controls media music video\",\n    pause_circle_filled: \"controls media music pending status video wait\",\n    pause_circle_outline: \"controls media music pending status video wait\",\n    pause_presentation: \"application desktop device pending screen share slides status wait website window www\",\n    payment: \"bill cash charge coin commerce cost creditcard currency dollars finance financial information money online price shopping symbol\",\n    payments: \"bill card cash coin commerce cost credit currency dollars finance layer money multiple online price shopping symbol\",\n    pedal_bike: \"automobile bicycle cars direction human maps public route scooter transportation vehicle vespa\",\n    pending: \"circle dots loading progress waiting\",\n    pending_actions: \"clipboard clock date document remember schedule time\",\n    pentagon: \"five shape sides\",\n    people: \"accounts committee community face family friends group humans network persons profiles social team users\",\n    people_alt: \"accounts committee face family friends group humans network persons profiles social team users\",\n    people_outline: \"accounts committee face family friends group humans network persons profiles social team users\",\n    percent: \"math number symbol\",\n    perm_camera_mic: \"image microphone min photography picture speaker\",\n    perm_contact_calendar: \"account agenda date face human information people person profile schedule time user\",\n    perm_data_setting: \"cellular configure gear information network settings wifi wireless\",\n    perm_device_information: \"Android alert announcement cell hardware iOS important mobile phone tablet\",\n    perm_identity: \"account avatar face human information people person profile save, thumbnail user\",\n    perm_media: \"collection data directories document file folders images landscape mountains photography picture save storage\",\n    perm_phone_msg: \"bubble call cell chat comment communicate contact device message mobile recording save speech telephone voice\",\n    perm_scan_wifi: \"alert announcement connection information internet network service signal wireless\",\n    person: \"account avatar face human people profile user\",\n    person_add: \"+ account avatar face friend human new people plus profile symbol user\",\n    person_add_alt: \"+ account face human people plus profile user\",\n    person_add_disabled: \"+ account enabled face human new offline people plus profile slash symbol user\",\n    personal_video: \"Android cam chrome desktop device hardware iOS mac monitor television tv web window\",\n    person_off: \"account avatar disabled enabled face human people profile slash user\",\n    person_outline: \"account avatar face human people profile user\",\n    person_pin: \"account avatar destination direction face gps human location maps people place profile stop user\",\n    person_pin_circle: \"account destination direction face gps human location maps people place profile stop user\",\n    person_remove: \"account avatar delete face human minus people profile unfriend user\",\n    person_search: \"account avatar face find glass human look magnifying people profile user\",\n    pest_control: \"bug exterminator insects\",\n    pest_control_rodent: \"exterminator mice\",\n    pets: \"animal cat claw dog hand paw\",\n    phishing: \"fishing fraud hook scam\",\n    phone: \"call cell chat contact device hardware mobile telephone text\",\n    phone_android: \"cell device hardware iOS mobile tablet\",\n    phone_bluetooth_speaker: \"call cell connection connectivity contact device hardware mobile signal symbol telephone wireless\",\n    phone_callback: \"arrow cell contact device down hardware mobile telephone\",\n    phone_disabled: \"call cell contact device enabled hardware mobile offline slash telephone\",\n    phone_enabled: \"call cell contact device hardware mobile telephone\",\n    phone_forwarded: \"arrow call cell contact device direction hardware mobile right telephone\",\n    phone_iphone: \"Android apple cell device hardware iOS mobile tablet\",\n    phonelink: \"Android chrome computer connect desktop device hardware iOS mac mobile sync tablet web windows\",\n    phonelink_erase: \"Android cancel cell close connection device exit hardware iOS mobile no remove stop tablet\",\n    phonelink_lock: \"Android cell connection device erase hardware iOS locked mobile password privacy private protection safety secure security tablet\",\n    phonelink_off: \"Android chrome computer connect desktop device disabled enabled hardware iOS mac mobile slash sync tablet web windows\",\n    phonelink_ring: \"Android cell connection data device hardware iOS mobile network service signal tablet wireless\",\n    phonelink_setup: \"Android call chat device hardware iOS information mobile settings tablet text\",\n    phone_locked: \"call cell contact device hardware mobile password privacy private protection safety secure security telephone\",\n    phone_missed: \"arrow call cell contact device hardware mobile telephone\",\n    phone_paused: \"call cell contact device hardware mobile telephone wait\",\n    photo: \"image mountains photography picture\",\n    photo_album: \"archive bookmark image label library mountains photography picture ribbon save tag\",\n    photo_camera: \"image photography picture\",\n    photo_camera_back: \"image landscape mountains photography picture rear\",\n    photo_camera_front: \"account face human image people person photography picture portrait profile user\",\n    photo_filter: \"filters image photography picture stars\",\n    photo_library: \"album image mountains photography picture\",\n    photo_size_select_actual: \"image mountains photography picture\",\n    photo_size_select_large: \"adjust album editing image library mountains photography picture\",\n    photo_size_select_small: \"adjust album editing image large library mountains photography picture\",\n    php: \"alphabet brackets character code css developer engineering font html letter platform symbol text type\",\n    piano: \"instrument keyboard keys musical social\",\n    piano_off: \"disabled enabled instrument keyboard keys musical on slash social\",\n    picture_as_pdf: \"alphabet character document file font image letter multiple photography symbol text type\",\n    picture_in_picture: \"cropped overlap photo position shape\",\n    picture_in_picture_alt: \"cropped overlap photo position shape\",\n    pie_chart: \"analytics bars data diagram infographic measure metrics statistics tracking\",\n    pie_chart_outline: \"analytics bars data diagram infographic measure metrics statistics tracking\",\n    pie_chart_outlined: \"graph\",\n    pin: \"1 2 3 digit key login logout number password pattern security star symbol unlock\",\n    pinch: \"arrows compress direction finger grasp hand navigation nip squeeze tweak\",\n    pin_drop: \"destination direction gps location maps navigation place stop\",\n    pivot_table_chart: \"analytics arrows bars data diagram direction drive editing grid infographic measure metrics rotate sheet statistics tracking\",\n    place: \"destination direction location maps navigation pin point stop\",\n    plagiarism: \"document find glass look magnifying page paper search see\",\n    play_arrow: \"controls media music player start video\",\n    play_circle: \"arrow controls media music video\",\n    play_disabled: \"controls enabled media music off slash video\",\n    play_for_work: \"arrow circle down google half\",\n    play_lesson: \"audio bookmark digital ebook lesson multimedia play reading ribbon\",\n    playlist_add: \"+ collection music new plus symbol task todo\",\n    playlist_add_check: \"approve checkmark collection complete done music ok select task tick todo validate verified yes\",\n    playlist_add_check_circle: \"album artist audio cd collection mark music record sound track\",\n    playlist_add_circle: \"album artist audio cd check collection mark music record sound track\",\n    playlist_play: \"arow arrow collection music\",\n    playlist_remove: \"- collection minus music\",\n    plumbing: \"build construction fix handyman repair tools wrench\",\n    plus_one: \"1 add digit increase number symbol\",\n    podcasts: \"broadcast casting network signal transmitting wireless\",\n    point_of_sale: \"checkout cost machine merchant money payment pos retail system transaction\",\n    policy: \"certified find glass legal look magnifying privacy private protection search security see shield verified\",\n    poll: \"analytics barchart bars data diagram infographic measure metrics statistics survey tracking vote\",\n    pool: \"athlete athletic beach body entertainment exercise hobby human ocean people person places sea sports swimming water\",\n    portable_wifi_off: \"connected connection data device disabled enabled internet network offline service signal slash usage wireless\",\n    portrait: \"account face human people person photo picture profile user\",\n    post_add: \"+ data document drive file folders item page paper plus sheet slide text writing\",\n    power: \"charge cord electrical online outlet plug socket\",\n    power_input: \"dc lines supply\",\n    power_off: \"charge cord disabled electrical enabled on outlet plug slash\",\n    power_settings_new: \"information off save shutdown\",\n    precision_manufacturing: \"arm automatic chain conveyor crane factory industry machinery mechanical production repairing robot supply warehouse\",\n    pregnant_woman: \"baby birth body female human lady maternity mom mother people person user women\",\n    present_to_all: \"arrow presentation screen share slides website\",\n    preview: \"design eye layout reveal screen see show website window www\",\n    price_change: \"arrows bill card cash coin commerce cost credit currency dollars down finance money online payment shopping symbol up\",\n    price_check: \"approve bill card cash coin commerce complete cost credit currency dollars done finance mark money ok online payment select shopping symbol tick validate verified yes\",\n    print: \"draft fax ink machine office paper printer send\",\n    print_disabled: \"enabled off on paper printer slash\",\n    priority_high: \"! alert attention caution danger error exclamation important mark notification symbol warning\",\n    privacy_tip: \"alert announcement announcment assistance certified details help information private protection security service shield support verified\",\n    production_quantity_limits: \"! alert attention bill card cart cash caution coin commerce credit currency danger dollars error exclamation important mark money notification online payment shopping symbol warning\",\n    propane: \"gas nest\",\n    propane_tank: \"bbq gas grill nest\",\n    psychology: \"behavior body brain cognitive function gear head human intellectual mental mind people person preferences psychiatric science settings social therapy thinking thoughts\",\n    public: \"country earth global globe language map network planet social space web world\",\n    public_off: \"disabled earth enabled global globe map network on planet slash social space web world\",\n    publish: \"arrow cloud file import submit upload\",\n    published_with_changes: \"approve arrows check complete done inprogress loading mark ok refresh renew replace rotate select tick validate verified yes\",\n    push_pin: \"location marker place remember save\",\n    qr_code: \"barcode camera media product quick response smartphone urls\",\n    qr_code_2: \"barcode camera media product quick response smartphone urls\",\n    qr_code_scanner: \"barcode camera media product quick response smartphone urls\",\n    query_builder: \"clock date hour minute save schedule time\",\n    query_stats: \"analytics chart data diagram find glass infographic line look magnifying measure metrics search see statistics tracking\",\n    question_answer: \"bubble chat comment communicate conversation converse feedback message speech talk\",\n    question_mark: \"? assistance help information mark punctuation question support symbol\",\n    queue: \"add collection layers multiple music playlist stack stream video\",\n    queue_music: \"add collection playlist stream\",\n    queue_play_next: \"+ add arrow collection desktop device display hardware monitor music new playlist plus screen steam symbol tv video\",\n    quickreply: \"bubble chat comment communicate fast lightning message speech thunderbolt\",\n    quiz: \"? assistance faq help information mark punctuation question support symbol test\",\n    radar: \"detect military near network position scan\",\n    radio: \"antenna audio device frequency hardware listen media music player signal tune\",\n    radio_button_checked: \"application bullet circle components design form interface off point record screen selected toggle ui ux website\",\n    radio_button_unchecked: \"bullet circle deselected form off point record toggle\",\n    railway_alert: \"! attention automobile bike cars caution danger direction error exclamation important maps mark notification public scooter subway symbol train transportation vehicle vespa warning\",\n    ramen_dining: \"breakfast dinner drink fastfood lunch meal noodles restaurant\",\n    ramp_left: \"arrows directions maps navigation path route sign traffic\",\n    ramp_right: \"arrows directions maps navigation path route sign traffic\",\n    rate_review: \"chat comment feedback message pencil stars write\",\n    raw_off: \"alphabet character disabled enabled font image letter original photography slash symbol text type\",\n    raw_on: \"alphabet character disabled enabled font image letter off original photography slash symbol text type\",\n    read_more: \"arrow text\",\n    receipt: \"bill credit invoice paper payment sale transaction\",\n    receipt_long: \"bill check document list paperwork record store transaction\",\n    recent_actors: \"account avatar cards carousel contacts face human layers list people person profile thumbnail user\",\n    recommend: \"approved circle confirm favorite gesture hand like reaction social support thumbs well\",\n    record_voice_over: \"account face human people person profile recording sound speaking speech transcript user\",\n    rectangle: \"four parallelograms polygons quadrilaterals recangle shape sides\",\n    redeem: \"bill cart cash certificate coin commerce credit currency dollars giftcard money online payment present shopping\",\n    redo: \"arrow backward forward next repeat rotate undo\",\n    reduce_capacity: \"arrow body covid decrease down human people person social\",\n    refresh: \"around arrows direction inprogress loading navigation refresh renew right rotate turn\",\n    remember_me: \"Android avatar device hardware human iOS identity mobile people person phone profile tablet user\",\n    remove: \"can delete line minus negative substract subtract trash\",\n    remove_circle: \"allowed banned block can delete disable minus negative not substract trash\",\n    remove_circle_outline: \"allowed banned block can delete disable minus negative not substract trash\",\n    remove_done: \"approve check complete disabled enabled finished mark multiple off ok select slash tick yes\",\n    remove_from_queue: \"collection desktop device display hardware list monitor screen steam television\",\n    remove_moderator: \"certified disabled enabled off privacy private protection security shield slash verified\",\n    remove_red_eye: \"iris looking preview see sight vision\",\n    remove_road: \"- cancel close destination direction exit highway maps minus new no stop street symbol traffic\",\n    remove_shopping_cart: \"card cash checkout coin commerce credit currency disabled dollars enabled off online payment slash tick\",\n    reorder: \"format lines list stacked\",\n    repeat: \"arrows controls media music video\",\n    repeat_on: \"arrows controls media music video\",\n    repeat_one: \"1 arrows controls digit media music number symbol video\",\n    repeat_one_on: \"arrows controls digit media music number symbol video\",\n    replay: \"arrows controls music refresh reload renew repeat retry rewind undo video\",\n    replay_10: \"arrows controls digit music number refresh renew repeat rewind symbol ten video\",\n    replay_30: \"arrows controls digit music number refresh renew repeat rewind symbol thirty video\",\n    replay_5: \"arrows controls digit five music number refresh renew repeat rewind symbol video\",\n    replay_circle_filled: \"arrows controls music refresh renew repeat video\",\n    reply: \"arrow backward left mail message send share\",\n    reply_all: \"arrows backward group left mail message multiple send share\",\n    report: \"! alert attention caution danger error exclamation important mark notification octagon symbol warning\",\n    report_gmailerrorred: \"! alert attention caution danger exclamation important mark notification octagon symbol warning\",\n    report_off: \"! alert attention caution danger disabled enabled error exclamation important mark notification octagon offline slash symbol warning\",\n    report_problem: \"! alert announcement attention caution danger error exclamation feedback important mark notification symbol triangle warning\",\n    request_quote: \"bill card cash coin commerce cost credit currency dollars finance money online payment price shopping symbol\",\n    reset_tv: \"arrow device hardware monitor television\",\n    restart_alt: \"around arrow inprogress loading reboot refresh renew repeat reset\",\n    restaurant: \"breakfast cutlery dining dinner eat food fork knife local lunch meal places spoon utensils\",\n    restaurant_menu: \"book dining eat food fork knife local meal spoon\",\n    restore: \"arrow backwards clock date history refresh renew reverse rotate schedule time turn undo\",\n    restore_from_trash: \"arrow backwards can clock date delete garbage history refresh remove renew reverse rotate schedule time turn up\",\n    restore_page: \"arrow data doc file history paper refresh rotate sheet storage undo web\",\n    reviews: \"bubble chat comment communicate feedback message rate rating recommendation speech\",\n    rice_bowl: \"dinner food lunch meal restaurant\",\n    ring_volume: \"calling cell contact device hardware incoming mobile ringer sound telephone\",\n    r_mobiledata: \"alphabet character font letter symbol text type\",\n    rocket: \"spaceship\",\n    rocket_launch: \"spaceship takeoff\",\n    roller_shades: \"blinds cover curtains nest open shutter sunshade\",\n    roller_shades_closed: \"blinds cover curtains nest shutter sunshade\",\n    roofing: \"architecture building chimney construction estate home house real residence residential service shelter\",\n    room: \"destination direction gps location maps marker pin place spot stop\",\n    room_preferences: \"building doorway entrance gear home house interior office open settings\",\n    room_service: \"alert bell concierge delivery hotel notify\",\n    rotate_90_degrees_ccw: \"arrows direction editing image photo turn\",\n    rotate_90_degrees_cw: \"arrows ccw direction editing image photo turn\",\n    rotate_left: \"around arrow circle direction inprogress loading refresh reload renew reset turn\",\n    rotate_right: \"around arrow circle direction inprogress loading refresh renew turn\",\n    roundabout_left: \"arrows directions maps navigation path route sign traffic\",\n    roundabout_right: \"arrows directions maps navigation path route sign traffic\",\n    rounded_corner: \"adjust edit shape square transform\",\n    route: \"directions maps path sign traffic\",\n    router: \"box cable connection device hardware internet network signal wifi\",\n    rowing: \"activity boat body canoe human people person sports water\",\n    rss_feed: \"application blog connection data internet network service signal website wifi wireless\",\n    rsvp: \"alphabet character font invitation invite letter plaît respond répondez sil symbol text type vous\",\n    rtt: \"call real rrt text time\",\n    rule: \"approve check done incomplete line mark missing no ok select tick validate verified wrong x yes\",\n    rule_folder: \"approve cancel check close complete data document done drive exit file mark no ok remove select sheet slide storage tick validate verified yes\",\n    run_circle: \"body exercise human people person running\",\n    running_with_errors: \"! alert attention caution danger duration exclamation important mark notification processing symbol time warning\",\n    rv_hookup: \"arrow attach automobile automotive back cars connect direction left maps public right trailer transportation travel truck van vehicle\",\n    safety_divider: \"apart distance separate social space\",\n    sailing: \"entertainment fishing hobby ocean sailboat sea social sports travel water\",\n    sanitizer: \"bacteria bottle clean covid disinfect germs pump\",\n    satellite: \"bluetooth connection connectivity data device image internet landscape location maps mountains network photography picture scan service signal symbol wifi wireless--\",\n    satellite_alt: \"alternative artificial communication space station television\",\n    save: \"data diskette document drive file floppy multimedia storage write\",\n    save_alt: \"arrow diskette document down file floppy multimedia write\",\n    save_as: \"compose create data disk document draft drive editing file floppy input multimedia pencil storage write writing\",\n    saved_search: \"find glass important look magnifying marked see star\",\n    savings: \"bank bill card cash coin commerce cost credit currency dollars finance money online payment piggy symbol\",\n    scale: \"measure monitor weight\",\n    scanner: \"copy device hardware machine\",\n    scatter_plot: \"analytics bars chart circles data diagram dot infographic measure metrics statistics tracking\",\n    schedule: \"calendar clock date mark save time\",\n    schedule_send: \"calendar clock date email letter remember share time\",\n    schema: \"analytics chart data diagram flow infographic measure metrics statistics tracking\",\n    school: \"academy achievement cap class college education graduation hat knowledge learning university\",\n    science: \"beaker chemical chemistry experiment flask glass laboratory research tube\",\n    score: \"2k alphabet analytics bars character chart data diagram digit font infographic letter measure metrics number statistics symbol text tracking type\",\n    screen_lock_landscape: \"Android device hardware iOS mobile phone rotate security tablet\",\n    screen_lock_portrait: \"Android device hardware iOS mobile phone rotate security tablet\",\n    screen_lock_rotation: \"Android arrow device hardware iOS mobile phone rotate tablet turn\",\n    screen_rotation: \"Android arrow device hardware iOS mobile phone rotate tablet turn\",\n    screen_search_desktop: \"Android arrow device hardware iOS lock monitor rotate web\",\n    screen_share: \"Android arrow cast chrome device display hardware iOS laptop mac mirror monitor steam streaming web window\",\n    screenshot: \"Android cell crop device hardware iOS mobile phone tablet\",\n    screenshot_monitor: \"Android chrome desktop device display hardware iOS mac screengrab web window\",\n    sd: \"alphabet camera card character data device digital drive flash font image letter memory photo secure symbol text type\",\n    sd_card: \"camera digital memory photos secure storage\",\n    sd_card_alert: \"! attention camera caution danger digital error exclamation important mark memory notification photos secure storage symbol warning\",\n    sd_storage: \"camera card data digital memory microsd secure\",\n    search: \"filter find glass look magnifying see up\",\n    search_off: \"cancel close disabled enabled find glass look magnifying on see slash stop x\",\n    security: \"certified privacy private protection shield verified\",\n    security_update: \"Android arrow device download hardware iOS mobile phone tablet\",\n    security_update_good: \"Android checkmark device hardware iOS mobile ok phone tablet tick\",\n    security_update_warning: \"! Android alert attention caution danger device download error exclamation hardware iOS important mark mobile notification phone symbol tablet\",\n    segment: \"alignment fonts format lines list paragraph part piece rules style text\",\n    select_all: \"selection square tool\",\n    self_improvement: \"body calm care chi human meditate meditation people person relax sitting wellbeing yoga zen\",\n    sell: \"bill card cart cash coin commerce credit currency dollars money online payment price shopping tag\",\n    send: \"chat email message paper plane reply right share telegram\",\n    send_and_archive: \"arrow download email letter save share\",\n    send_time_extension: \"deliver dispatch envelop mail message schedule\",\n    send_to_mobile: \"Android arrow device export forward hardware iOS phone right share tablet\",\n    sensors: \"connection network scan signal wireless\",\n    sensors_off: \"connection disabled enabled network scan signal slash wireless\",\n    sentiment_dissatisfied: \"angry disappointed dislike emoji emoticon emotions expressions face feelings frown mood person sad smiley survey unhappy unsatisfied upset\",\n    sentiment_neutral: \"emotionless emotions expressions face feelings indifference mood okay person survey\",\n    sentiment_satisfied: \"emoji emoticon emotions expressions face feelings glad happiness happy like mood person pleased smiley smiling survey\",\n    sentiment_satisfied_alt: \"account emoji face happy human people person profile smile user\",\n    sentiment_very_dissatisfied: \"angry disappointed dislike emoji emoticon emotions expressions face feelings mood person sad smiley sorrow survey unhappy unsatisfied upset\",\n    sentiment_very_satisfied: \"emoji emoticon emotions expressions face feelings glad happiness happy like mood person pleased smiley smiling survey\",\n    set_meal: \"chopsticks dinner fish food lunch restaurant teishoku\",\n    settings: \"application change details gear information options personal service\",\n    settings_accessibility: \"body details human information people personal preferences profile user\",\n    settings_applications: \"change details gear information options personal save service\",\n    settings_backup_restore: \"arrow backwards history refresh reverse rotate time undo\",\n    settings_bluetooth: \"connection connectivity device network signal symbol wifi\",\n    settings_brightness: \"dark filter light mode sun\",\n    settings_cell: \"Android cellphone device hardware iOS mobile tablet\",\n    settings_ethernet: \"arrows brackets computer connection connectivity dots internet network parenthesis wifi\",\n    settings_input_antenna: \"airplay arrows computer connection connectivity dots internet network screencast stream wifi wireless\",\n    settings_input_component: \"audio av cables connection connectivity internet plugs points video wifi\",\n    settings_input_composite: \"cable component connection connectivity plugs points\",\n    settings_input_hdmi: \"cable connection connectivity definition high plugin points video wire\",\n    settings_input_svideo: \"cable connection connectivity definition plugin plugs points standard svideo,\",\n    settings_overscan: \"arrows expand image photo picture\",\n    settings_phone: \"call cell contact device hardware mobile telephone\",\n    settings_power: \"information off save shutdown\",\n    settings_remote: \"bluetooth connection connectivity control device signal wifi wireless\",\n    settings_suggest: \"change details gear options recommendation service suggestion system\",\n    settings_system_daydream: \"backup cloud drive storage\",\n    settings_voice: \"microphone recorder speaker\",\n    share: \"android connect contect link multimedia multiple network options send shared sharing social\",\n    share_location: \"destination direction gps maps pin place stop tracking\",\n    shield: \"certified privacy private protection secure security verified\",\n    shop: \"arrow bag bill briefcase buy card cart cash coin commerce credit currency dollars google money online payment play purchase shopping store\",\n    shop_2: \"add arrow buy cart google play purchase shopping\",\n    shopping_bag: \"bill business buy card cart cash coin commerce credit currency dollars money online payment storefront\",\n    shopping_basket: \"add bill buy card cart cash checkout coin commerce credit currency dollars money online payment purchase\",\n    shopping_cart: \"add bill buy card cash checkout coin commerce credit currency dollars money online payment purchase\",\n    shopping_cart_checkout: \"arrow cash coin commerce currency dollars money online payment right\",\n    shop_two: \"add arrow briefcase buy cart google play purchase shopping\",\n    shortcut: \"arrow direction forward right\",\n    short_text: \"brief comment document lines note write writing\",\n    show_chart: \"analytics bars chart data diagram infographic line measure metrics presentation show statistics stock tracking\",\n    shower: \"bathroom closet home house place plumbing sprinkler wash water wc\",\n    shuffle: \"arrows controls music random video\",\n    shuffle_on: \"arrows controls music random video\",\n    shutter_speed: \"aperture camera duration image lens photography photos picture setting stop timer watch\",\n    sick: \"covid discomfort emotions expressions face feelings fever flu ill mood pain person survey upset\",\n    signal_cellular_0_bar: \"data internet mobile network phone speed wifi wireless\",\n    signal_cellular_4_bar: \"data internet mobile network phone speed wifi wireless\",\n    signal_cellular_alt: \"analytics bar chart data diagram infographic internet measure metrics mobile network phone statistics tracking wifi wireless\",\n    signal_cellular_connected_no_internet_0_bar: \"! alert attention caution danger data error exclamation important mark mobile network notification phone symbol warning wifi wireless\",\n    signal_cellular_connected_no_internet_4_bar: \"! alert attention caution danger data error exclamation important mark mobile network notification phone symbol warning wifi wireless\",\n    signal_cellular_nodata: \"internet mobile network offline phone quit wifi wireless x\",\n    signal_cellular_no_sim: \"camera card chip device disabled enabled memory network offline phone slash storage\",\n    signal_cellular_null: \"data internet mobile network phone wifi wireless\",\n    signal_cellular_off: \"data disabled enabled internet mobile network offline phone slash wifi wireless\",\n    signal_wifi_bad: \"bar cancel cellular close data exit internet mobile network no phone quit remove stop wireless\",\n    signal_wifi_off: \"cellular data disabled enabled internet mobile network phone slash speed wireless\",\n    signal_wifi_statusbar_null: \"cellular data internet mobile network phone speed wireless\",\n    signpost: \"arrow direction left maps right signal signs street traffic\",\n    sim_card: \"camera chip device memory network phone storage\",\n    sim_card_alert: \"! attention camera caution danger digital error exclamation important mark memory notification photos sd secure storage symbol warning\",\n    sim_card_download: \"arrow camera chip device memory phone storage\",\n    single_bed: \"bedroom double furniture home hotel house king night pillows queen rest sleep twin\",\n    sip: \"alphabet call character dialer font initiation internet letter over phone protocol routing session symbol text type voice\",\n    skateboarding: \"athlete athletic body entertainment exercise hobby human people person skateboarder social sports\",\n    skip_next: \"arrow back controls forward music play previous transport video\",\n    skip_previous: \"arrow backward controls forward music next play transport video\",\n    sledding: \"athlete athletic body entertainment exercise hobby human people person sledge snow social sports travel winter\",\n    slideshow: \"movie photos play presentation square video view\",\n    slow_motion_video: \"arrow circle controls music play speed time\",\n    smart_button: \"action auto components composer function interface special stars ui ux website\",\n    smart_display: \"airplay chrome connect device screencast stream television tv video wireless\",\n    smartphone: \"Android call cell chat device hardware iOS mobile tablet text\",\n    smart_screen: \"Android airplay cell connect device hardware iOS mobile phone screencast stream tablet video\",\n    smart_toy: \"games robot\",\n    smoke_free: \"cigarette disabled enabled never no off places prohibited slash smoking tobacco warning zone\",\n    smoking_rooms: \"allowed cigarette places smoke tobacco zone\",\n    sms: \"3 bubble chat comment communication conversation dots message more service speech three\",\n    sms_failed: \"! alert attention bubbles caution chat comment communication conversation danger error exclamation important mark message notification service speech symbol warning\",\n    snippet_folder: \"data document drive file sheet slide storage\",\n    snooze: \"alarm bell clock duration notification set timer watch\",\n    snowboarding: \"athlete athletic body entertainment exercise hobby human people person social sports travel winter\",\n    snowmobile: \"automobile car direction skimobile social sports transportation travel vehicle winter\",\n    snowshoeing: \"body human people person sports travel walking winter\",\n    soap: \"bathroom clean fingers gesture hand wash wc\",\n    social_distance: \"6 apart body ft human people person space\",\n    solar_power: \"eco energy heat nest sunny\",\n    sort: \"filter find lines list organize\",\n    sort_by_alpha: \"alphabetize az by character font letters list order organize symbol text type\",\n    soup_kitchen: \"breakfast brunch dining food lunch meal\",\n    source: \"code composer content creation data document file folder mode storage view\",\n    south: \"arrow directional down maps navigation\",\n    south_america: \"america continent landscape place region south\",\n    south_east: \"arrow directional down maps navigation right\",\n    south_west: \"arrow directional down left maps navigation\",\n    spa: \"aromatherapy flower healthcare leaf massage meditation nature petals places relax wellbeing wellness\",\n    space_bar: \"keyboard line\",\n    speaker: \"audio box electronic loud music sound stereo system video\",\n    speaker_group: \"audio box electronic loud multiple music sound stereo system video\",\n    speaker_notes: \"bubble cards chat comment communicate format list message speech text\",\n    speaker_notes_off: \"bubble cards chat comment communicate disabled enabled format list message on slash speech text\",\n    speaker_phone: \"Android cell device hardware iOS mobile sound tablet volume\",\n    speed: \"arrow clock controls dial fast gauge measure motion music slow speedometer test velocity video\",\n    spellcheck: \"alphabet approve character checkmark edit font letter ok processor select symbol text tick type word write yes\",\n    splitscreen: \"grid layout multitasking two\",\n    spoke: \"connection network radius\",\n    sports: \"athlete athletic basketball blowing coach entertainment exercise game hobby instrument live referee soccer social sound trophy warning whistle\",\n    sports_bar: \"alcohol beer drink liquor pint places pub\",\n    sports_baseball: \"athlete athletic entertainment exercise game hobby social\",\n    sports_basketball: \"athlete athletic entertainment exercise game hobby social\",\n    sports_cricket: \"athlete athletic ball bat entertainment exercise game hobby social\",\n    sports_esports: \"controller entertainment gamepad gaming hobby online playstation social video xbox\",\n    sports_football: \"american athlete athletic entertainment exercise game hobby social\",\n    sports_golf: \"athlete athletic ball club entertainment exercise game golfer golfing hobby social\",\n    sports_handball: \"athlete athletic body entertainment exercise game hobby human people person social\",\n    sports_hockey: \"athlete athletic entertainment exercise game hobby ice social sticks\",\n    sports_kabaddi: \"athlete athletic body combat entertainment exercise fighting game hobby human judo martial people person social wrestle wrestling\",\n    sports_martial_arts: \"athlete athletic entertainment exercise hobby human karate people person social\",\n    sports_mma: \"arts athlete athletic boxing combat entertainment exercise fighting game glove hobby martial mixed social\",\n    sports_motorsports: \"athlete athletic automobile bike drive driving entertainment helmet hobby motorcycle protect social vehicle\",\n    sports_rugby: \"athlete athletic ball entertainment exercise game hobby social\",\n    sports_score: \"destination flag goal\",\n    sports_soccer: \"athlete athletic entertainment exercise football game hobby social\",\n    sports_tennis: \"athlete athletic ball bat entertainment exercise game hobby racket social\",\n    sports_volleyball: \"athlete athletic entertainment exercise game hobby social\",\n    square: \"draw four quadrangle shape sides\",\n    square_foot: \"construction feet inches length measurement ruler school set tools\",\n    ssid_chart: \"graph lines network wifi\",\n    stacked_bar_chart: \"analytics chart-chart data diagram infographic measure metrics statistics tracking\",\n    stacked_line_chart: \"analytics data diagram infographic measure metrics statistics tracking\",\n    stadium: \"activity amphitheater arena coliseum event local star things ticket\",\n    stairs: \"down staircase up\",\n    star: \"best bookmark favorite highlight ranking rate rating save toggle\",\n    star_border: \"best bookmark favorite highlight outline ranking rate rating save toggle\",\n    star_half: \"0.5 1/2 achievement bookmark favorite highlight important marked ranking rate rating reward saved shape special toggle\",\n    star_outline: \"bookmark favorite half highlight ranking rate rating save toggle\",\n    star_rate: \"achievement bookmark favorite highlight important marked ranking rating reward saved shape special\",\n    stars: \"achievement bookmark circle favorite highlight important like love marked ranking rate rating reward saved shape special\",\n    start: \"arrow keyboard next right\",\n    stay_current_landscape: \"Android device hardware iOS mobile phone tablet\",\n    stay_current_portrait: \"Android device hardware iOS mobile phone tablet\",\n    stay_primary_landscape: \"Android current device hardware iOS mobile phone tablet\",\n    stay_primary_portrait: \"Android current device hardware iOS mobile phone tablet\",\n    sticky_note_2: \"bookmark message paper text writing\",\n    stop: \"arrow controls music pause player square video\",\n    stop_circle: \"controls music pause play square video\",\n    stop_screen_share: \"Android arrow cast chrome device disabled display enabled hardware iOS laptop mac mirror monitor offline slash steam streaming web window\",\n    storage: \"computer database drive memory network server\",\n    store: \"bill building business buy card cash coin company credit currency dollars e-commerce market money online payment purchase shopping storefront\",\n    storefront: \"business buy cafe commerce market merchant places restaurant retail sell shopping stall\",\n    store_mall_directory: \"building\",\n    storm: \"forecast hurricane temperature twister weather wind\",\n    straight: \"arrows directions maps navigation path route sign traffic up\",\n    straighten: \"length measurement piano ruler size\",\n    stream: \"cast connected feed live network signal wireless\",\n    streetview: \"gps location maps\",\n    strikethrough_s: \"alphabet character cross doc editing editor font letter out spreadsheet styles symbol text type writing\",\n    stroller: \"baby care carriage children infant kid newborn toddler young\",\n    style: \"booklet cards filters options tags\",\n    subdirectory_arrow_left: \"arrow down navigation\",\n    subdirectory_arrow_right: \"arrow down navigation\",\n    subject: \"alignment document email full justify lines list note text writing\",\n    subscript: \"2 doc editing editor gmail novitas spreadsheet style symbol text writing\",\n    subscriptions: \"enroll media order playlist queue signup subscribe youtube\",\n    subtitles: \"accessibility accessible captions character closed decoder language media movies translate tv\",\n    subtitles_off: \"accessibility accessible caption closed disabled enabled language slash translate video\",\n    subway: \"automobile bike cars maps metro rail scooter train transportation travel tunnel underground vehicle vespa\",\n    summarize: \"document list menu note report summary\",\n    superscript: \"2 doc editing editor gmail novitas spreadsheet style symbol text writing\",\n    supervised_user_circle: \"account avatar control face human parental parents people person profile supervisor\",\n    supervisor_account: \"administrator avatar control face human parental parents people person profile supervised user\",\n    support: \"assist help lifebuoy rescue safety\",\n    support_agent: \"care customer face headphone person representative service\",\n    surfing: \"athlete athletic beach body entertainment exercise hobby human people person sea social sports summer water\",\n    surround_sound: \"audio circle signal speaker system volume volumn wireless\",\n    swap_calls: \"arrows device direction mobile share\",\n    swap_horiz: \"arrows back direction forward horizontal\",\n    swap_horizontal_circle: \"arrows back direction forward\",\n    swap_vert: \"arrows back direction down navigation up vertical\",\n    swap_vertical_circle: \"arrows back direction down horizontal up\",\n    swipe: \"arrows fingers gesture hands touch\",\n    swipe_down: \"arrows direction disable enable finger hands hit navigation strike swing swpie take\",\n    swipe_down_alt: \"arrows direction disable enable finger hands hit navigation strike swing swpie take\",\n    swipe_left: \"arrows finger hand hit navigation reject strike swing take\",\n    swipe_left_alt: \"arrows finger hand hit navigation reject strike swing take\",\n    swipe_right: \"accept arrows direction finger hands hit navigation strike swing swpie take\",\n    swipe_right_alt: \"accept arrows direction finger hands hit navigation strike swing swpie take\",\n    swipe_up: \"arrows direction disable enable finger hands hit navigation strike swing swpie take\",\n    swipe_up_alt: \"arrows direction disable enable finger hands hit navigation strike swing swpie take\",\n    swipe_vertical: \"arrows direction finger hands hit navigation strike swing swpie take verticle\",\n    switch_access_shortcut: \"arrows direction navigation new north star symbol up\",\n    switch_access_shortcut_add: \"+ arrows direction navigation new north plus star symbol up\",\n    switch_account: \"choices face human multiple options people person profile social user\",\n    switch_camera: \"arrows photography picture\",\n    switch_left: \"arrows directional navigation toggle\",\n    switch_right: \"arrows directional navigation toggle\",\n    switch_video: \"arrows camera photography videos\",\n    sync: \"360 around arrows direction inprogress loading refresh renew rotate turn\",\n    sync_alt: \"arrows horizontal internet technology update wifi\",\n    sync_disabled: \"360 around arrows direction enabled inprogress loading off refresh renew rotate slash turn\",\n    sync_lock: \"around arrows locked password privacy private protection renew rotate safety secure security turn\",\n    sync_problem: \"! 360 alert around arrows attention caution danger direction error exclamation important inprogress loading mark notification refresh renew rotate symbol turn warning\",\n    system_security_update: \"Android arrow cell device down hardware iOS mobile phone tablet\",\n    system_security_update_good: \"Android approve cell check complete device done hardware iOS mark mobile ok phone select tablet tick validate verified yes\",\n    system_security_update_warning: \"! Android alert attention caution cell danger device error exclamation hardware iOS important mark mobile notification phone symbol tablet\",\n    system_update: \"Android arrows cell device direction download hardware iOS install mobile phone tablet\",\n    system_update_alt: \"arrow download export\",\n    tab: \"browser computer documents folder internet tabs website windows\",\n    table_chart: \"analytics bars data diagram grid infographic measure metrics statistics tracking\",\n    table_rows: \"grid layout lines stacked\",\n    tablet: \"Android device hardware iOS ipad mobile web\",\n    tablet_android: \"device hardware iOS ipad mobile web\",\n    tablet_mac: \"Android apple device hardware iOS ipad mac mobile tablet web\",\n    table_view: \"format grid group layout multiple\",\n    tab_unselected: \"browser computer documents folder internet tabs website windows\",\n    tag: \"hashtag key media number pound social trend\",\n    tag_faces: \"emoji emotion happy satisfied smile\",\n    takeout_dining: \"box container delivery food meal restaurant\",\n    tap_and_play: \"Android cell connection device hardware iOS internet mobile network nfc phone signal tablet to wifi wireless\",\n    tapas: \"appetizer brunch dinner food lunch restaurant snack\",\n    task: \"approve check complete data document done drive file folders mark ok page paper select sheet slide tick validate verified writing yes\",\n    task_alt: \"approve check circle complete done mark ok select tick validate verified yes\",\n    taxi_alert: \"! attention automobile cab cars caution danger direction error exclamation important lyft maps mark notification public symbol transportation uber vehicle warning yellow\",\n    terminal: \"application code emulator program software\",\n    terrain: \"geography landscape mountain\",\n    text_decrease: \"- alphabet character font letter minus remove resize subtract symbol type\",\n    text_fields: \"T add alphabet character font input letter symbol type\",\n    text_format: \"A alphabet character font letter square style symbol type\",\n    text_increase: \"+ add alphabet character font letter new plus resize symbol type\",\n    text_rotate_up: \"A alphabet arrow character field font letter move symbol type\",\n    text_rotate_vertical: \"A alphabet arrow character down field font letter move symbol type verticle\",\n    text_rotation_angledown: \"A alphabet arrow character field font letter move rotate symbol type\",\n    text_rotation_angleup: \"A alphabet arrow character field font letter move rotate symbol type\",\n    text_rotation_down: \"A alphabet arrow character field font letter move rotate symbol type\",\n    text_rotation_none: \"A alphabet arrow character field font letter move rotate symbol type\",\n    textsms: \"bubble chat comment communicate dots feedback message speech\",\n    text_snippet: \"data document file notes storage writing\",\n    texture: \"diagonal lines pattern stripes\",\n    theater_comedy: \"broadway event movie musical places show standup tour watch\",\n    theaters: \"film media movies photography showtimes video watch\",\n    thermostat: \"forecast temperature weather\",\n    thermostat_auto: \"A celsius fahrenheit temperature thermometer\",\n    thumb_down: \"dislike downvote favorite fingers gesture hands ranking rate rating reject up\",\n    thumb_down_alt: \"bad decline disapprove dislike feedback hand hate negative no reject social veto vote\",\n    thumb_down_off_alt: \"bad decline disapprove dislike favorite feedback filled fingers gesture hands hate negative no ranking rate rating reject sad social veto vote\",\n    thumbs_up_down: \"dislike favorite fingers gesture hands rate rating vote\",\n    thumb_up: \"approve dislike down favorite fingers gesture hands ranking rate rating success upvote\",\n    thumb_up_alt: \"agreed approved confirm correct favorite feedback good hand happy like okay positive satisfaction social success vote yes\",\n    thumb_up_off_alt: \"agreed approved confirm correct favorite feedback fingers gesture good hands happy like okay positive ranking rate rating satisfaction social vote yes\",\n    timelapse: \"duration motion photo timer video\",\n    timeline: \"analytics chart data graph history line movement points tracking trending zigzag zigzap\",\n    timer: \"alarm alart bell clock disabled duration enabled notification off slash stopwatch wait\",\n    timer_10: \"digits duration numbers seconds\",\n    timer_10_select: \"alphabet camera character digit font letter number seconds symbol text type\",\n    timer_3: \"digits duration numbers seconds\",\n    timer_3_select: \"alphabet camera character digit font letter number seconds symbol text type\",\n    timer_off: \"alarm alart bell clock disabled duration enabled notification slash stopwatch\",\n    time_to_leave: \"automobile cars destination direction drive estimate eta maps public transportation travel trip vehicle\",\n    tips_and_updates: \"alert announcement electricity idea information lamp lightbulb stars\",\n    title: \"T alphabet character font header letter subject symbol text type\",\n    toc: \"content format lines list reorder stacked table text titles\",\n    today: \"agenda calendar date event mark month range remember reminder schedule time week\",\n    toggle_off: \"application components configuration control design disable inable inactive interface selection settings slider switch ui ux website\",\n    toggle_on: \"application components configuration control design disable inable inactive interface off selection settings slider switch ui ux website\",\n    token: \"badge hexagon mark shield sign symbol\",\n    toll: \"bill booth card cash circles coin commerce credit currency dollars highway money online payment ticket\",\n    tonality: \"circle editing filter image photography picture\",\n    topic: \"data document drive file folder sheet slide storage\",\n    tornado: \"crisis disaster natural rain storm weather wind\",\n    touch_app: \"arrow command fingers gesture hand press swipe tap\",\n    tour: \"destination flag places travel visit\",\n    toys: \"car fan games kids windmill\",\n    track_changes: \"bullseye circle evolve lines movement radar rotate shift target\",\n    traffic: \"direction light maps signal street\",\n    train: \"automobile cars direction maps public rail subway transportation vehicle\",\n    tram: \"automobile cars direction maps public rail subway train transportation vehicle\",\n    transfer_within_a_station: \"arrows body direction human left maps people person public right route stop transit transportation vehicle walk\",\n    transform: \"adjust crop editing image photo picture\",\n    transgender: \"female lgbt neutral neutrual social symbol\",\n    transit_enterexit: \"arrow direction maps navigation route transportation\",\n    translate: \"alphabet language letter speaking speech text translator words\",\n    travel_explore: \"earth find glass global globe look magnifying map network planet search see social space web world\",\n    trending_down: \"analytics arrow change chart data diagram infographic measure metrics movement rate rating sale statistics tracking\",\n    trending_flat: \"arrow change chart data graph metric movement rate right tracking\",\n    trending_up: \"analytics arrow change chart data diagram infographic measure metrics movement rate rating statistics tracking\",\n    trip_origin: \"circle departure\",\n    try: \"bookmark bubble chat comment communicate favorite feedback highlight important marked message saved shape special speech star\",\n    tty: \"call cell contact deaf device hardware impaired mobile speech talk telephone text\",\n    tune: \"adjust editing options settings sliders\",\n    tungsten: \"electricity indoor lamp lightbulb setting\",\n    turned_in: \"archive bookmark favorite item label library reading remember ribbon save submit tag\",\n    turned_in_not: \"archive bookmark favorite item label library outline reading remember ribbon save submit tag\",\n    turn_left: \"arrows directions maps navigation path route sign traffic\",\n    turn_right: \"arrows directions maps navigation path route sign traffic\",\n    turn_sharp_left: \"arrows directions maps navigation path route sign traffic\",\n    turn_sharp_right: \"arrows directions maps navigation path route sign traffic\",\n    turn_slight_left: \"arrows directions maps navigation path right route sign traffic\",\n    turn_slight_right: \"arrows directions maps navigation path route sharp sign traffic\",\n    tv: \"device display linear living monitor room screencast stream television video wireless\",\n    tv_off: \"Android chrome desktop device disabled enabled hardware iOS mac monitor slash television web window\",\n    two_wheeler: \"automobile bicycle cars direction maps moped motorbike motorcycle public ride riding scooter transportation travel twom vehicle wheeler wheels\",\n    umbrella: \"beach protection rain sunny\",\n    unarchive: \"arrow inbox mail store undo up\",\n    undo: \"arrow backward mail previous redo repeat rotate\",\n    unfold_less: \"arrows chevron collapse direction expandable inward list navigation up\",\n    unfold_more: \"arrows chevron collapse direction down expandable list navigation\",\n    unpublished: \"approve check circle complete disabled done enabled mark off ok select slash tick validate verified yes\",\n    unsubscribe: \"cancel close email envelop esubscribe message newsletter off remove send\",\n    upcoming: \"alarm calendar mail message notification\",\n    update: \"arrow backwards clock forward future history load refresh reverse rotate schedule time\",\n    update_disabled: \"arrow backwards clock enabled forward history load off on refresh reverse rotate schedule slash time\",\n    upgrade: \"arrow export instal line replace update\",\n    upload: \"arrows download drive\",\n    upload_file: \"arrow data document download drive folders page paper sheet slide writing\",\n    usb: \"cable connection device wire\",\n    usb_off: \"cable connection device wire\",\n    u_turn_left: \"arrows directions maps navigation path route sign traffic u-turn\",\n    u_turn_right: \"arrows directions maps navigation path route sign traffic u-turn\",\n    vaccines: \"aid covid doctor drug emergency hospital immunity injection medical medication medicine needle pharmacy sick syringe vaccination vial\",\n    verified: \"approve badge burst check complete done mark ok select star tick validate yes\",\n    verified_user: \"approve audit certified checkmark complete done ok privacy private protection security select shield tick validate yes\",\n    vertical_align_bottom: \"alignment arrow doc down editing editor spreadsheet text type writing\",\n    vertical_align_center: \"alignment arrow doc down editing editor spreadsheet text type up writing\",\n    vertical_align_top: \"alignment arrow doc editing editor spreadsheet text type up writing\",\n    vertical_shades: \"blinds cover curtains nest open shutter sunshade\",\n    vertical_shades_closed: \"blinds cover curtains nest roller shutter sunshade\",\n    vertical_split: \"design format grid layout paragraph text website writing\",\n    vibration: \"Android alert cell device hardware iOS mobile mode motion notification phone silence silent tablet vibrate\",\n    video_call: \"+ add camera chat conference filming hardware image motion new picture plus screen symbol videography\",\n    videocam: \"camera chat conference filming hardware image motion picture screen videography\",\n    video_camera_back: \"image landscape mountains photography picture rear\",\n    video_camera_front: \"account face human image people person photography picture profile user\",\n    videocam_off: \"camera chat conference disabled enabled filming hardware image motion offline picture screen slash videography\",\n    video_file: \"camera document filming hardware image motion picture videography\",\n    videogame_asset: \"console controller device gamepad gaming nintendo playstation xbox\",\n    videogame_asset_off: \"console controller device disabled enabled gamepad gaming playstation slash\",\n    video_label: \"device item screen window\",\n    video_library: \"arrow collection play\",\n    video_settings: \"change details gear information options play screen service window\",\n    video_stable: \"filming recording setting stability taping\",\n    view_agenda: \"blocks cards design format grid layout website,stacked\",\n    view_array: \"blocks design format grid layout website\",\n    view_carousel: \"banner blocks cards design format grid images layout website\",\n    view_column: \"blocks design format grid layout vertical website\",\n    view_comfy: \"grid layout pattern squares\",\n    view_comfy_alt: \"cozy design format layout web\",\n    view_compact: \"grid layout pattern squares\",\n    view_compact_alt: \"dense design format layout web\",\n    view_cozy: \"comfy design format layout web\",\n    view_day: \"blocks calendar cards carousel design format grid layout website week\",\n    view_headline: \"blocks design format grid layout paragraph text website\",\n    view_in_ar: \"3d augmented cube daydream headset reality square vr\",\n    view_kanban: \"grid layout pattern squares\",\n    view_list: \"blocks design format grid layout lines reorder stacked title website\",\n    view_module: \"blocks design format grid layout reorder squares stacked title website\",\n    view_quilt: \"blocks design format grid layout reorder squares stacked title website\",\n    view_sidebar: \"design format grid layout web\",\n    view_stream: \"blocks design format grid layout lines list reorder stacked title website\",\n    view_timeline: \"grid layout pattern squares\",\n    view_week: \"bars blocks columns day design format grid layout website\",\n    vignette: \"border editing effect filter gradient image photography setting\",\n    villa: \"architecture beach estate home house maps place real residence residential stay traveling vacation\",\n    visibility: \"eye on password preview reveal see shown visability\",\n    visibility_off: \"disabled enabled eye hidden invisible on password reveal see show slash view visability\",\n    voice_chat: \"bubble camera comment communicate facetime feedback message speech video\",\n    voicemail: \"call device message missed mobile phone recording\",\n    voice_over_off: \"account disabled enabled face human people person profile recording slash speaking speech transcript user\",\n    volume_down: \"audio av control music quieter shh soft sound speaker tv\",\n    volume_mute: \"audio control music sound speaker tv\",\n    volume_off: \"audio av control disabled enabled low music mute slash sound speaker tv\",\n    volume_up: \"audio control music sound speaker tv\",\n    volunteer_activism: \"donation fingers gesture giving hands heart love sharing\",\n    vpn_key: \"login network passcode password register security signin signup unlock\",\n    vpn_key_off: \"[offline] disabled enabled network on passcode password slash unlock\",\n    vpn_lock: \"earth globe locked network password privacy private protection safety secure security virtual world\",\n    vrpano: \"angle image landscape mountains panorama photography picture view wide\",\n    wallpaper: \"background image landscape photography picture\",\n    warehouse: \"garage industry manufacturing storage\",\n    warning: \"! alert announcement attention caution danger error exclamation feedback important mark notification problem symbol triangle\",\n    warning_amber: \"! alert attention caution danger error exclamation important mark notification symbol triangle\",\n    wash: \"bathroom clean fingers gesture hand wc\",\n    watch: \"Android clock gadget iOS smartwatch time vr wearables web wristwatch\",\n    watch_later: \"clock date hour minute schedule time\",\n    watch_off: \"Android clock close gadget iOS shut time vr wearables web wristwatch\",\n    water: \"aqua beach lake ocean river waves weather\",\n    water_damage: \"architecture building droplet estate house leak plumbing real residence residential shelter\",\n    waterfall_chart: \"analytics bar data diagram infographic measure metrics statistics tracking\",\n    waves: \"beach lake ocean pool river sea swim water\",\n    wb_auto: \"A W alphabet automatic balance character editing font image letter photography symbol text type white wp\",\n    wb_cloudy: \"balance editing white wp\",\n    wb_incandescent: \"balance bright editing lamp lightbulb lighting settings white wp\",\n    wb_iridescent: \"balance bright editing lighting settings white wp\",\n    wb_shade: \"balance house lighting white\",\n    wb_sunny: \"balance bright lighting weather white\",\n    wc: \"bathroom closet female gender man person restroom toilet unisex wash water women\",\n    web: \"blocks browser internet page screen website www\",\n    web_asset: \"-website application browser design desktop download image interface internet layout screen ui ux video window www\",\n    web_asset_off: \"browser disabled enabled internet on screen slash webpage website windows www\",\n    webhook: \"api developer development enterprise software\",\n    weekend: \"chair couch furniture home living lounge relax room seat\",\n    west: \"arrow directional left maps navigation\",\n    whatshot: \"arrow circle direction fire frames round trending\",\n    wheelchair_pickup: \"accessibility accessible body handicap help human person\",\n    where_to_vote: \"approve ballot check complete destination direction done election location maps mark ok pin place poll select stop tick validate verified yes\",\n    widgets: \"app blocks box menu setting squares ui\",\n    wifi: \"connection data internet network scan service signal wireless\",\n    wifi_calling: \"cell connection connectivity contact device hardware mobile signal telephone wireless\",\n    wifi_calling_3: \"cellular data internet mobile network phone speed wireless\",\n    wifi_channel: \"(scan) [cellular connection data internet mobile] network service signal wireless\",\n    wifi_find: \"(scan) [cellular connection data detect discover glass internet look magnifying mobile] network notice search service signal wireless\",\n    wifi_lock: \"cellular connection data internet locked mobile network password privacy private protection safety secure security service signal wireless\",\n    wifi_off: \"connection data disabled enabled internet network offline scan service signal slash wireless\",\n    wifi_password: \"(scan) [cellular connection data internet lock mobile] network secure service signal wireless\",\n    wifi_protected_setup: \"around arrows rotate\",\n    wifi_tethering: \"cellular connection data internet mobile network phone scan service signal speed wireless\",\n    wifi_tethering_off: \"cellular connection data disabled enabled internet mobile network offline phone scan service signal slash speed wireless\",\n    window: \"close glass grid home house interior layout outside\",\n    wind_power: \"eco energy nest windy\",\n    wine_bar: \"alcohol cocktail cup drink glass liquor\",\n    work: \"-briefcase baggage business job suitcase\",\n    work_history: \"arrow backwards baggage briefcase business clock date job refresh renew reverse rotate schedule suitcase time turn\",\n    work_off: \"baggage briefcase business disabled enabled job on slash suitcase\",\n    work_outline: \"baggage briefcase business job suitcase\",\n    workspace_premium: \"certification degree ecommerce guarantee medal permit ribbon verification\",\n    workspaces: \"circles collaboration dot filled group team\",\n    wrap_text: \"arrow doc editing editor spreadsheet type write writing\",\n    wrong_location: \"cancel close destination direction exit maps no pin place quit remove stop\",\n    wysiwyg: \"composer mode screen software system text view visibility website window\",\n    yard: \"backyard flower garden home house nature pettle plants\",\n    youtube_searched_for: \"arrow backwards find glass history inprogress loading look magnifying refresh renew restore reverse rotate see yt\",\n    zoom_in: \"bigger find glass grow look magnifier magnifying plus scale search see size\",\n    zoom_in_map: \"arrows destination location maps move place stop\",\n    zoom_out: \"find glass look magnifier magnifying minus negative scale search see size smaller\",\n    zoom_out_map: \"arrows destination location maps move place stop\"\n};\n","import { iconSynonyms } from \"./icon_synonyms\";\nimport { iconKeys } from \"@firecms/ui\";\n\n// @ts-ignore\nimport * as JsSearch from \"js-search\";\n\nexport const iconsSearch = new JsSearch.Search(\"key\");\niconsSearch.addIndex(\"synonyms\");\n\niconsSearch.addDocuments(iconKeys\n    .map((importName) => {\n        return {\n            key: importName,\n            // @ts-ignore\n            synonyms: iconSynonyms[importName] ?? [],\n        }\n    }));\n","import React from \"react\";\nimport { hashString } from \"./hash\";\nimport { coolIconKeys, Icon, iconKeys } from \"@firecms/ui\";\nimport { slugify } from \"./strings\";\nimport equal from \"react-fast-compare\"\n\nexport function getIcon(iconKey?: string, className?: string): React.ReactElement | undefined {\n    if (!iconKey) return undefined;\n    iconKey = slugify(iconKey);\n    if (!(iconKey in iconKeysMap)) {\n        return undefined;\n    }\n    return iconKey in iconKeysMap ? <Icon iconKey={iconKey} size={\"medium\"} className={className}/> : undefined;\n}\n\nexport type IconViewProps = {\n    path: string;\n    name: string;\n    singularName?: string;\n    group?: string;\n    icon?: string;\n}\n\nexport const IconForView = React.memo(\n    function IconForView({ collectionOrView, className }: { collectionOrView?: IconViewProps, className?: string }): React.ReactElement {\n        if (!collectionOrView) return <></>;\n        const icon = getIcon(collectionOrView.icon, className);\n        if (collectionOrView?.icon && icon)\n            return icon;\n\n        let slugName = slugify((\"singularName\" in collectionOrView ? collectionOrView.singularName : undefined) ?? collectionOrView.name);\n\n        let key: string | undefined;\n        if (slugName in iconKeysMap)\n            key = slugName;\n\n        if (!key) {\n            slugName = slugify(collectionOrView.path);\n            if (slugName in iconKeysMap)\n                key = slugName;\n        }\n\n        const iconsCount = coolIconKeys.length;\n\n        if (!key)\n            key = coolIconKeys[hashString(collectionOrView.path) % iconsCount];\n\n        return <Icon iconKey={key} size={\"medium\"} className={className}/>;\n    }, (prevProps, nextProps) => {\n        return equal(prevProps.collectionOrView?.icon, nextProps.collectionOrView?.icon);\n    });\n\nconst iconKeysMap: Record<string, string> = iconKeys.reduce((acc: Record<string, string>, key) => {\n    acc[key] = key;\n    return acc;\n}, {});\n","export function hashString(str: string): number {\n    let hash = 0;\n    let i;\n    let chr;\n    for (i = 0; i < str.length; i++) {\n        chr = str.charCodeAt(i);\n        hash = ((hash << 5) - hash) + chr;\n        hash |= 0; // Convert to 32bit integer\n    }\n    return Math.abs(hash);\n}\n","import { EntityCollection, PropertyConfig, ResolvedEntityCollection } from \"../types\";\nimport { isReferenceProperty } from \"./property_utils\";\nimport { isPropertyBuilder } from \"./entities\";\nimport { getFieldConfig } from \"../core\";\n\nexport function getEntityPreviewKeys(targetCollection: EntityCollection<any>,\n                                     fields: Record<string, PropertyConfig>,\n                                     previewProperties?: string[],\n                                     limit = 3) {\n    const allProperties = Object.keys(targetCollection.properties);\n    let listProperties = previewProperties?.filter(p => allProperties.includes(p as string));\n    if (listProperties && listProperties.length > 0) {\n        return listProperties;\n    } else {\n        listProperties = allProperties;\n        return listProperties.filter(key => {\n            const propertyOrBuilder = targetCollection.properties[key];\n            return propertyOrBuilder && !isPropertyBuilder(propertyOrBuilder) && !isReferenceProperty(propertyOrBuilder, fields);\n        }).slice(0, limit);\n    }\n}\n\nexport function getEntityTitlePropertyKey<M extends Record<string, any>>(collection: EntityCollection<M>, propertyConfigs: Record<string, PropertyConfig<any>>): string | undefined {\n    if (collection.titleProperty) {\n        return collection.titleProperty as string;\n    }\n    // find first text field property\n    for (const key in collection.properties) {\n        const property = collection.properties[key];\n        if (!isPropertyBuilder(property)) {\n            const field = getFieldConfig(property, propertyConfigs);\n            if (field?.key === \"text_field\") {\n                return key;\n            }\n        }\n    }\n    return undefined;\n}\n\nexport function getEntityImagePreviewPropertyKey<M extends object>(collection: ResolvedEntityCollection<M>): string | undefined {\n\n    // find first text field property\n    for (const key in collection.properties) {\n        const property = collection.properties[key];\n        if (property.dataType === \"string\" && property.storage?.acceptedFiles?.includes(\"image/*\")) {\n            return key;\n        }\n\n    }\n    return undefined;\n}\n","import {\n    EntityCollection,\n    MapProperty,\n    ModifyCollectionProps,\n    PropertiesOrBuilders,\n    Property,\n    PropertyOrBuilder\n} from \"../types\";\nimport { mergeDeep } from \"./objects\";\nimport { sortProperties } from \"./collections\";\nimport { isPropertyBuilder } from \"./entities\";\n\nfunction applyModifyFunction(modifyCollection: ((props: ModifyCollectionProps) => (EntityCollection | void)) | undefined,\n                             collection: EntityCollection,\n                             parentPaths: string[]) {\n    if (modifyCollection) {\n        const modified = modifyCollection({\n            collection,\n            parentPaths\n        });\n        const resCollection = modified ?? collection;\n        if (resCollection.subcollections) {\n            resCollection.subcollections = resCollection.subcollections.map((subcollection) => {\n                return applyModifyFunction(modifyCollection, subcollection, [...parentPaths, collection.path]);\n            });\n        }\n        return resCollection;\n    } else {\n        return collection;\n    }\n}\n\n/**\n *\n */\nexport function joinCollectionLists(targetCollections: EntityCollection[],\n                                    sourceCollections: EntityCollection[] | undefined,\n                                    parentPaths: string[] = [],\n                                    modifyCollection?: (props: ModifyCollectionProps) => EntityCollection | void): EntityCollection[] {\n\n    // merge collections that are in both lists\n    const updatedCollections = (sourceCollections ?? [])\n        .map((sourceCol) => {\n            const targetCol = targetCollections?.find((collection) => {\n                return collection.id === sourceCol.id;\n                // return collection.path === codedCollection.path || collection.id && codedCollection.id;\n            });\n            if (!targetCol) {\n                return applyModifyFunction(modifyCollection, sourceCol, parentPaths);\n            } else {\n                return mergeCollection(targetCol, sourceCol, parentPaths, modifyCollection);\n            }\n        });\n\n    const sourceCollectionIds = updatedCollections.map(c => c.id);\n    // fetched collections that are not in the source collections\n    const resultStoredCollections = targetCollections\n        .filter((col) => {\n            return !sourceCollectionIds.includes(col.id);\n        })\n        .map((col) => {\n            if (modifyCollection) {\n                return applyModifyFunction(modifyCollection, col, parentPaths);\n            } else {\n                return col;\n            }\n        });\n\n    return [...updatedCollections, ...resultStoredCollections];\n}\n\n/**\n *\n */\nexport function mergeCollection(target: EntityCollection,\n                                source: EntityCollection,\n                                parentPaths: string[] = [],\n                                modifyCollection?: (props: ModifyCollectionProps) => EntityCollection | void\n): EntityCollection {\n\n    const subcollectionsMerged = joinCollectionLists(\n        target?.subcollections ?? [],\n        source?.subcollections ?? [],\n        [...parentPaths, target.path],\n        modifyCollection\n    );\n\n    const propertiesMerged: PropertiesOrBuilders = { ...target.properties } as PropertiesOrBuilders;\n    Object.keys(source.properties).forEach((key) => {\n        const property = target.properties[key] as Property;\n        if (property)\n            propertiesMerged[key] = mergePropertyOrBuilder(property, source.properties[key] as PropertyOrBuilder);\n        else\n            propertiesMerged[key] = source.properties[key] as PropertyOrBuilder;\n    });\n\n    const mergedCollection = mergeDeep(target, source);\n    const targetPropertiesOrder = getCollectionKeys(target);\n    const sourcePropertiesOrder = getCollectionKeys(source);\n    const mergedPropertiesOrder = [...new Set([...sourcePropertiesOrder, ...targetPropertiesOrder])];\n    const mergedEntityViews = [...new Set([...(target.entityViews ?? []), ...(source.entityViews ?? [])])];\n\n    let resultCollection: EntityCollection = {\n        ...mergedCollection,\n        subcollections: subcollectionsMerged,\n        properties: sortProperties(propertiesMerged, mergedPropertiesOrder),\n        propertiesOrder: mergedPropertiesOrder,\n        entityViews: mergedEntityViews\n    };\n    if (modifyCollection) {\n        const modifiedCollection = modifyCollection({\n            collection: resultCollection,\n            parentPaths\n        });\n        if (modifiedCollection)\n            resultCollection = modifiedCollection;\n    }\n    return resultCollection\n}\n\nfunction mergePropertyOrBuilder(target: PropertyOrBuilder, source: PropertyOrBuilder): PropertyOrBuilder {\n    if (isPropertyBuilder(source)) {\n        return source;\n    } else if (isPropertyBuilder(target)) {\n        return target;\n    } else {\n        const mergedProperty = mergeDeep(target, source);\n        const targetEditable = Boolean(target.editable);\n        const sourceEditable = Boolean(source.editable);\n        if (source.dataType === \"map\" && source.properties) {\n            const targetProperties = (\"properties\" in target ? target.properties : {}) as PropertiesOrBuilders;\n            const sourceProperties = (\"properties\" in source ? source.properties : {}) as PropertiesOrBuilders;\n            const targetPropertiesOrder = \"propertiesOrder\" in target && target.propertiesOrder ? target.propertiesOrder : Object.keys(targetProperties);\n            const sourcePropertiesOrder = \"propertiesOrder\" in source && source.propertiesOrder ? source.propertiesOrder : (\"properties\" in source ? Object.keys(source.properties) : []);\n            const mergedPropertiesOrder = [...new Set([...targetPropertiesOrder, ...sourcePropertiesOrder])];\n            const mergedProperties: PropertiesOrBuilders = { ...targetProperties } as PropertiesOrBuilders;\n            Object.keys(source.properties).forEach((key) => {\n                const property = targetProperties[key] as Property;\n                if (property)\n                    mergedProperties[key] = mergePropertyOrBuilder(property, sourceProperties[key] as PropertyOrBuilder);\n            });\n            return {\n                ...mergedProperty,\n                editable: targetEditable && sourceEditable,\n                properties: mergedProperties,\n                propertiesOrder: mergedPropertiesOrder\n            } as MapProperty;\n        }\n        return {\n            ...mergedProperty,\n            editable: targetEditable && sourceEditable\n        };\n    }\n}\n\nfunction getCollectionKeys(collection: EntityCollection) {\n    if (collection.propertiesOrder && collection.propertiesOrder.length > 0) {\n        const propertiesOrder = collection.propertiesOrder;\n        if (collection.additionalFields) {\n            collection.additionalFields.forEach((field) => {\n                if (!propertiesOrder.includes(field.key)) {\n                    propertiesOrder.push(field.key);\n                }\n            });\n        }\n        return propertiesOrder;\n    }\n    return [\n        ...Object.keys(collection.properties),\n        ...(collection.additionalFields ?? [])?.map(f => f.key)\n    ];\n}\n","import { useEffect, useRef } from \"react\";\n\nexport function printChanged(props: any, prev: any, path: string | undefined = \"\", depth: number | undefined = 0, maxDepth: number | undefined = 10) {\n    if (depth > maxDepth) {\n        return;\n    }\n    if (props && prev && typeof props === \"object\" && typeof prev === \"object\") {\n        Object.keys(props).forEach((key) => {\n            printChanged(props[key], prev[key], path + \".\" + key, depth + 1, maxDepth);\n        });\n    } else if (props !== prev) {\n        console.log(\"Changed props:\", path);\n    }\n\n}\n\nexport function useTraceUpdate(props: any, maxDepth = 3) {\n    const prev = useRef(props);\n    useEffect(() => {\n        console.log(\"Changed props:\");\n        printChanged(props, prev.current, \"\", 0, maxDepth);\n        prev.current = props;\n    });\n}\n","import React from \"react\";\nimport { DataSource } from \"../types\";\n\nexport const DataSourceContext = React.createContext<DataSource>({} as DataSource);\n","import { useContext, useMemo } from \"react\";\nimport { DataSource, EntityCollection } from \"../../types\";\nimport { DataSourceContext } from \"../../contexts/DataSourceContext\";\n\n/**\n * Use this hook to get the datasource being used\n * @group Hooks and utilities\n */\nexport const useDataSource = (collection?: EntityCollection<any, any>): DataSource => {\n    const defaultDataSource = useContext(DataSourceContext);\n    if (collection?.overrides?.dataSource)\n        return collection?.overrides.dataSource;\n    return defaultDataSource;\n};\n","import React from \"react\";\nimport { NavigationController } from \"../types\";\n\nexport const NavigationContext = React.createContext<NavigationController>({} as NavigationController);\n","import { useContext } from \"react\";\nimport { NavigationController } from \"../types\";\nimport { NavigationContext } from \"../contexts/NavigationContext\";\n\n/**\n * Use this hook to get the navigation of the app.\n * This controller provides the resolved collections for the CMS as well\n * as utility methods.\n *\n * @group Hooks and utilities\n */\nexport const useNavigationController = (): NavigationController => useContext(NavigationContext);\n","import { AuthController, User } from \"../types\";\nimport { useContext } from \"react\";\nimport { AuthControllerContext } from \"../contexts/AuthControllerContext\";\n\n/**\n * Hook to retrieve the AuthContext.\n *\n * Consider that in order to use this hook you need to have a parent\n * `FireCMS`\n *\n * @see AuthController\n * @group Hooks and utilities\n */\nexport const useAuthController = <UserType extends User = User, AuthControllerType extends AuthController<UserType> = AuthController<UserType>>(): AuthControllerType => useContext(AuthControllerContext) as AuthControllerType;\n","import React from \"react\";\nimport { SideDialogsController } from \"../types\";\n\nexport const SideDialogsControllerContext = React.createContext<SideDialogsController>({} as SideDialogsController);\n","import { SideDialogsController } from \"../types\";\nimport { SideDialogsControllerContext } from \"../contexts/SideDialogsControllerContext\";\nimport { useContext } from \"react\";\n\n/**\n * Hook to retrieve the side dialogs' controller.\n *\n * This hook allows you to open and close side dialogs. This is the mechanism\n * used when open a side entity dialog, or when selecting a reference.\n *\n * If you want to open a side entity dialog, you can use the {@link useSideEntityController}\n * hook.\n *\n * If you want to select a reference, you can use the {@link useReferenceDialog}\n *\n * Consider that in order to use this hook you need to have a parent\n * `FireCMS`\n *\n * @group Hooks and utilities\n */\nexport const useSideDialogsController = (): SideDialogsController => useContext(SideDialogsControllerContext);\n","import React from \"react\";\nimport { SideEntityController } from \"../types\";\n\nexport const SideEntityControllerContext = React.createContext<SideEntityController>({} as SideEntityController);\n","import { SideEntityController } from \"../types\";\nimport { useContext } from \"react\";\nimport { SideEntityControllerContext } from \"../contexts/SideEntityControllerContext\";\n\n/**\n * Use this hook to retrieve an entity controller that allows you to open\n * a side dialog to edit an entity.\n *\n * Consider that in order to use this hook you need to have a parent\n * `FireCMS`\n *\n * @see SideEntityController\n * @group Hooks and utilities\n */\nexport const useSideEntityController = (): SideEntityController => useContext(SideEntityControllerContext);\n","import React from \"react\";\nimport { StorageSource } from \"../types\";\n\nexport const StorageSourceContext = React.createContext<StorageSource>({} as StorageSource);\n","import { EntityCollection, StorageSource } from \"../types\";\nimport { StorageSourceContext } from \"../contexts/StorageSourceContext\";\nimport { useContext } from \"react\";\n\n/**\n * Use this hook to get the storage source being used\n * @group Hooks and utilities\n */\nexport const useStorageSource = (collection?: EntityCollection): StorageSource => {\n    const defaultStorageSource = useContext(StorageSourceContext);\n    if (collection?.overrides?.storageSource)\n        return collection.overrides.storageSource;\n    return defaultStorageSource;\n};\n","import React, { useCallback, useMemo } from \"react\";\nimport { useSnackbar } from \"notistack\";\n\n/**\n * Possible snackbar types\n * @group Hooks and utilities\n */\nexport type SnackbarMessageType = \"success\" | \"info\" | \"warning\" | \"error\";\n\n/**\n * Controller to display snackbars\n * @group Hooks and utilities\n */\nexport interface SnackbarController {\n\n    /**\n     * Close the currently open snackbar\n     */\n    close: () => void;\n\n    /**\n     * Display a new snackbar. You need to specify the type and message.\n     * You can optionally specify a title\n     */\n    open: (props: {\n        type: SnackbarMessageType;\n        message: React.ReactNode;\n        autoHideDuration?: number;\n    }) => void;\n\n}\n\n/**\n * Hook to retrieve the SnackbarContext.\n *\n * Consider that in order to use this hook you need to have a parent\n * `FireCMS`\n *\n * @see SnackbarController\n * @group Hooks and utilities\n */\nexport const useSnackbarController = () => {\n\n    const {\n        enqueueSnackbar,\n        closeSnackbar\n    } = useSnackbar();\n\n    const open = useCallback((props: {\n        type: SnackbarMessageType;\n        message: React.ReactNode;\n        autoHideDuration?: number;\n    }) => {\n        const {\n            type,\n            message,\n            autoHideDuration\n        } = props;\n        enqueueSnackbar({\n            message,\n            variant: type,\n            autoHideDuration\n        })\n    }, []);\n\n    const close = useCallback(() => {\n        closeSnackbar();\n    }, []);\n\n    return useMemo(() => ({\n        open,\n        close\n    }), [open, close]);\n\n};\n","import React from \"react\";\nimport { UserConfigurationPersistence } from \"../types\";\n\nexport const UserConfigurationPersistenceContext = React.createContext<UserConfigurationPersistence | undefined>(undefined);\n","import { UserConfigurationPersistence } from \"../types\";\nimport { useContext } from \"react\";\nimport { UserConfigurationPersistenceContext } from \"../contexts/UserConfigurationPersistenceContext\";\n\n/**\n * Use this controller to access the configuration that is stored externally,\n * and not defined in code\n *\n * @group Hooks and utilities\n */\nexport const useUserConfigurationPersistence = (): UserConfigurationPersistence | undefined => useContext(UserConfigurationPersistenceContext);\n","import React, { PropsWithChildren, useCallback, useRef, useState } from \"react\";\nimport { DialogControllerEntryProps, DialogsController } from \"../types/dialogs_controller\";\n\nexport const DialogsControllerContext = React.createContext<DialogsController>({} as DialogsController);\n\nexport const DialogsProvider: React.FC<PropsWithChildren<{}>> = ({ children }) => {\n\n    const [dialogEntries, setDialogEntries] = useState<DialogControllerEntryProps[]>([]);\n    const dialogEntriesRef = useRef<DialogControllerEntryProps[]>(dialogEntries);\n\n    const updateDialogEntries = (newPanels: DialogControllerEntryProps[]) => {\n        dialogEntriesRef.current = newPanels;\n        setDialogEntries(newPanels);\n    };\n\n    const close = useCallback(() => {\n\n        if (dialogEntries.length === 0)\n            return;\n\n        const updatedPanels = [...dialogEntries.slice(0, -1)];\n        updateDialogEntries(updatedPanels);\n\n    }, [dialogEntries]);\n\n    const open = useCallback((dialogEntry: DialogControllerEntryProps) => {\n\n        const updatedPanels = [...dialogEntries, dialogEntry];\n        updateDialogEntries(updatedPanels);\n\n        return {\n            closeDialog: () => {\n                const updatedPanels = dialogEntriesRef.current.filter(e => e.key !== dialogEntry.key);\n                updateDialogEntries(updatedPanels);\n            }\n        }\n    }, [dialogEntries]);\n\n    return (\n        <DialogsControllerContext.Provider value={{\n            open,\n            close\n        }}>\n            {children}\n            {dialogEntries.map((entry, i) => <entry.Component\n                key={`dialog_${i}`}\n                open={true}\n                closeDialog={close}\n            />)}\n        </DialogsControllerContext.Provider>\n    );\n};\n","import { useContext } from \"react\";\nimport { DialogsController } from \"../types/dialogs_controller\";\nimport { DialogsControllerContext } from \"../contexts/DialogsProvider\";\n\n/**\n * Use this hook to open a dialog imperatively.\n * Alternatively, you can use dialogs declaratively using the `Dialog` component.\n *\n * Consider that in order to use this hook you need to have a parent\n * `FireCMS`\n *\n * @group Hooks and utilities\n */\nexport const useDialogsController = (): DialogsController => useContext(DialogsControllerContext);\n","import React from \"react\";\nimport { CustomizationController } from \"../types/customization_controller\";\n\nexport const CustomizationControllerContext = React.createContext<CustomizationController>({} as CustomizationController);\n","import { useContext } from \"react\";\nimport { CustomizationController } from \"../types/customization_controller\";\nimport { CustomizationControllerContext } from \"../contexts/CustomizationControllerContext\";\n\n/**\n * Use this hook to retrieve the customization controller.\n * This hook includes all the customization options that can be used\n * to customize the CMS.\n *\n * You will likely not need to use this hook directly.\n *\n * @group Hooks and utilities\n */\nexport const useCustomizationController = (): CustomizationController => useContext(CustomizationControllerContext);\n","import React from \"react\";\nimport { AnalyticsController } from \"../types\";\n\nexport const AnalyticsContext = React.createContext<AnalyticsController>({} as AnalyticsController);\n","import { useContext } from \"react\";\nimport { AnalyticsController } from \"../types\";\nimport { AnalyticsContext } from \"../contexts/AnalyticsContext\";\n\n/**\n * @group Hooks and utilities\n */\nexport const useAnalyticsController = (): AnalyticsController => useContext(AnalyticsContext);\n","import { AuthController, FireCMSContext, User } from \"../types\";\nimport { useAuthController } from \"./useAuthController\";\nimport { useSideDialogsController } from \"./useSideDialogsController\";\nimport { useNavigationController } from \"./useNavigationController\";\nimport { useSideEntityController } from \"./useSideEntityController\";\nimport { useDataSource } from \"./data/useDataSource\";\nimport { useStorageSource } from \"./useStorageSource\";\nimport { useSnackbarController } from \"./useSnackbarController\";\nimport { useUserConfigurationPersistence } from \"./useUserConfigurationPersistence\";\nimport { useDialogsController } from \"./useDialogsController\";\nimport { useCustomizationController } from \"./useCustomizationController\";\nimport { useAnalyticsController } from \"./useAnalyticsController\";\nimport React, { useEffect } from \"react\";\n\n/**\n * Hook to retrieve the {@link FireCMSContext}.\n *\n * Consider that in order to use this hook you need to have a parent\n * `FireCMS` component.\n *\n * @see FireCMSContext\n * @group Hooks and utilities\n */\nexport const useFireCMSContext = <UserType extends User = User, AuthControllerType extends AuthController<UserType> = AuthController<UserType>>(): FireCMSContext<UserType, AuthControllerType> => {\n\n    const authController = useAuthController<UserType, AuthControllerType>();\n    const sideDialogsController = useSideDialogsController();\n    const sideEntityController = useSideEntityController();\n    const navigation = useNavigationController();\n    const dataSource = useDataSource();\n    const storageSource = useStorageSource();\n    const snackbarController = useSnackbarController();\n    const userConfigPersistence = useUserConfigurationPersistence();\n    const dialogsController = useDialogsController();\n    const customizationController = useCustomizationController();\n    const analyticsController = useAnalyticsController();\n\n    const fireCMSContextRef = React.useRef<FireCMSContext<UserType, AuthControllerType>>({\n        authController,\n        sideDialogsController,\n        sideEntityController,\n        navigation,\n        dataSource,\n        storageSource,\n        snackbarController,\n        userConfigPersistence,\n        dialogsController,\n        customizationController,\n        analyticsController\n    });\n\n    useEffect(() => {\n        fireCMSContextRef.current = {\n            authController,\n            sideDialogsController,\n            sideEntityController,\n            navigation,\n            dataSource,\n            storageSource,\n            snackbarController,\n            userConfigPersistence,\n            dialogsController,\n            customizationController,\n            analyticsController\n        };\n    }, [authController, dialogsController, navigation, sideDialogsController]);\n\n    return fireCMSContextRef.current;\n}\n\n// export const useFireCMSContext = <UserType extends User = User, AuthControllerType extends AuthController<UserType> = AuthController<UserType>>(): FireCMSContext<UserType, AuthControllerType> => {\n//\n//     const authController = useAuthController<UserType, AuthControllerType>();\n//     const sideDialogsController = useSideDialogsController();\n//     const sideEntityController = useSideEntityController();\n//     const navigation = useNavigationController();\n//     const dataSource = useDataSource();\n//     const storageSource = useStorageSource();\n//     const snackbarController = useSnackbarController();\n//     const userConfigPersistence = useUserConfigurationPersistence();\n//     const dialogsController = useDialogsController();\n//     const customizationController = useCustomizationController();\n//     const analyticsController = useAnalyticsController();\n//\n//     return {\n//         authController,\n//         sideDialogsController,\n//         sideEntityController,\n//         navigation,\n//         dataSource,\n//         storageSource,\n//         snackbarController,\n//         userConfigPersistence,\n//         dialogsController,\n//         customizationController,\n//         analyticsController\n//     };\n//\n// };\n","import { useEffect, useState } from \"react\";\nimport { Entity, EntityCollection, FireCMSContext, User } from \"../../types\";\nimport { useDataSource } from \"./useDataSource\";\nimport { useNavigationController } from \"../useNavigationController\";\nimport { useFireCMSContext } from \"../useFireCMSContext\";\n\n/**\n * @group Hooks and utilities\n */\nexport interface EntityFetchProps<M extends Record<string, any>, UserType extends User = User> {\n    path: string;\n    entityId?: string;\n    collection: EntityCollection<M, UserType>;\n    useCache?: boolean;\n}\n\n/**\n * @group Hooks and utilities\n */\nexport interface EntityFetchResult<M extends Record<string, any>> {\n    entity?: Entity<M>,\n    dataLoading: boolean,\n    dataLoadingError?: Error\n}\n\nconst CACHE: Record<string, Entity<any> | undefined> = {};\n\n/**\n * This hook is used to fetch an entity.\n * It gives real time updates if the datasource supports it.\n * @param path\n * @param collection\n * @param entityId\n * @param useCache\n * @group Hooks and utilities\n */\n\nexport function useEntityFetch<M extends Record<string, any>, UserType extends User>(\n    {\n        path: inputPath,\n        entityId,\n        collection,\n        useCache = false\n    }: EntityFetchProps<M, UserType>): EntityFetchResult<M> {\n\n    const dataSource = useDataSource(collection);\n    const navigationController = useNavigationController();\n\n    const path = navigationController.resolveAliasesFrom(inputPath);\n\n    const context: FireCMSContext<UserType> = useFireCMSContext();\n\n    const [entity, setEntity] = useState<Entity<M> | undefined>();\n    const [dataLoading, setDataLoading] = useState<boolean>(true);\n    const [dataLoadingError, setDataLoadingError] = useState<Error | undefined>();\n\n    useEffect(() => {\n\n        setDataLoading(true);\n\n        const onEntityUpdate = async (updatedEntity: Entity<M> | undefined) => {\n            if (collection.callbacks?.onFetch && updatedEntity) {\n                try {\n                    updatedEntity = await collection.callbacks.onFetch({\n                        collection,\n                        path,\n                        entity: updatedEntity,\n                        context\n                    });\n                } catch (e: any) {\n                    console.error(e);\n                }\n            }\n            CACHE[`${path}/${entityId}`] = updatedEntity;\n            setEntity(updatedEntity);\n            setDataLoading(false);\n            setDataLoadingError(undefined);\n        };\n\n        const onError = (error: Error) => {\n            console.error(\"ERROR fetching entity\", error);\n            setDataLoading(false);\n            setEntity(undefined);\n            setDataLoadingError(error);\n        };\n\n        if (entityId && useCache && CACHE[`${path}/${entityId}`]) {\n            setEntity(CACHE[`${path}/${entityId}`]);\n            setDataLoading(false);\n            setDataLoadingError(undefined);\n            // eslint-disable-next-line @typescript-eslint/no-empty-function\n            return () => {\n            };\n        } else if (entityId && path && collection) {\n            if (dataSource.listenEntity) {\n                return dataSource.listenEntity<M>({\n                    path,\n                    entityId,\n                    collection,\n                    onUpdate: onEntityUpdate,\n                    onError\n                });\n            } else {\n                dataSource.fetchEntity<M>({\n                    path,\n                    entityId,\n                    collection\n                })\n                    .then(onEntityUpdate)\n                    .catch(onError);\n                return () => {\n                };\n            }\n        }\n        // if no entityId is provided we do nothing\n        else {\n            onEntityUpdate(undefined);\n            return () => {\n            };\n        }\n    }, [entityId, path]);\n\n    return {\n        entity,\n        dataLoading,\n        dataLoadingError\n    };\n\n}\n","import {\n    DataSource,\n    Entity,\n    EntityCallbacks,\n    EntityCollection,\n    EntityValues,\n    FireCMSContext,\n    SaveEntityProps,\n    User\n} from \"../../types\";\nimport { useDataSource } from \"./useDataSource\";\nimport { resolveCollection } from \"../../util\";\n\n/**\n * @group Hooks and utilities\n */\nexport type SaveEntityWithCallbacksProps<M extends Record<string, any>> =\n    SaveEntityProps<M> &\n    {\n        onSaveSuccess?: (updatedEntity: Entity<M>) => void,\n        onSaveFailure?: (e: Error) => void,\n        onPreSaveHookError?: (e: Error) => void,\n        onSaveSuccessHookError?: (e: Error) => void\n    }\n\n/**\n * This function is in charge of saving an entity to the datasource.\n * It will run all the save callbacks specified in the collection.\n * It is also possible to attach callbacks on save success or error, and callback\n * errors.\n *\n * If you just want to save the data without running the `onSaveSuccess`,\n * `onSaveFailure` and `onPreSave` callbacks, you can use the `saveEntity` method\n * in the datasource ({@link useDataSource}).\n *\n * @param collection\n * @param path\n * @param entityId\n * @param callbacks\n * @param values\n * @param previousValues\n * @param status\n * @param dataSource\n * @param context\n * @param onSaveSuccess\n * @param onSaveFailure\n * @param onPreSaveHookError\n * @param onSaveSuccessHookError\n * @see useDataSource\n * @group Hooks and utilities\n */\nexport async function saveEntityWithCallbacks<M extends Record<string, any>, UserType extends User>({\n                                                                                                        collection,\n                                                                                                        path,\n                                                                                                        entityId,\n                                                                                                        values,\n                                                                                                        previousValues,\n                                                                                                        status,\n                                                                                                        dataSource,\n                                                                                                        context,\n                                                                                                        onSaveSuccess,\n                                                                                                        onSaveFailure,\n                                                                                                        onPreSaveHookError,\n                                                                                                        onSaveSuccessHookError\n                                                                                                    }: SaveEntityWithCallbacksProps<M> & {\n                                                                                                        collection: EntityCollection<M, UserType>,\n                                                                                                        dataSource: DataSource,\n                                                                                                        context: FireCMSContext<UserType>,\n                                                                                                    }\n): Promise<void> {\n\n    if (status !== \"new\" && !entityId) {\n        throw new Error(\"Entity id must be specified when updating an existing entity\");\n    }\n    let updatedValues: Partial<EntityValues<M>>;\n\n    const customizationController = context.customizationController;\n\n    const resolvedPath = context.navigation.resolveAliasesFrom(path);\n\n    const callbacks = collection.callbacks;\n    if (callbacks?.onPreSave) {\n        try {\n            const resolvedCollection = resolveCollection<M>({\n                collection,\n                path,\n                values: previousValues as EntityValues<M>,\n                entityId,\n                fields: customizationController.propertyConfigs\n            });\n            updatedValues = await callbacks.onPreSave({\n                collection: resolvedCollection,\n                path,\n                resolvedPath,\n                entityId,\n                values,\n                previousValues,\n                status,\n                context\n            });\n        } catch (e: any) {\n            console.error(e);\n            if (onPreSaveHookError)\n                onPreSaveHookError(e);\n            return;\n        }\n    } else {\n        updatedValues = values;\n    }\n\n    return dataSource.saveEntity({\n        collection,\n        path: resolvedPath,\n        entityId,\n        values: updatedValues,\n        previousValues,\n        status\n    }).then((entity) => {\n        try {\n            if (callbacks?.onSaveSuccess) {\n                const resolvedCollection = resolveCollection<M>({\n                    collection,\n                    path,\n                    values: updatedValues as EntityValues<M>,\n                    entityId,\n                    fields: customizationController.propertyConfigs\n                });\n                callbacks.onSaveSuccess({\n                    collection: resolvedCollection,\n                    path,\n                    resolvedPath,\n                    entityId: entity.id,\n                    values: updatedValues,\n                    previousValues,\n                    status,\n                    context\n                });\n            }\n        } catch (e: any) {\n            if (onSaveSuccessHookError)\n                onSaveSuccessHookError(e);\n        }\n        if (onSaveSuccess)\n            onSaveSuccess(entity);\n    })\n        .catch((e) => {\n            console.error(\"!!!\", e);\n            if (callbacks?.onSaveFailure) {\n\n                const resolvedCollection = resolveCollection<M>({\n                    collection,\n                    path,\n                    values: updatedValues as EntityValues<M>,\n                    entityId,\n                    fields: customizationController.propertyConfigs\n                });\n                callbacks.onSaveFailure({\n                    collection: resolvedCollection,\n                    path,\n                    resolvedPath,\n                    entityId,\n                    values: updatedValues,\n                    previousValues,\n                    status,\n                    context\n                });\n            }\n            if (onSaveFailure) onSaveFailure(e);\n        });\n}\n","import {\n    DataSource,\n    DeleteEntityProps,\n    Entity,\n    EntityCallbacks,\n    EntityOnDeleteProps,\n    FireCMSContext,\n    ResolvedEntityCollection,\n    User\n} from \"../../types\";\n\n/**\n * @group Hooks and utilities\n */\nexport type DeleteEntityWithCallbacksProps<M extends Record<string, any>, UserType extends User = User> =\n    DeleteEntityProps<M>\n    & {\n    callbacks?: EntityCallbacks<M, UserType>;\n    onDeleteSuccess?: (entity: Entity<M>) => void;\n    onDeleteFailure?: (entity: Entity<M>, e: Error) => void;\n    onPreDeleteHookError?: (entity: Entity<M>, e: Error) => void;\n    onDeleteSuccessHookError?: (entity: Entity<M>, e: Error) => void;\n}\n\n/**\n * This function is in charge of deleting an entity in the datasource.\n * It will run all the delete callbacks specified in the collection.\n * It is also possible to attach callbacks on save success or error, and callback\n * errors.\n *\n * If you just want to delete any data without running the `onPreDelete`,\n * and `onDelete` callbacks, you can use the `deleteEntity` method\n * in the datasource ({@link useDataSource}).\n *\n * @param dataSource\n * @param entity\n * @param collection\n * @param callbacks\n * @param onDeleteSuccess\n * @param onDeleteFailure\n * @param onPreDeleteHookError\n * @param onDeleteSuccessHookError\n * @param context\n * @group Hooks and utilities\n */\nexport async function deleteEntityWithCallbacks<M extends Record<string, any>, UserType extends User>({\n                                                                                                          dataSource,\n                                                                                                          entity,\n                                                                                                          collection,\n                                                                                                          callbacks,\n                                                                                                          onDeleteSuccess,\n                                                                                                          onDeleteFailure,\n                                                                                                          onPreDeleteHookError,\n                                                                                                          onDeleteSuccessHookError,\n                                                                                                          context\n                                                                                                      }: DeleteEntityWithCallbacksProps<M> & {\n                                                                                                          collection: ResolvedEntityCollection<M>,\n                                                                                                          dataSource: DataSource,\n                                                                                                          context: FireCMSContext<UserType>\n                                                                                                      }\n): Promise<boolean> {\n\n    console.debug(\"Deleting entity\", entity.path, entity.id);\n\n    const entityDeleteProps: EntityOnDeleteProps<M, any> = {\n        entity,\n        collection,\n        entityId: entity.id,\n        path: entity.path,\n        context\n    };\n\n    if (callbacks?.onPreDelete) {\n        try {\n            await callbacks.onPreDelete(entityDeleteProps);\n        } catch (e: any) {\n            console.error(e);\n            if (onPreDeleteHookError)\n                onPreDeleteHookError(entity, e);\n            return false;\n        }\n    }\n    return dataSource.deleteEntity({\n        entity\n    }).then(() => {\n        onDeleteSuccess && onDeleteSuccess(entity);\n        try {\n            if (callbacks?.onDelete) {\n                callbacks.onDelete(entityDeleteProps);\n            }\n            return true;\n        } catch (e: any) {\n            if (onDeleteSuccessHookError)\n                onDeleteSuccessHookError(entity, e);\n            return false;\n        }\n    }).catch((e) => {\n        if (onDeleteFailure) onDeleteFailure(entity, e);\n        return false;\n    });\n}\n","import { Entity, EntityCollection, EntityCustomView, FireCMSContext, User } from \"../types\";\nimport { useEffect, useState } from \"react\";\nimport { getNavigationEntriesFromPathInternal } from \"../util/navigation_from_path\";\nimport { useFireCMSContext } from \"./useFireCMSContext\";\n\n/**\n * @see resolveNavigationFrom\n * @group Hooks and utilities\n */\nexport type ResolvedNavigationEntry<M extends Record<string, any>> =\n    | ResolvedNavigationEntity<M>\n    | ResolvedNavigationCollection<M>\n    | ResolvedNavigationEntityCustom<M>;\n\n/**\n * @see resolveNavigationFrom\n * @group Hooks and utilities\n */\nexport interface ResolvedNavigationEntity<M extends Record<string, any>> {\n    type: \"entity\";\n    entity: Entity<M>;\n    entityId: string;\n    path: string;\n    parentCollection: EntityCollection<M>;\n}\n\n/**\n * @see resolveNavigationFrom\n * @group Hooks and utilities\n */\nexport interface ResolvedNavigationCollection<M extends Record<string, any>> {\n    type: \"collection\";\n    path: string;\n    collection: EntityCollection<M>;\n}\n\n/**\n * @see resolveNavigationFrom\n * @group Hooks and utilities\n */\ninterface ResolvedNavigationEntityCustom<M extends Record<string, any>> {\n    type: \"custom_view\";\n    path: string;\n    view: EntityCustomView<M>;\n}\n\n/**\n * Use this function to retrieve an array of navigation entries (resolved\n * collection, entity or entity custom_view) for the given path. You need to pass the app context\n * that you receive in different callbacks, such as the save hooks.\n *\n * It will take into account the `navigation` provided at the `FireCMS` level.\n *\n * @param path\n * @param context\n * @group Hooks and utilities\n */\nexport function resolveNavigationFrom<M extends Record<string, any>, UserType extends User>({\n                                                                                                path,\n                                                                                                context\n                                                                                            }: {\n    path: string,\n    context: FireCMSContext<UserType>\n}): Promise<ResolvedNavigationEntry<M>[]> {\n\n    const dataSource = context.dataSource;\n    const navigation = context.navigation;\n\n    if (!navigation) {\n        throw Error(\"Calling getNavigationFrom, but main navigation has not yet been initialised\");\n    }\n\n    const navigationEntries = getNavigationEntriesFromPathInternal({\n        path,\n        collections: navigation.collections ?? []\n    });\n\n    const resultPromises: Promise<ResolvedNavigationEntry<any>>[] = navigationEntries\n        .map((entry) => {\n            if (entry.type === \"collection\") {\n                return Promise.resolve(entry);\n            } else if (entry.type === \"entity\") {\n                const collection = navigation.getCollection(entry.path);\n                if (!collection) {\n                    throw Error(`No collection defined in the navigation for the entity with path ${entry.path}`);\n                }\n                return dataSource.fetchEntity({\n                    path: entry.path,\n                    entityId: entry.entityId,\n                    collection\n                })\n                    .then((entity) => {\n                        if (!entity) return undefined;\n                        return { ...entry, entity };\n                    });\n            } else if (entry.type === \"custom_view\") {\n                return Promise.resolve(entry);\n            } else {\n                throw Error(\"Unmapped element in useEntitiesFromPath\");\n            }\n        })\n        .filter(v => Boolean(v)) as Promise<ResolvedNavigationEntry<any>>[];\n\n    return Promise.all(resultPromises);\n}\n\n/**\n * @group Hooks and utilities\n */\nexport interface NavigationFromProps {\n    path: string;\n}\n\n/**\n * @group Hooks and utilities\n */\nexport interface NavigationFrom<M extends Record<string, any>> {\n    data?: ResolvedNavigationEntry<M>[]\n    dataLoading: boolean,\n    dataLoadingError?: Error\n}\n\n/**\n * Use this hook to retrieve an array of navigation entries (resolved\n * collection or entity) for the given path. You can use this hook\n * in any React component that lives under `FireCMS`\n * @group Hooks and utilities\n */\nexport function useResolvedNavigationFrom<M extends Record<string, any>, UserType extends User>(\n    {\n        path\n    }: NavigationFromProps): NavigationFrom<M> {\n\n    const context: FireCMSContext<UserType> = useFireCMSContext();\n\n    const [data, setData] = useState<ResolvedNavigationEntry<M>[] | undefined>();\n    const [dataLoading, setDataLoading] = useState<boolean>(false);\n    const [dataLoadingError, setDataLoadingError] = useState<Error | undefined>();\n\n    useEffect(() => {\n        const navigation = context.navigation;\n        if (navigation) {\n            setDataLoading(true);\n            setDataLoadingError(undefined);\n            resolveNavigationFrom<M, UserType>({ path, context })\n                .then((res) => {\n                    setData(res);\n                })\n                .catch((e) => setDataLoadingError(e))\n                .finally(() => setDataLoading(false));\n        }\n\n    }, [path, context]);\n\n    if (!context.navigation) {\n        return { dataLoading: true };\n    }\n\n    return { data, dataLoading, dataLoadingError };\n}\n","import { ModeControllerContext } from \"../contexts/ModeController\";\nimport { useContext } from \"react\";\n\n/**\n * Use this controller to change color mode\n * @group Hooks and utilities\n */\nexport interface ModeController {\n    mode: \"light\" | \"dark\";\n    setMode: (mode: \"light\" | \"dark\") => void;\n    toggleMode: () => void;\n}\n\n/**\n * Hook to retrieve the current mode (\"light\" | \"dark\"), and `setMode`\n * or `toggle` functions to change it.\n *\n * Consider that in order to use this hook you need to have a parent\n * `FireCMS`\n *\n * @see ModeController\n * @group Hooks and utilities\n */\nexport const useModeController = () => useContext(ModeControllerContext);\n","// FORKED FROM https://github.com/fayeed/use-clipboard\n\nimport { MutableRefObject, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UseClipboardProps {\n    /**\n     * It's callback function that is called after the `copy` command\n     * is executed.\n     *\n     * @param text: The selected clipboard text.\n     */\n    onSuccess?: (text: string) => void;\n\n    /**\n     * Triggers when the hook encounters an error.\n     * If passed hook won't throw an error.\n     *\n     * @param error: cause of the error\n     */\n    onError?: (error: string) => void;\n\n    /**\n     * Disables the new clipboard API `navigator.clipboard` even if\n     * it is supported.\n     */\n    disableClipboardAPI?: boolean;\n\n    /**\n     * revert back the isCopied flag to false again if a value is set.\n     */\n    copiedDuration?: number;\n}\n\nexport interface useClipboardReturnType {\n    /**\n     * Use ref to pull the text content from.\n     */\n    ref: MutableRefObject<any>;\n\n    /**\n     * Use it to perform the copy operation\n     */\n    copy: (text?: string) => void;\n\n    /**\n     * Use it to perform the cut operation\n     */\n    cut: () => void;\n\n    /**\n     * Indicates wheater the content was successfully copied or not.\n     */\n    isCoppied: boolean;\n\n    /**\n     * Current selected clipboard content.\n     */\n    clipboard: string;\n\n    /**\n     * Clears the user clipboard.\n     */\n    clearClipboard: () => void;\n\n    /**\n     * Check to see if the browser supports the new `navigator.clipboard` API.\n     */\n    isSupported: () => boolean;\n}\n\nexport const useClipboard = (\n    options?: UseClipboardProps\n): useClipboardReturnType => {\n    const { onSuccess, onError, disableClipboardAPI = false, copiedDuration } =\n    options || {};\n    const ref = useRef<any>(null);\n    const [isCoppied, setIsCoppied] = useState(false);\n    const [clipboard, setClipbaord] = useState(\"\");\n\n    useEffect(() => {\n        if (copiedDuration) setTimeout(() => setIsCoppied(false), copiedDuration);\n    }, [isCoppied]);\n\n    const isSupported = () => navigator.clipboard !== undefined;\n\n    const handleError = useCallback((error: string) => {\n        if (onError) onError(error);\n        else throw new Error(error);\n    }, [onError]);\n\n    const handleSuccess = useCallback((text: string) => {\n        if (onSuccess) onSuccess(text);\n        setIsCoppied(true);\n        setClipbaord(text);\n    }, [onSuccess]);\n\n    const copyToClipboard = useCallback((text: string) => {\n        navigator.clipboard\n            .writeText(text)\n            .then(() => handleSuccess(text))\n            .catch((err) => {\n                handleError(err);\n                setIsCoppied(false);\n            });\n    }, [handleError, handleSuccess]);\n\n    const clearClipboard = () => {\n        if (isSupported()) {\n            navigator.clipboard.writeText(\"\");\n        }\n    };\n\n    const copy = (text?: string) =>\n        action(\"copy\", typeof text === \"object\" ? undefined : text);\n\n    const cut = () => action(\"cut\");\n\n    const action = useCallback(\n        (operation = \"copy\", text?: string) => {\n            const element = ref.current as HTMLElement;\n\n            const isInput =\n                element &&\n                (element.tagName === \"INPUT\" || element.tagName === \"TEXTAREA\");\n\n            const input = ref.current as HTMLInputElement;\n\n            if (isSupported() && !disableClipboardAPI) {\n                if (text) {\n                    copyToClipboard(text);\n                } else if (element) {\n                    if (isInput) {\n                        copyToClipboard(input.value);\n\n                        if (operation === \"cut\") {\n                            input.value = \"\";\n                        }\n                    } else {\n                        copyToClipboard(element.innerText);\n                    }\n                } else {\n                    handleError(\"Both the ref & text were undefined\");\n                }\n            }\n        },\n        [disableClipboardAPI, copyToClipboard, handleError]\n    );\n\n    return {\n        ref,\n        isCoppied,\n        clipboard,\n        clearClipboard,\n        isSupported,\n        copy,\n        cut\n    };\n};\n","import { useEffect, useState } from \"react\";\n\ntype LayoutListener = (isLargeLayout: boolean) => void;\n\nconst breakpoints = {\n    xs: 0,\n    sm: 640,\n    md: 768,\n    lg: 1024,\n    xl: 1280,\n    \"2xl\": 1536,\n    \"3xl\": 1920\n}\n\n// Global state and listeners array\nlet isLargeLayoutGlobal = checkLargeLayout(\"lg\"); // Default value\nconst listeners: LayoutListener[] = [];\n\n// Utility to notify all listeners\nconst notifyListeners = () => {\n    listeners.forEach(listener => listener(isLargeLayoutGlobal));\n};\n\n// Listen to resize events once, at a global level\nif (typeof window !== \"undefined\")\n    window.addEventListener(\"resize\", () => {\n        const newIsLargeLayout = checkLargeLayout(\"lg\");\n        if (newIsLargeLayout !== isLargeLayoutGlobal) {\n            isLargeLayoutGlobal = newIsLargeLayout;\n            notifyListeners();\n        }\n    });\n\nexport const useLargeLayout = () => {\n    const [isLargeLayout, setIsLargeLayout] = useState(isLargeLayoutGlobal);\n\n    useEffect(() => {\n        // Listener function to update component state\n        const listener: LayoutListener = (newIsLargeLayout) => {\n            setIsLargeLayout(newIsLargeLayout);\n        };\n\n        // Register listener\n        listeners.push(listener);\n\n        // Initial state\n        setIsLargeLayout(isLargeLayoutGlobal);\n\n        // Clean up by removing the listener\n        return () => {\n            const index = listeners.indexOf(listener);\n            if (index > -1) {\n                listeners.splice(index, 1);\n            }\n        };\n    }, []);\n\n    return isLargeLayout;\n};\n\nfunction checkLargeLayout(breakpoint: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" = \"lg\"): boolean {\n    if (typeof window === \"undefined\")\n        return false;\n    return window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;\n}\n\n// import { useEffect, useState } from \"react\";\n//\n// const breakpoints = {\n//     xs: 0,\n//     sm: 640,\n//     md: 768,\n//     lg: 1024,\n//     xl: 1280,\n//     \"2xl\": 1536,\n//     \"3xl\": 1920\n// }\n// export const useLargeLayout = (breakpoint: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" = \"lg\"): boolean => {\n//     const [isLargeLayout, setIsLargeLayout] = useState<boolean>(false);\n//\n//     useEffect(() => {\n//         const handleResize = () => {\n//             const matched = window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;\n//             setIsLargeLayout(matched);\n//         };\n//\n//         // Set initial state\n//         handleResize();\n//\n//         // Set up event listener for resize events\n//         window.addEventListener(\"resize\", handleResize);\n//\n//         // Clean up event listener when component unmounts\n//         return () => {\n//             window.removeEventListener(\"resize\", handleResize);\n//         };\n//     }, []);\n//\n//     return isLargeLayout;\n// };\n","import { useSideDialogsController } from \"./useSideDialogsController\";\nimport { ReferenceSelectionInnerProps, ReferenceSelectionTable } from \"../components\";\nimport { useCallback } from \"react\";\nimport { useNavigationController } from \"./useNavigationController\";\n\n/**\n * This hook is used to open a side dialog that allows the selection\n * of entities under a given path.\n * You can use it in custom views for selecting entities.\n * You need to specify the path of the target collection at least.\n * If your collection is not defined in your  top collection configuration\n * (in your `FireCMS` component), you need to specify explicitly.\n * This is the same hook used internally when a reference property is defined.\n * @group Hooks and utilities\n */\nexport function useReferenceDialog<M extends Record<string, any>>(referenceDialogProps: Omit<ReferenceSelectionInnerProps<M>, \"path\"> & {\n    path?: string | false;\n    onClose?: () => void;\n}): { open: () => void; close: () => void } {\n\n    const navigation = useNavigationController();\n    const sideDialogsController = useSideDialogsController();\n\n    const open = useCallback(() => {\n        if (referenceDialogProps.path) {\n            let usedCollection = referenceDialogProps.collection;\n            if (!usedCollection)\n                usedCollection = navigation.getCollection(referenceDialogProps.path);\n            if (!usedCollection)\n                throw Error(\"Not able to resolve the collection in useReferenceDialog. Make sure a collection is registered in path \" + referenceDialogProps.path);\n            sideDialogsController.open({\n                key: `reference_${referenceDialogProps.path}`,\n                component:\n                    <ReferenceSelectionTable\n                        collection={usedCollection}\n                        {...referenceDialogProps as ReferenceSelectionInnerProps<M>}/>,\n                width: \"90vw\",\n                onClose: () => {\n                    referenceDialogProps.onClose?.();\n                }\n            });\n        } else {\n            throw Error(\"useReferenceDialog: You are trying to open a reference dialog, but have not declared the `path`\")\n        }\n    }, [navigation, referenceDialogProps, sideDialogsController]);\n\n    const close = useCallback(() => {\n        sideDialogsController.close();\n    }, [sideDialogsController]);\n\n    return {\n        open,\n        close\n    }\n\n}\n","import { EntityCollection, EntityReference } from \"../types\";\nimport { getCollectionPathsCombinations, removeInitialAndTrailingSlashes } from \"./navigation_utils\";\n\nexport function getParentReferencesFromPath(props: {\n    path: string,\n    collections: EntityCollection[] | undefined,\n    currentFullPath?: string,\n}): EntityReference [] {\n\n    const {\n        path,\n        collections = [],\n        currentFullPath,\n    } = props;\n\n    const subpaths = removeInitialAndTrailingSlashes(path).split(\"/\");\n    const subpathCombinations = getCollectionPathsCombinations(subpaths);\n\n    const result: EntityReference[] = [];\n    for (let i = 0; i < subpathCombinations.length; i++) {\n        const subpathCombination = subpathCombinations[i];\n\n        const collection: EntityCollection<any> | undefined = collections && collections.find((entry) => entry.id === subpathCombination || entry.path === subpathCombination);\n\n        if (collection) {\n            const pathOrAlias = collection.id ?? collection.path;\n            const collectionPath = currentFullPath && currentFullPath.length > 0\n                ? (currentFullPath + \"/\" + pathOrAlias)\n                : pathOrAlias;\n\n            const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, \"\"));\n            const nextSegments = restOfThePath.length > 0 ? restOfThePath.split(\"/\") : [];\n            if (nextSegments.length > 0) {\n                const entityId = nextSegments[0];\n                const fullPath = collectionPath + \"/\" + entityId;\n                result.push(new EntityReference(entityId, collectionPath));\n                if (nextSegments.length > 1) {\n                    const newPath = nextSegments.slice(1).join(\"/\");\n                    if (!collection) {\n                        throw Error(\"collection not found resolving path: \" + collection);\n                    }\n                    if (collection.subcollections) {\n                        result.push(...getParentReferencesFromPath({\n                            path: newPath,\n                            collections: collection.subcollections,\n                            currentFullPath: fullPath\n                        }));\n                    }\n                }\n            }\n            break;\n        }\n\n    }\n    return result;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport equal from \"react-fast-compare\"\n\nimport {\n    AuthController,\n    CMSView,\n    CMSViewsBuilder,\n    DataSourceDelegate,\n    EntityCollection,\n    EntityCollectionsBuilder,\n    EntityReference,\n    NavigationController,\n    PermissionsBuilder,\n    TopNavigationEntry,\n    TopNavigationResult,\n    User,\n    UserConfigurationPersistence\n} from \"../types\";\nimport {\n    applyPermissionsFunctionIfEmpty,\n    getCollectionByPathOrId,\n    mergeDeep,\n    removeInitialAndTrailingSlashes,\n    resolveCollectionPathIds,\n    resolvePermissions\n} from \"../util\";\nimport { getParentReferencesFromPath } from \"../util/parent_references_from_path\";\n\nconst DEFAULT_BASE_PATH = \"/\";\nconst DEFAULT_COLLECTION_PATH = \"/c\";\n\nexport type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {\n    basePath?: string,\n    baseCollectionPath?: string,\n    authController: AuthController<UserType>;\n    collections?: EC[] | EntityCollectionsBuilder<EC>;\n    collectionPermissions?: PermissionsBuilder;\n    views?: CMSView[] | CMSViewsBuilder;\n    adminViews?: CMSView[] | CMSViewsBuilder;\n    viewsOrder?: string[];\n    userConfigPersistence?: UserConfigurationPersistence;\n    dataSourceDelegate: DataSourceDelegate;\n    /**\n     * Use this method to inject collections to the CMS.\n     * You receive the current collections as a parameter, and you can return\n     * a new list of collections.\n     * @see {@link joinCollectionLists}\n     * @param collections\n     */\n    injectCollections?: (collections: EntityCollection[]) => EntityCollection[];\n};\n\nexport function useBuildNavigationController<EC extends EntityCollection, UserType extends User>(props: BuildNavigationContextProps<EC, UserType>): NavigationController {\n    const {\n        basePath = DEFAULT_BASE_PATH,\n        baseCollectionPath = DEFAULT_COLLECTION_PATH,\n        authController,\n        collections: collectionsProp,\n        collectionPermissions,\n        views: viewsProp,\n        adminViews: adminViewsProp,\n        viewsOrder,\n        userConfigPersistence,\n        dataSourceDelegate,\n        injectCollections\n    } = props;\n\n    const collectionsRef = useRef<EntityCollection[] | undefined>();\n    const viewsRef = useRef<CMSView[] | undefined>();\n    const adminViewsRef = useRef<CMSView[] | undefined>();\n\n    const [initialised, setInitialised] = useState<boolean>(false);\n\n    const [topLevelNavigation, setTopLevelNavigation] = useState<TopNavigationResult | undefined>(undefined);\n    const [navigationLoading, setNavigationLoading] = useState<boolean>(true);\n    const [navigationLoadingError, setNavigationLoadingError] = useState<Error | undefined>(undefined);\n\n    const cleanBasePath = removeInitialAndTrailingSlashes(basePath);\n    const cleanBaseCollectionPath = removeInitialAndTrailingSlashes(baseCollectionPath);\n\n    const homeUrl = cleanBasePath ? `/${cleanBasePath}` : \"/\";\n\n    const fullCollectionPath = cleanBasePath ? `/${cleanBasePath}/${cleanBaseCollectionPath}` : `/${cleanBaseCollectionPath}`;\n\n    const buildCMSUrlPath = useCallback((path: string): string => cleanBasePath ? `/${cleanBasePath}/${encodePath(path)}` : `/${encodePath(path)}`,\n        [cleanBasePath]);\n\n    const buildUrlCollectionPath = useCallback((path: string): string => `${removeInitialAndTrailingSlashes(baseCollectionPath)}/${encodePath(path)}`,\n        [baseCollectionPath]);\n\n    const computeTopNavigation = useCallback((collections: EntityCollection[], views: CMSView[], adminViews: CMSView[], viewsOrder?: string[]): TopNavigationResult => {\n        let navigationEntries: TopNavigationEntry[] = [\n            ...(collections ?? []).map(collection => (!collection.hideFromNavigation\n                ? ({\n                    url: buildUrlCollectionPath(collection.id ?? collection.path),\n                    type: \"collection\",\n                    name: collection.name.trim(),\n                    path: collection.id ?? collection.path,\n                    collection,\n                    description: collection.description?.trim(),\n                    group: getGroup(collection)\n                } satisfies TopNavigationEntry)\n                : undefined))\n                .filter(Boolean) as TopNavigationEntry[],\n            ...(views ?? []).map(view =>\n                !view.hideFromNavigation\n                    ? ({\n                        url: buildCMSUrlPath(Array.isArray(view.path) ? view.path[0] : view.path),\n                        name: view.name.trim(),\n                        type: \"view\",\n                        path: view.path,\n                        view,\n                        description: view.description?.trim(),\n                        group: getGroup(view)\n                    } satisfies TopNavigationEntry)\n                    : undefined)\n                .filter(Boolean) as TopNavigationEntry[],\n            ...(adminViews ?? []).map(view =>\n                !view.hideFromNavigation\n                    ? ({\n                        url: buildCMSUrlPath(Array.isArray(view.path) ? view.path[0] : view.path),\n                        name: view.name.trim(),\n                        type: \"admin\",\n                        path: view.path,\n                        view,\n                        description: view.description?.trim(),\n                        group: \"Admin\"\n                    } satisfies TopNavigationEntry)\n                    : undefined)\n                .filter(Boolean) as TopNavigationEntry[]\n        ];\n\n        // Sort by group, entries with group \"Admin\" will go last, and second to last will be the group \"Views\"\n        navigationEntries = navigationEntries.sort((a, b) => {\n            if (a.group !== \"Views\" && a.group !== \"Admin\" && (b.group === \"Views\" || b.group === \"Admin\")) {\n                return -1;\n            }\n            if (b.group !== \"Views\" && b.group !== \"Admin\" && (a.group === \"Views\" || a.group === \"Admin\")) {\n                return 1;\n            }\n            if (a.group === \"Admin\" && b.group !== \"Admin\") {\n                return 1;\n            }\n            if (a.group !== \"Admin\" && b.group === \"Admin\") {\n                return -1;\n            }\n            if (a.group === \"Views\" && b.group !== \"Views\") {\n                return -1;\n            }\n            if (a.group !== \"Views\" && b.group === \"Views\") {\n                return 1;\n            }\n            return 0;\n\n        });\n\n        if (viewsOrder) {\n            navigationEntries = navigationEntries.sort((a, b) => {\n                const aIndex = viewsOrder.indexOf(a.path);\n                const bIndex = viewsOrder.indexOf(b.path);\n                if (aIndex === -1 && bIndex === -1) {\n                    return 0;\n                }\n                if (aIndex === -1) {\n                    return 1;\n                }\n                if (bIndex === -1) {\n                    return -1;\n                }\n                return aIndex - bIndex;\n            });\n        }\n\n        const groups: string[] = Object.values(navigationEntries)\n            .map(e => e.group)\n            .filter(Boolean)\n            .filter((value, index, array) => array.indexOf(value) === index) as string[];\n\n        return {\n            navigationEntries,\n            groups\n        };\n    }, [buildCMSUrlPath, buildUrlCollectionPath]);\n\n    const refreshNavigation = useCallback(async () => {\n\n        if (authController.initialLoading)\n            return;\n\n        console.debug(\"Refreshing navigation\");\n\n        try {\n\n            const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([\n                    resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, injectCollections),\n                    resolveCMSViews(viewsProp, authController, dataSourceDelegate),\n                    resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)\n                ]\n            );\n\n            let shouldUpdateTopLevelNav = false;\n            if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {\n                collectionsRef.current = resolvedCollections;\n                shouldUpdateTopLevelNav = true;\n            }\n            if (!equal(viewsRef.current, resolvedViews)) {\n                viewsRef.current = resolvedViews;\n                shouldUpdateTopLevelNav = true;\n            }\n            if (!equal(adminViewsRef.current, resolvedAdminViews)) {\n                adminViewsRef.current = resolvedAdminViews;\n                shouldUpdateTopLevelNav = true;\n            }\n\n            const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);\n            if (shouldUpdateTopLevelNav && !equal(topLevelNavigation, computedTopLevelNav)) {\n                setTopLevelNavigation(computedTopLevelNav);\n            }\n        } catch (e) {\n            console.error(e);\n            setNavigationLoadingError(e as any);\n        }\n\n        setNavigationLoading(false);\n        setInitialised(true);\n\n    }, [\n        collectionsProp,\n        collectionPermissions,\n        authController.user,\n        authController.initialLoading,\n        viewsProp,\n        adminViewsProp,\n        computeTopNavigation,\n        injectCollections\n    ]);\n\n    useEffect(() => {\n        refreshNavigation();\n    }, [refreshNavigation]);\n\n    const getCollection = useCallback((\n        idOrPath: string,\n        includeUserOverride = false\n    ): EC | undefined => {\n        const collections = collectionsRef.current;\n        if (!collections)\n            return undefined;\n\n        const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections);\n\n        const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : undefined;\n        const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride) : undefined;\n\n        let result: Partial<EntityCollection> | undefined = overriddenCollection;\n\n        if (overriddenCollection) {\n            const subcollections = overriddenCollection.subcollections;\n            const callbacks = overriddenCollection.callbacks;\n            const permissions = overriddenCollection.permissions;\n            result = {\n                ...result,\n                subcollections: result?.subcollections ?? subcollections,\n                callbacks: result?.callbacks ?? callbacks,\n                permissions: result?.permissions ?? permissions\n            };\n        }\n\n        if (!result) return undefined;\n\n        return { ...overriddenCollection, ...result } as EC;\n\n    }, [userConfigPersistence]);\n\n    const getCollectionFromPaths = useCallback(<EC extends EntityCollection>(pathSegments: string[]): EC | undefined => {\n\n        const collections = collectionsRef.current;\n        if (collections === undefined)\n            throw Error(\"getCollectionFromPaths: Collections have not been initialised yet\");\n        let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];\n\n        for (let i = 0; i < pathSegments.length; i++) {\n            const pathSegment = pathSegments[i];\n            const collection: EntityCollection | undefined = currentCollections!.find(c => c.id === pathSegment || c.path === pathSegment);\n            if (!collection)\n                return undefined;\n            currentCollections = collection.subcollections;\n            if (i === pathSegments.length - 1)\n                return collection as EC;\n        }\n\n        return undefined;\n\n    }, []);\n\n    const getCollectionFromIds = useCallback(<EC extends EntityCollection>(ids: string[]): EC | undefined => {\n\n        const collections = collectionsRef.current;\n        if (collections === undefined)\n            throw Error(\"getCollectionFromIds: Collections have not been initialised yet\");\n        let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];\n\n        for (let i = 0; i < ids.length; i++) {\n            const id = ids[i];\n            const collection: EntityCollection | undefined = currentCollections!.find(c => c.id === id);\n            if (!collection)\n                return undefined;\n            currentCollections = collection.subcollections;\n            if (i === ids.length - 1)\n                return collection as EC;\n        }\n\n        return undefined;\n\n    }, []);\n\n    const isUrlCollectionPath = useCallback(\n        (path: string): boolean => removeInitialAndTrailingSlashes(path + \"/\").startsWith(removeInitialAndTrailingSlashes(fullCollectionPath) + \"/\"),\n        [fullCollectionPath]);\n\n    const urlPathToDataPath = useCallback((path: string): string => {\n        if (path.startsWith(fullCollectionPath))\n            return path.replace(fullCollectionPath, \"\");\n        throw Error(\"Expected path starting with \" + fullCollectionPath);\n    }, [fullCollectionPath]);\n\n    const buildUrlEditCollectionPath = useCallback(({\n                                                        path\n                                                    }: {\n            path: string\n        }): string => {\n            return `s/edit/${encodePath(path)}`;\n        },\n        []);\n\n    const resolveAliasesFrom = useCallback((path: string): string => {\n        const collections = collectionsRef.current ?? [];\n        return resolveCollectionPathIds(path, collections);\n    }, []);\n\n    const getAllParentReferencesForPath = useCallback((path: string): EntityReference[] => {\n        const collections = collectionsRef.current ?? [];\n        return getParentReferencesFromPath({\n            path,\n            collections\n        });\n    }, []);\n\n    const getParentCollectionIds = useCallback((path: string): string[] => {\n\n        const strings = path.split(\"/\");\n        const oddPathSegments = strings.filter((_, i) => i % 2 === 0);\n        oddPathSegments.pop();\n\n        const result: string[][] = [];\n\n        for (let i = 1; i <= oddPathSegments.length; i++) {\n            result.push(oddPathSegments.slice(0, i));\n        }\n\n        // for each odd path segment, get the collection\n        return result.map(r => getCollectionFromPaths(r)?.id).filter(Boolean) as string[];\n    }, [getAllParentReferencesForPath])\n\n    const convertIdsToPaths = useCallback((ids: string[]): string[] => {\n        const collections = collectionsRef.current;\n        let currentCollections = collections;\n        const paths: string[] = [];\n        for (let i = 0; i < ids.length; i++) {\n            const id = ids[i];\n            const collection: EntityCollection | undefined = currentCollections!.find(c => c.id === id);\n            if (!collection)\n                throw Error(`Collection with id ${id} not found`);\n            paths.push(collection.path);\n            currentCollections = collection.subcollections;\n        }\n        return paths;\n    }, [getCollectionFromIds]);\n\n    return {\n        collections: collectionsRef.current,\n        views: viewsRef.current,\n        adminViews: adminViewsRef.current,\n        loading: !initialised || navigationLoading,\n        navigationLoadingError,\n        homeUrl,\n        basePath,\n        baseCollectionPath,\n        initialised,\n        getCollection,\n        getCollectionFromPaths,\n        getCollectionFromIds,\n        isUrlCollectionPath,\n        urlPathToDataPath,\n        buildUrlCollectionPath,\n        buildUrlEditCollectionPath,\n        buildCMSUrlPath,\n        resolveAliasesFrom,\n        topLevelNavigation,\n        refreshNavigation,\n        getParentReferencesFromPath: getAllParentReferencesForPath,\n        getParentCollectionIds,\n        convertIdsToPaths\n    };\n}\n\nexport function getSidePanelKey(path: string, entityId?: string) {\n    if (entityId)\n        return `${removeInitialAndTrailingSlashes(path)}/${removeInitialAndTrailingSlashes(entityId)}`;\n    else\n        return removeInitialAndTrailingSlashes(path);\n}\n\nfunction encodePath(input: string) {\n    return encodeURIComponent(removeInitialAndTrailingSlashes(input))\n        .replaceAll(\"%2F\", \"/\")\n        .replaceAll(\"%23\", \"#\");\n}\n\nfunction filterOutNotAllowedCollections(resolvedCollections: EntityCollection[], authController: AuthController<User>): EntityCollection[] {\n    return resolvedCollections\n        .filter((c) => {\n            if (!c.permissions) return true;\n            const resolvedPermissions = resolvePermissions(c, authController, c.path, null)\n            return resolvedPermissions?.read !== false;\n        })\n        .map((c) => {\n            if (!c.subcollections) return c;\n            return {\n                ...c,\n                subcollections: filterOutNotAllowedCollections(c.subcollections, authController)\n            }\n        });\n}\n\nasync function resolveCollections(collections: undefined | EntityCollection[] | EntityCollectionsBuilder<any>,\n                                  collectionPermissions: PermissionsBuilder | undefined,\n                                  authController: AuthController,\n                                  dataSource: DataSourceDelegate,\n                                  injectCollections?: (collections: EntityCollection[]) => EntityCollection[]): Promise<EntityCollection[]> {\n    let resolvedCollections: EntityCollection[] = [];\n    if (typeof collections === \"function\") {\n        resolvedCollections = await collections({\n            user: authController.user,\n            authController,\n            dataSource\n        });\n    } else if (Array.isArray(collections)) {\n        resolvedCollections = collections;\n    }\n\n    if (injectCollections) {\n        resolvedCollections = injectCollections(resolvedCollections ?? []);\n    }\n\n    resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);\n\n    resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);\n\n    return resolvedCollections;\n}\n\nasync function resolveCMSViews(baseViews: CMSView[] | CMSViewsBuilder | undefined, authController: AuthController, dataSource: DataSourceDelegate) {\n    let resolvedViews: CMSView[] = [];\n    if (typeof baseViews === \"function\") {\n        resolvedViews = await baseViews({\n            user: authController.user,\n            authController,\n            dataSource\n        });\n    } else if (Array.isArray(baseViews)) {\n        resolvedViews = baseViews;\n    }\n    return resolvedViews;\n}\n\nfunction getGroup(collectionOrView: EntityCollection<any, any> | CMSView) {\n    const trimmed = collectionOrView.group?.trim();\n    if (!trimmed || trimmed === \"\") {\n        return \"Views\";\n    }\n    return trimmed ?? \"Views\";\n}\n\nfunction areCollectionListsEqual(a: EntityCollection[], b: EntityCollection[]) {\n    if (a.length !== b.length) {\n        return false;\n    }\n    const aCopy = [...a];\n    const bCopy = [...b];\n    const aSorted = aCopy.sort((x, y) => x.id.localeCompare(y.id));\n    const bSorted = bCopy.sort((x, y) => x.id.localeCompare(y.id));\n    return aSorted.every((value, index) => areCollectionsEqual(value, bSorted[index]));\n}\n\nfunction areCollectionsEqual(a: EntityCollection, b: EntityCollection) {\n    const {\n        subcollections: subcollectionsA,\n        ...restA\n    } = a;\n    const {\n        subcollections: subcollectionsB,\n        ...restB\n    } = b;\n    if (!areCollectionListsEqual(subcollectionsA ?? [], subcollectionsB ?? [])) {\n        return false;\n    }\n    return equal(restA, restB);\n}\n","import React from \"react\";\n\n/**\n * @group Preview components\n */\nexport function EmptyValue() {\n\n    return <div\n        className=\"rounded-full bg-gray-200 bg-opacity-30 dark:bg-opacity-20 w-5 h-2 inline-block\"/>;\n}\n","import { CollectionSize } from \"../types\";\nimport { PreviewSize } from \"./PropertyPreviewProps\";\n\nexport const TINY_THUMBNAIL = 40;\nexport const SMALL_THUMBNAIL = 100;\nexport const REGULAR_THUMBNAIL = 200;\n\nexport function getThumbnailMeasure(size: PreviewSize): number {\n    if (size === \"tiny\")\n        return TINY_THUMBNAIL;\n    else if (size === \"small\")\n        return SMALL_THUMBNAIL;\n    else if (size === \"medium\")\n        return REGULAR_THUMBNAIL;\n    else throw Error(\"Thumbnail size not mapped\");\n}\n\nexport function getPreviewSizeFrom(size: CollectionSize): PreviewSize {\n    switch (size) {\n        case \"xs\":\n        case \"s\":\n            return \"tiny\";\n        case \"m\":\n            return \"small\";\n        case \"l\":\n        case \"xl\":\n            return \"medium\";\n        default:\n            throw Error(\"Missing mapping value in getPreviewSizeFrom: \" + size);\n    }\n}\n","import React, { CSSProperties, useMemo, useState } from \"react\";\n\nimport { getThumbnailMeasure } from \"../util\";\nimport { PreviewSize } from \"../PropertyPreviewProps\";\nimport { ContentCopyIcon, IconButton, OpenInNewIcon, Tooltip } from \"@firecms/ui\";\n\n/**\n * @group Preview components\n */\nexport interface ImagePreviewProps {\n    size: PreviewSize,\n    url: string\n}\n\n/**\n * @group Preview components\n */\nexport function ImagePreview({\n                                 size,\n                                 url\n                             }: ImagePreviewProps) {\n\n    const [onHover, setOnHover] = useState(false);\n\n    const imageSize = useMemo(() => getThumbnailMeasure(size), [size]);\n\n    if (size === \"tiny\") {\n        return (\n            <img src={url}\n                 className={\"rounded-md\"}\n                 key={\"tiny_image_preview_\" + url}\n                 style={{\n                     position: \"relative\",\n                     objectFit: \"cover\",\n                     width: imageSize,\n                     height: imageSize,\n                     maxHeight: \"100%\"\n                 }}/>\n        );\n    }\n\n    const imageStyle: CSSProperties =\n        {\n            maxWidth: \"100%\",\n            maxHeight: \"100%\"\n        };\n\n    return (\n        <div\n            className=\"relative flex items-center justify-center max-w-full max-h-full\"\n            style={{\n                width: imageSize,\n                height: imageSize\n            }}\n            key={\"image_preview_\" + url}\n            onMouseEnter={() => setOnHover(true)}\n            onMouseMove={() => setOnHover(true)}\n            onMouseLeave={() => setOnHover(false)}>\n\n            <img src={url}\n                 className={\"rounded-md\"}\n                 style={imageStyle}/>\n\n            {onHover && <>\n\n                {navigator && <Tooltip title=\"Copy url to clipboard\">\n                    <div\n                        className=\"rounded-full absolute bottom-[-4px] right-8\">\n                        <IconButton\n                            variant={\"filled\"}\n                            size={\"small\"}\n                            onClick={(e) => {\n                                e.stopPropagation();\n                                e.preventDefault();\n                                return navigator.clipboard.writeText(url);\n                            }}>\n                            <ContentCopyIcon className={\"text-gray-500\"}\n                                             size={\"small\"}/>\n                        </IconButton>\n                    </div>\n                </Tooltip>}\n\n                <Tooltip title=\"Open image in new tab\">\n                    <IconButton\n                        variant={\"filled\"}\n                        component={\"a\" as React.ElementType}\n                        style={{\n                            position: \"absolute\",\n                            bottom: -4,\n                            right: -4\n                        }}\n                        href={url}\n                        rel=\"noopener noreferrer\"\n                        target=\"_blank\"\n                        size={\"small\"}\n                        onClick={(e: any) => e.stopPropagation()}\n                    >\n                        <OpenInNewIcon className={\"text-gray-500\"}\n                                       size={\"small\"}/>\n                    </IconButton>\n                </Tooltip>\n            </>\n            }\n        </div>\n    );\n}\n","import React from \"react\";\n\nimport { ImagePreview } from \"./ImagePreview\";\nimport { getThumbnailMeasure } from \"../util\";\nimport { PreviewType } from \"../../types\";\nimport { PreviewSize } from \"../PropertyPreviewProps\";\nimport { DescriptionIcon, OpenInNewIcon, Tooltip, Typography } from \"@firecms/ui\";\nimport { EmptyValue } from \"./EmptyValue\";\n\n/**\n * @group Preview components\n */\nexport function UrlComponentPreview({\n                                        url,\n                                        previewType,\n                                        size,\n                                        hint\n                                    }: {\n    url: string,\n    previewType?: PreviewType,\n    size: PreviewSize,\n    hint?: string\n}): React.ReactElement {\n\n    if (!previewType) {\n        if (!url || !url.trim()) return <EmptyValue/>;\n        return (\n            <a className=\"flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary\"\n               href={url}\n               rel=\"noopener noreferrer\"\n               onMouseDown={(e: React.MouseEvent) => {\n                   e.preventDefault();\n               }}\n               target=\"_blank\">\n                <OpenInNewIcon size={\"small\"}/>\n                {url}\n            </a>\n        );\n    }\n\n    if (previewType === \"image\") {\n        return <ImagePreview url={url}\n                             size={size}/>;\n    } else if (previewType === \"audio\") {\n        return <audio controls\n                      src={url}>\n            Your browser does not support the\n            <code>audio</code> element.\n        </audio>;\n    } else if (previewType === \"video\") {\n        return <video\n            className={`max-w-${size === \"small\" ? \"sm\" : \"md\"}`}\n            controls\n        >\n            <source src={url}/>\n        </video>;\n    } else {\n        return (\n            <a\n                href={url}\n                rel=\"noopener noreferrer\"\n                target=\"_blank\"\n                onClick={(e) => e.stopPropagation()}\n                className=\"flex flex-col items-center justify-center\"\n                style={{\n                    width: getThumbnailMeasure(size),\n                    height: getThumbnailMeasure(size)\n                }}>\n                <DescriptionIcon className=\"flex-grow\"/>\n                {hint &&\n                    <Tooltip title={hint}>\n                        <Typography\n                            className=\"max-w-full truncate rtl text-left\"\n                            variant={\"caption\"}>{hint}</Typography>\n                    </Tooltip>}\n            </a>\n        );\n    }\n}\n","import {\n    ResolvedArrayProperty,\n    ResolvedMapProperty,\n    ResolvedProperties,\n    ResolvedProperty,\n    ResolvedStringProperty\n} from \"../../types\";\nimport React from \"react\";\nimport { getThumbnailMeasure } from \"../util\";\nimport { PreviewSize } from \"../PropertyPreviewProps\";\nimport { Skeleton } from \"@firecms/ui\";\n\nexport interface SkeletonPropertyComponentProps {\n    property: ResolvedProperty,\n    size: PreviewSize\n}\n\n/**\n * @group Preview components\n */\nexport function SkeletonPropertyComponent({\n                                              property,\n                                              size\n                                          }: SkeletonPropertyComponentProps\n) {\n\n    if (!property) {\n        console.error(\"No property assigned for skeleton component\", property, size);\n    }\n\n    let content: React.ReactNode | any;\n    if (property.dataType === \"string\") {\n        const stringProperty = property as ResolvedStringProperty;\n        if (stringProperty.url) {\n            content = renderUrlComponent(stringProperty, size);\n        } else if (stringProperty.storage) {\n            content = renderSkeletonImageThumbnail(size);\n        } else {\n            content = renderSkeletonText();\n        }\n    } else if (property.dataType === \"array\") {\n        const arrayProperty = property as ResolvedArrayProperty;\n\n        if (arrayProperty.of) {\n            if (Array.isArray(arrayProperty.of)) {\n                content = <>{arrayProperty.of.map((p, i) => renderGenericArrayCell(p, i))} </>;\n            } else {\n                if (arrayProperty.of.dataType === \"map\" && arrayProperty.of.properties) {\n                    content = renderArrayOfMaps(arrayProperty.of.properties, size, arrayProperty.of.previewProperties);\n                } else if (arrayProperty.of.dataType === \"string\") {\n                    if (arrayProperty.of.enumValues) {\n                        content = renderArrayEnumTableCell();\n                    } else if (arrayProperty.of.storage) {\n                        content = renderGenericArrayCell(arrayProperty.of);\n                    } else {\n                        content = renderArrayOfStrings();\n                    }\n                } else {\n                    content = renderGenericArrayCell(arrayProperty.of);\n                }\n            }\n        }\n\n    } else if (property.dataType === \"map\") {\n        content = renderMap(property as ResolvedMapProperty, size);\n    } else if (property.dataType === \"date\") {\n        content = renderSkeletonText();\n    } else if (property.dataType === \"reference\") {\n        content = renderReference();\n    } else if (property.dataType === \"boolean\") {\n        content = renderSkeletonText();\n    } else {\n        content = renderSkeletonText();\n    }\n    return (content || null);\n}\n\nfunction renderMap<T extends Record<string, any>>(property: ResolvedMapProperty<T>, size: PreviewSize) {\n\n    if (!property.properties)\n        return <></>;\n\n    let mapPropertyKeys: string[];\n    if (size === \"medium\") {\n        mapPropertyKeys = Object.keys(property.properties);\n    } else {\n        mapPropertyKeys = (property.previewProperties || Object.keys(property.properties)) as string[];\n        if (size === \"small\")\n            mapPropertyKeys = mapPropertyKeys.slice(0, 3);\n        else if (size === \"tiny\")\n            mapPropertyKeys = mapPropertyKeys.slice(0, 1);\n    }\n\n    if (size !== \"medium\")\n        return (\n            <div\n                className=\"w-full flex flex-col space-y-4\"\n            >\n                {mapPropertyKeys.map((key, index) => (\n                    <div key={`map_${key}`}>\n                        {property.properties && property.properties[key] &&\n                            <SkeletonPropertyComponent\n                                property={property.properties[key]}\n                                size={\"small\"}/>}\n                    </div>\n                ))}\n            </div>\n        );\n\n    return (\n        <table className=\"table-auto\">\n            <tbody>\n            {mapPropertyKeys &&\n                mapPropertyKeys.map((key, index) => {\n                    return (\n                        <tr\n                            key={`map_preview_table__${index}`}\n                            className=\"border-b last:border-b-0\">\n                            <th key={`table-cell-title--${key}`}\n                                className=\"align-top\"\n                                style={{ width: \"30%\" }}>\n                                <p className=\"text-xs text-secondary\">\n                                    {property.properties![key].name}\n                                </p>\n                            </th>\n                            <th key={`table-cell-${key}`}\n                                style={{ width: \"70%\" }}>\n                                {property.properties && property.properties[key] &&\n                                    <SkeletonPropertyComponent\n                                        property={property.properties[key]}\n                                        size={\"small\"}/>}\n                            </th>\n                        </tr>\n                    );\n                })}\n            </tbody>\n        </table>\n    );\n}\n\nfunction renderArrayOfMaps<M extends Record<string, any>>(properties: ResolvedProperties<M>, size: PreviewSize, previewProperties?: string[]) {\n    let tableProperties = previewProperties;\n    if (!tableProperties || !tableProperties.length) {\n        tableProperties = Object.keys(properties) as string[];\n        if (size)\n            tableProperties = tableProperties.slice(0, 3);\n    }\n\n    return (\n        <table className=\"table-auto\">\n            <tbody>\n            {\n                [0, 1, 2].map((value, index) => {\n                    return (\n                        <tr key={`table_${value}_${index}`}>\n                            {tableProperties && tableProperties.map(\n                                (key) => (\n                                    <th\n                                        key={`table-cell-${key}`}\n                                    >\n                                        <SkeletonPropertyComponent\n                                            property={(properties)[key]}\n                                            size={\"small\"}/>\n                                    </th>\n                                )\n                            )}\n                        </tr>\n                    );\n                })}\n            </tbody>\n        </table>\n    );\n}\n\nfunction renderArrayOfStrings() {\n    return (\n        <div className={\"flex flex-col gap-2\"}>\n            {\n                [0, 1].map((value, index) => (\n                    renderSkeletonText(index)\n                ))}\n        </div>\n    );\n}\n\nfunction renderArrayEnumTableCell() {\n    return (\n        <div className={\"flex flex-col gap-2\"}>\n            {\n                [0, 1].map((value, index) =>\n                    <>\n                        {renderSkeletonText(index)}\n                    </>\n                )}\n        </div>\n    );\n}\n\nfunction renderGenericArrayCell(\n    property: ResolvedProperty,\n    index = 0\n) {\n    return (\n\n        <div key={\"array_index_\" + index}\n             className={\"flex flex-col gap-2\"}>\n\n            {\n                [0, 1].map((value, index) =>\n                    <>\n                        <SkeletonPropertyComponent key={`i_${index}`}\n                                                   property={property}\n                                                   size={\"small\"}/>\n                    </>\n                )}\n        </div>\n    );\n}\n\nfunction renderUrlAudioComponent() {\n    return (\n        <Skeleton width={300}\n                  height={100}/>\n    );\n}\n\nexport function renderSkeletonImageThumbnail(size: PreviewSize) {\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    const imageSize = size === \"tiny\" ? 40 : size === \"small\" ? 100 : 200;\n    return (\n        <Skeleton width={imageSize}\n                  height={imageSize}/>\n    );\n}\n\nfunction renderUrlVideo(size: PreviewSize) {\n\n    return (\n        <Skeleton width={size !== \"medium\" ? 300 : 500}\n                  height={size !== \"medium\" ? 200 : 250}/>\n    );\n}\n\nfunction renderReference() {\n    return <Skeleton width={200} height={100}/>;\n}\n\nfunction renderUrlComponent(property: ResolvedStringProperty, size: PreviewSize = \"medium\") {\n\n    if (typeof property.url === \"boolean\") {\n        return <div style={{\n            display: \"flex\"\n        }}>\n            {renderSkeletonIcon()}\n            {renderSkeletonText()}\n        </div>;\n    }\n\n    return renderUrlFile(size);\n}\n\nfunction renderUrlFile(size: PreviewSize) {\n\n    return (\n        <div\n            className={`w-${getThumbnailMeasure(size)} h-${getThumbnailMeasure(size)}`}>\n            {renderSkeletonIcon()}\n        </div>\n    );\n}\n\nexport function renderSkeletonText(index?: number, width = 120) {\n    return <Skeleton width={width} key={`skeleton_${index}`}/>;\n}\n\nexport function renderSkeletonCaptionText(index?: number) {\n    return <Skeleton\n        height={20}/>;\n}\n\nexport function renderSkeletonIcon() {\n    return <Skeleton width={24} height={24}/>;\n}\n","import React, { useEffect } from \"react\";\n\nimport { renderSkeletonImageThumbnail } from \"../property_previews/SkeletonPropertyComponent\";\nimport { UrlComponentPreview } from \"./UrlComponentPreview\";\nimport { useStorageSource } from \"../../hooks\";\nimport { DownloadConfig, FileType } from \"../../types\";\nimport { PreviewSize } from \"../PropertyPreviewProps\";\nimport { ErrorView } from \"../../components\";\n\ntype StorageThumbnailProps = {\n    storagePathOrDownloadUrl: string;\n    storeUrl: boolean;\n    size: PreviewSize;\n};\n\n/**\n * @group Preview components\n */\nexport const StorageThumbnail = React.memo<StorageThumbnailProps>(StorageThumbnailInternal, areEqual) as React.FunctionComponent<StorageThumbnailProps>;\n\nfunction areEqual(prevProps: StorageThumbnailProps, nextProps: StorageThumbnailProps) {\n    return prevProps.size === nextProps.size &&\n        prevProps.storagePathOrDownloadUrl === nextProps.storagePathOrDownloadUrl &&\n        prevProps.storeUrl === nextProps.storeUrl;\n}\n\nconst URL_CACHE: Record<string, DownloadConfig> = {};\n\nexport function StorageThumbnailInternal({\n                                             storeUrl,\n                                             storagePathOrDownloadUrl,\n                                             size\n                                         }: StorageThumbnailProps) {\n\n    const [error, setError] = React.useState<Error | undefined>(undefined);\n    const storage = useStorageSource();\n\n    const [downloadConfig, setDownloadConfig] = React.useState<DownloadConfig>(URL_CACHE[storagePathOrDownloadUrl]);\n\n    useEffect(() => {\n        if (!storagePathOrDownloadUrl)\n            return;\n        let unmounted = false;\n        storage.getDownloadURL(storagePathOrDownloadUrl)\n            .then(function (downloadConfig) {\n                if (!unmounted) {\n                    setDownloadConfig(downloadConfig);\n                    URL_CACHE[storagePathOrDownloadUrl] = downloadConfig;\n                }\n            }).catch(setError);\n        return () => {\n            unmounted = true;\n        };\n    }, [storagePathOrDownloadUrl]);\n\n    if (!storagePathOrDownloadUrl) return null;\n\n    const filetype = downloadConfig?.metadata ? getFiletype(downloadConfig?.metadata.contentType) : undefined;\n    const previewType = filetype?.startsWith(\"image\")\n        ? \"image\"\n        : (filetype?.startsWith(\"video\")\n            ? \"video\"\n            : (filetype?.startsWith(\"audio\") ? \"audio\" : \"file\"));\n\n    if (downloadConfig?.fileNotFound)\n        return <ErrorView error={\"File not found\"}></ErrorView>\n\n    return downloadConfig?.url\n        ? <UrlComponentPreview previewType={previewType}\n                               url={downloadConfig.url}\n                               size={size}\n                               hint={storagePathOrDownloadUrl}/>\n        : renderSkeletonImageThumbnail(size);\n}\n\nfunction getFiletype(input: string): FileType {\n    if (input.startsWith(\"image\")) return \"image/*\";\n    else if (input.startsWith(\"video\")) return \"video/*\";\n    else if (input.startsWith(\"audio\")) return \"audio/*\";\n    else if (input.startsWith(\"application\")) return \"application/*\";\n    else if (input.startsWith(\"text\")) return \"text/*\";\n    else if (input.startsWith(\"font\")) return \"font/*\";\n    else return input;\n}\n","import React from \"react\";\nimport { Chip } from \"@firecms/ui\";\nimport { EnumValues } from \"../../types\";\nimport { buildEnumLabel, enumToObjectEntries, getColorScheme, getLabelOrConfigFrom } from \"../../util/enums\";\n\nexport interface EnumValuesChipProps {\n    enumValues?: EnumValues;\n    enumKey: string | number;\n    size: \"tiny\" | \"small\" | \"medium\";\n    className?: string;\n    children?: React.ReactNode;\n}\n\n/**\n * @group Preview components\n */\nexport function EnumValuesChip({\n                                   enumValues,\n                                   enumKey,\n                                   size,\n                                   className,\n                                   children\n                               }: EnumValuesChipProps) {\n    if (!enumValues) return null;\n    const enumValuesConfig = enumToObjectEntries(enumValues);\n    const enumValue = enumKey !== undefined ? getLabelOrConfigFrom(enumValuesConfig, enumKey) : undefined;\n    const label = buildEnumLabel(enumValue);\n    const colorScheme = getColorScheme(enumValuesConfig, enumKey);\n    return <Chip\n        className={className}\n        colorScheme={colorScheme}\n        error={!label}\n        outlined={false}\n        size={size}>\n        {children}\n        {!children && (label !== undefined ? label : String(enumKey))}\n    </Chip>;\n}\n","import React from \"react\";\n\nimport { resolvePropertyEnum } from \"../../util\";\nimport { EnumValuesChip } from \"../components/EnumValuesChip\";\nimport { PreviewType } from \"../../types\";\nimport { UrlComponentPreview } from \"../components/UrlComponentPreview\";\nimport { PropertyPreviewProps } from \"../PropertyPreviewProps\";\nimport { ErrorBoundary } from \"../../components\";\nimport { Chip, cn, getColorSchemeForSeed } from \"@firecms/ui\";\n\n/**\n * @group Preview components\n */\nexport function StringPropertyPreview({\n                                          propertyKey,\n                                          value,\n                                          property,\n                                          size\n                                      }: PropertyPreviewProps<string>): React.ReactElement {\n\n    if (property.enumValues) {\n        const enumKey = value;\n        const resolvedProperty = resolvePropertyEnum(property);\n        return <EnumValuesChip\n            enumKey={enumKey}\n            enumValues={resolvedProperty.enumValues}\n            size={size}/>;\n    } else if (property.previewAsTag) {\n        const colorScheme = getColorSchemeForSeed(propertyKey ?? \"\");\n        return (\n            <ErrorBoundary>\n                <Chip\n                    colorScheme={colorScheme}\n                    size={size}>\n                    {value}\n                </Chip>\n            </ErrorBoundary>);\n    } else if (property.url) {\n        return (\n            <UrlComponentPreview size={size}\n                                 url={value}\n                                 previewType={typeof property.url === \"string\" ? property.url as PreviewType : undefined}/>\n        );\n    } else {\n        if (!value) return <></>;\n        const lines = value.split(\"\\n\");\n        return value && value.includes(\"\\n\")\n            ? <div className={cn(\"overflow-x-scroll\", size === \"tiny\" ? \"text-sm\" : \"\")}>\n                {lines.map((str, index) =>\n                    <React.Fragment key={`string_preview_${index}`}>\n                        <span>{str}</span>\n                        {index !== lines.length - 1 && <br/>}\n                    </React.Fragment>)}\n            </div>\n            : (size === \"tiny\"\n                    ? <span className={\"text-sm\"}>{value}</span>\n                    : <>{value}</>\n            );\n    }\n}\n","import React from \"react\";\n\nimport { resolveArrayProperty } from \"../../util\";\nimport { ResolvedProperty } from \"../../types\";\nimport { useCustomizationController } from \"../../hooks\";\nimport { PreviewSize, PropertyPreviewProps } from \"../PropertyPreviewProps\";\nimport { PropertyPreview } from \"../PropertyPreview\";\nimport { cn, defaultBorderMixin } from \"@firecms/ui\";\nimport { ErrorBoundary } from \"../../components\";\n\n/**\n * @group Preview components\n */\nexport function ArrayPropertyPreview({\n                                         propertyKey,\n                                         value,\n                                         property: inputProperty,\n                                         // entity,\n                                         size\n                                     }: PropertyPreviewProps<any[]>) {\n\n    const customizationController = useCustomizationController();\n    const property = resolveArrayProperty({\n        propertyKey,\n        property: inputProperty,\n        fields: customizationController.propertyConfigs\n    });\n\n    if (!property.of) {\n        throw Error(`You need to specify an 'of' prop (or specify a custom field) in your array property ${propertyKey}`);\n    }\n\n    if (property.dataType !== \"array\")\n        throw Error(\"Picked wrong preview component ArrayPreview\");\n\n    const values = value;\n\n    if (!values) return null;\n\n    const childSize: PreviewSize = size === \"medium\" ? \"small\" : \"tiny\";\n\n    return (\n        <div className=\"flex flex-col gap-2\">\n            {values &&\n                values.map((value, index) => {\n                        const of: ResolvedProperty = property.resolvedProperties[index] ??\n                            (property.resolvedProperties[index] ?? (Array.isArray(property.of) ? property.of[index] : property.of));\n                        return of\n                            ? <React.Fragment\n                                key={\"preview_array_\" + index}>\n                                <div className={cn(defaultBorderMixin, \"m-1 border-b last:border-b-0\")}>\n                                    <ErrorBoundary>\n                                        <PropertyPreview\n                                            propertyKey={propertyKey}\n                                            // entity={entity}\n                                            value={value}\n                                            property={of}\n                                            size={childSize}/>\n                                    </ErrorBoundary>\n                                </div>\n                            </React.Fragment>\n                            : null;\n                    }\n                )}\n        </div>\n    );\n}\n","import * as React from \"react\";\nimport { useMemo } from \"react\";\n\nimport { Entity, EntityCollection, ResolvedProperty } from \"../types\";\n\nimport {\n    getEntityImagePreviewPropertyKey,\n    getEntityPreviewKeys,\n    getEntityTitlePropertyKey,\n    getValueInPath,\n    resolveCollection\n} from \"../util\";\nimport { cn, defaultBorderMixin, IconButton, KeyboardTabIcon, Skeleton, Tooltip, Typography } from \"@firecms/ui\";\nimport { PreviewSize, PropertyPreview, SkeletonPropertyComponent } from \"../preview\";\nimport { useCustomizationController, useNavigationController, useSideEntityController } from \"../hooks\";\nimport { useAnalyticsController } from \"../hooks/useAnalyticsController\";\n\nexport type EntityPreviewProps = {\n    size: PreviewSize,\n    actions?: React.ReactNode,\n    collection?: EntityCollection,\n    hover?: boolean;\n    previewProperties?: string[],\n    disabled: undefined | boolean,\n    entity: Entity<any>,\n    includeEntityNavigation?: boolean,\n    onClick?: (e: React.SyntheticEvent) => void;\n};\n\n/**\n * This view is used to display a preview of an entity.\n * It is used by default in reference fields and whenever a reference is displayed.\n */\nexport function EntityPreview({\n                                  actions,\n                                  disabled,\n                                  hover,\n                                  collection: collectionProp,\n                                  previewProperties,\n                                  onClick,\n                                  size,\n                                  includeEntityNavigation,\n                                  entity\n                              }: EntityPreviewProps) {\n\n    const analyticsController = useAnalyticsController();\n    const sideEntityController = useSideEntityController();\n    const customizationController = useCustomizationController();\n\n    const navigationController = useNavigationController();\n\n    const collection = collectionProp ?? navigationController.getCollection(entity.path);\n\n    if (!collection) {\n        throw Error(`Couldn't find the corresponding collection view for the path: ${entity.path}`);\n    }\n\n    const resolvedCollection = React.useMemo(() => resolveCollection({\n        collection,\n        path: entity.path,\n        values: entity.values,\n        fields: customizationController.propertyConfigs\n    }), [collection]);\n\n    const listProperties = useMemo(() => getEntityPreviewKeys(resolvedCollection, customizationController.propertyConfigs, previewProperties, size === \"small\" || size === \"medium\" ? 3 : 1),\n        [previewProperties, resolvedCollection, size]);\n\n    const titleProperty = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);\n    const imagePropertyKey = getEntityImagePreviewPropertyKey(resolvedCollection);\n    const imageProperty = imagePropertyKey ? resolvedCollection.properties[imagePropertyKey] : undefined;\n\n    const restProperties = listProperties.filter(p => p !== titleProperty && p !== imagePropertyKey);\n\n    return <EntityPreviewContainer onClick={disabled ? undefined : onClick}\n                                   hover={disabled ? undefined : hover}\n                                   size={size}>\n        {imageProperty && (\n            <div className={cn(\"w-10 h-10 mr-2 shrink-0 grow-0\", size === \"tiny\" ? \"my-0.5\" : \"m-2 self-start\")}>\n                <PropertyPreview property={imageProperty}\n                                 propertyKey={imagePropertyKey as string}\n                                 size={\"tiny\"}\n                                 value={getValueInPath(entity.values, imagePropertyKey as string)}/>\n            </div>\n        )}\n\n        <div className={\"flex flex-col flex-grow w-full m-1\"}>\n\n            {size !== \"tiny\" && (\n                entity\n                    ? <div className={`${\n                        size !== \"medium\"\n                            ? \"block whitespace-nowrap overflow-hidden truncate\"\n                            : \"\"\n                    }`}>\n                        <Typography variant={\"caption\"}\n                                    color={\"disabled\"}\n                                    className={\"font-mono\"}>\n                            {entity.id}\n                        </Typography>\n                    </div>\n                    : <Skeleton/>)}\n\n            {titleProperty && (\n                <div className={\"my-0.5 text-sm font-medium\"}>\n                    {\n                        entity\n                            ? <PropertyPreview\n                                propertyKey={titleProperty as string}\n                                value={getValueInPath(entity.values, titleProperty)}\n                                property={resolvedCollection.properties[titleProperty as string] as ResolvedProperty}\n                                size={\"medium\"}/>\n                            : <SkeletonPropertyComponent\n                                property={resolvedCollection.properties[titleProperty as string] as ResolvedProperty}\n                                size={\"medium\"}/>\n                    }\n                </div>\n            )}\n\n            {restProperties && restProperties.map((key) => {\n                const childProperty = resolvedCollection.properties[key as string];\n                if (!childProperty) return null;\n\n                return (\n                    <div key={\"ref_prev_\" + key}\n                         className={restProperties.length > 1 ? \"my-0.5\" : \"my-0\"}>\n                        {\n                            entity\n                                ? <PropertyPreview\n                                    propertyKey={key as string}\n                                    value={getValueInPath(entity.values, key)}\n                                    property={childProperty as ResolvedProperty}\n                                    size={\"tiny\"}/>\n                                : <SkeletonPropertyComponent\n                                    property={childProperty as ResolvedProperty}\n                                    size={\"tiny\"}/>\n                        }\n                    </div>\n                );\n            })}\n\n        </div>\n\n        {entity && includeEntityNavigation &&\n            <Tooltip title={`See details for ${entity.id}`}\n                     className={size !== \"tiny\" ? \"self-start\" : \"\"}>\n                <IconButton\n                    color={\"inherit\"}\n                    size={\"small\"}\n                    onClick={(e) => {\n                        e.stopPropagation();\n                        analyticsController.onAnalyticsEvent?.(\"entity_click_from_reference\", {\n                            path: entity.path,\n                            entityId: entity.id\n                        });\n                        sideEntityController.open({\n                            entityId: entity.id,\n                            path: entity.path,\n                            collection,\n                            updateUrl: true\n                        });\n                    }}>\n                    <KeyboardTabIcon size={\"small\"}/>\n                </IconButton>\n            </Tooltip>}\n\n        {actions}\n\n    </EntityPreviewContainer>;\n}\n\nexport type EntityPreviewContainerProps = {\n    children: React.ReactNode;\n    hover?: boolean;\n    fullwidth?: boolean;\n    size: PreviewSize;\n    className?: string;\n    style?: React.CSSProperties;\n    onClick?: (e: React.SyntheticEvent) => void;\n};\n\nconst EntityPreviewContainerInner = React.forwardRef<HTMLDivElement, EntityPreviewContainerProps>(({\n                                                                                                       children,\n                                                                                                       hover,\n                                                                                                       onClick,\n                                                                                                       size,\n                                                                                                       style,\n                                                                                                       className,\n                                                                                                       fullwidth = true,\n                                                                                                       ...props\n                                                                                                   }, ref) => {\n    return <div\n        ref={ref}\n        style={{\n            ...style,\n            // @ts-ignore\n            tabindex: 0\n        }}\n        className={cn(\n            \"bg-white dark:bg-gray-900\",\n            fullwidth ? \"w-full\" : \"\",\n            \"items-center\",\n            hover ? \"hover:bg-slate-50 dark:hover:bg-gray-800 group-hover:bg-slate-50 dark:group-hover:bg-gray-800\" : \"\",\n            size === \"tiny\" ? \"p-1\" : \"p-2\",\n            \"flex border rounded-lg\",\n            onClick ? \"cursor-pointer\" : \"\",\n            defaultBorderMixin,\n            className)}\n        onClick={(event) => {\n            if (onClick) {\n                event.preventDefault();\n                onClick(event);\n            }\n        }}\n        {...props}>\n        {children}\n    </div>;\n});\n\nEntityPreviewContainerInner.displayName = \"EntityPreviewContainer\";\n\nexport const EntityPreviewContainer = React.memo(EntityPreviewContainerInner) as React.FC<EntityPreviewContainerProps>;\n","import * as React from \"react\";\n\nimport { Entity, EntityCollection, EntityReference } from \"../../types\";\nimport {\n    useCustomizationController,\n    useEntityFetch,\n    useNavigationController,\n    useSideEntityController\n} from \"../../hooks\";\nimport { PreviewSize } from \"../PropertyPreviewProps\";\nimport { IconButton, KeyboardTabIcon, Skeleton, Tooltip } from \"@firecms/ui\";\nimport { ErrorView } from \"../../components\";\nimport { useAnalyticsController } from \"../../hooks/useAnalyticsController\";\nimport { EntityPreview, EntityPreviewContainer } from \"../../components/EntityPreview\";\n\nexport type ReferencePreviewProps = {\n    disabled?: boolean;\n    reference: EntityReference,\n    size: PreviewSize;\n    previewProperties?: string[];\n    onClick?: (e: React.SyntheticEvent) => void;\n    hover?: boolean;\n    allowEntityNavigation?: boolean;\n};\n\n/**\n * @group Preview components\n */\nexport const ReferencePreview = React.memo<ReferencePreviewProps>(function ReferencePreview(props: ReferencePreviewProps) {\n    const reference = props.reference;\n    if (!(typeof reference === \"object\" && \"isEntityReference\" in reference && reference.isEntityReference())) {\n        console.warn(\"Reference preview received value of type\", typeof reference);\n        return <EntityPreviewContainer\n            onClick={props.onClick}\n            size={props.size}>\n            <ErrorView error={\"Unexpected value. Click to edit\"}\n                       tooltip={JSON.stringify(reference)}/>\n        </EntityPreviewContainer>;\n    }\n    return <ReferencePreviewInternal {...props} />;\n}, areEqual) as React.FunctionComponent<ReferencePreviewProps>;\n\nfunction areEqual(prevProps: ReferencePreviewProps, nextProps: ReferencePreviewProps) {\n    return prevProps.disabled === nextProps.disabled &&\n        prevProps.size === nextProps.size &&\n        prevProps.hover === nextProps.hover &&\n        prevProps.reference?.id === nextProps.reference?.id &&\n        prevProps.reference?.path === nextProps.reference?.path &&\n        prevProps.allowEntityNavigation === nextProps.allowEntityNavigation\n        ;\n}\n\nfunction ReferencePreviewInternal<M extends Record<string, any>>({\n                                                                     disabled,\n                                                                     reference,\n                                                                     previewProperties,\n                                                                     size,\n                                                                     hover,\n                                                                     onClick,\n                                                                     allowEntityNavigation = true\n                                                                 }: ReferencePreviewProps) {\n\n    const customizationController = useCustomizationController();\n\n    const navigationController = useNavigationController();\n\n    const collection = navigationController.getCollection(reference.path);\n    if (!collection) {\n        if (customizationController.components?.missingReference) {\n            return <customizationController.components.missingReference path={reference.path}/>;\n        } else {\n            throw Error(`Couldn't find the corresponding collection view for the path: ${reference.path}`);\n        }\n    }\n\n    return <ReferencePreviewExisting\n        reference={reference}\n        collection={collection}\n        previewProperties={previewProperties}\n        size={size}\n        disabled={disabled}\n        allowEntityNavigation={allowEntityNavigation}\n        onClick={onClick}\n        hover={hover}/>\n}\n\nfunction ReferencePreviewExisting<M extends Record<string, any> = any>({\n                                                                           reference,\n                                                                           collection,\n                                                                           previewProperties,\n                                                                           size,\n                                                                           disabled,\n                                                                           allowEntityNavigation,\n                                                                           onClick,\n                                                                           hover\n                                                                       }: ReferencePreviewProps & {\n    collection: EntityCollection<M>\n}) {\n\n    const {\n        entity,\n        dataLoading,\n        dataLoadingError\n    } = useEntityFetch({\n        path: reference.path,\n        entityId: reference.id,\n        collection,\n        useCache: true\n    });\n\n    if (entity) {\n        referencesCache.set(reference.pathWithId, entity);\n    }\n\n    const usedEntity = entity ?? referencesCache.get(reference.pathWithId);\n\n    let body: React.ReactNode;\n\n    if (!reference) {\n        body = <ErrorView error={\"Reference not set\"}/>;\n    } else if (usedEntity && !usedEntity.values) {\n        body = <ErrorView error={\"Reference does not exist\"}\n                          tooltip={reference.path}/>;\n    }\n    if (body) {\n\n        return (\n            <EntityPreviewContainer onClick={disabled ? undefined : onClick}\n                                    hover={disabled ? undefined : hover}\n                                    size={size}>\n                {body}\n            </EntityPreviewContainer>\n        );\n    }\n\n    if (dataLoading && !usedEntity) {\n        return (\n            <EntityPreviewContainer onClick={disabled ? undefined : onClick}\n                                    hover={disabled ? undefined : hover}\n                                    size={size}>\n                <Skeleton/>\n            </EntityPreviewContainer>\n        );\n    }\n\n    if (!usedEntity) {\n        return (\n            <EntityPreviewContainer onClick={disabled ? undefined : onClick}\n                                    hover={disabled ? undefined : hover}\n                                    size={size}>\n                <ErrorView error={\"Entity not found\"}/>\n            </EntityPreviewContainer>\n        );\n    }\n    return <EntityPreview size={size}\n                          previewProperties={previewProperties}\n                          disabled={disabled}\n                          entity={usedEntity}\n                          collection={collection}\n                          onClick={onClick}\n                          includeEntityNavigation={allowEntityNavigation}\n                          hover={hover}/>;\n\n}\n\nconst referencesCache = new Map<string, Entity<any>>();\n","import { ResolvedReferenceProperty } from \"../../types\";\nimport { resolveArrayProperty } from \"../../util\";\nimport { useCustomizationController } from \"../../hooks\";\nimport { PreviewSize, PropertyPreviewProps } from \"../PropertyPreviewProps\";\nimport { ReferencePreview } from \"../components/ReferencePreview\";\n\n/**\n * @group Preview components\n */\nexport function ArrayOfReferencesPreview({\n                                             propertyKey,\n                                             value,\n                                             property: inputProperty,\n                                             size\n                                         }: PropertyPreviewProps<any[]>) {\n\n    const customizationController = useCustomizationController();\n    const property = resolveArrayProperty({\n        propertyKey,\n        property: inputProperty,\n        fields: customizationController.propertyConfigs\n    });\n\n    if (Array.isArray(property?.of)) {\n        throw Error(\"Using array properties instead of single one in `of` in ArrayProperty\");\n    }\n\n    if (property?.dataType !== \"array\" || !property.of || property.of.dataType !== \"reference\")\n        throw Error(\"Picked wrong preview component ArrayOfReferencesPreview\");\n\n    const childSize: PreviewSize = size === \"medium\" ? \"small\" : \"tiny\";\n\n    return (\n        <div className=\"flex flex-col w-full\">\n            {value &&\n                value.map((reference, index) => {\n                        const ofProperty = property.of as ResolvedReferenceProperty;\n                        return <div className=\"mt-1 mb-1 w-full\"\n                                    key={`preview_array_ref_${propertyKey}_${index}`}>\n                            <ReferencePreview\n                                disabled={!ofProperty.path}\n                                previewProperties={ofProperty.previewProperties}\n                                size={childSize}\n                                reference={reference}\n                            />\n                        </div>;\n                    }\n                )}\n        </div>\n    );\n}\n","import React from \"react\";\n\nimport { resolveArrayProperty } from \"../../util\";\nimport { ResolvedProperty } from \"../../types\";\n\nimport { useCustomizationController } from \"../../hooks\";\nimport { PreviewSize, PropertyPreviewProps } from \"../PropertyPreviewProps\";\nimport { PropertyPreview } from \"../PropertyPreview\";\nimport { ErrorBoundary } from \"../../components\";\n\n/**\n * @group Preview components\n */\nexport function ArrayOfStorageComponentsPreview({\n                                                    propertyKey,\n                                                    // entity,\n                                                    value,\n                                                    property: inputProperty,\n                                                    size\n                                                }: PropertyPreviewProps<any[]>) {\n\n    const customizationController = useCustomizationController();\n    const property = resolveArrayProperty({\n        propertyKey,\n        property: inputProperty,\n        fields: customizationController.propertyConfigs\n    });\n\n    if (Array.isArray(property.of)) {\n        throw Error(\"Using array properties instead of single one in `of` in ArrayProperty\");\n    }\n\n    if (property.dataType !== \"array\" || !property.of || property.of.dataType !== \"string\")\n        throw Error(\"Picked wrong preview component ArrayOfStorageComponentsPreview\");\n\n    const childSize: PreviewSize = size === \"medium\" ? \"small\" : \"tiny\";\n\n    return (\n        <div className={\"flex flex-wrap gap-2\"}>\n            {value &&\n                value.map((v, index) =>\n                    <ErrorBoundary key={`preview_array_storage_${propertyKey}_${index}`}>\n                        <PropertyPreview\n                            propertyKey={propertyKey}\n                            value={v}\n                            // entity={entity}\n                            property={property.of as ResolvedProperty<string>}\n                            size={childSize}/>\n                    </ErrorBoundary>\n                )}\n        </div>\n    );\n}\n","import React from \"react\";\n\nimport { EnumValueConfig } from \"../../types\";\nimport { EnumValuesChip } from \"./EnumValuesChip\";\nimport { PreviewSize } from \"../PropertyPreviewProps\";\nimport { ErrorBoundary } from \"../../components\";\n\n/**\n * @group Preview components\n */\nexport function ArrayEnumPreview({\n                                     name,\n                                     value,\n                                     enumValues,\n                                     size\n                                 }: {\n    value: string[] | number[],\n    name: string | undefined,\n    enumValues: EnumValueConfig[],\n    size: PreviewSize\n}) {\n\n    return (\n        <div className=\"flex flex-wrap gap-1.5\">\n            {value && value.map((enumKey, index) => {\n                    return (\n                        <ErrorBoundary\n                            key={`preview_array_ref_${name}_${index}`}>\n                            <EnumValuesChip\n                                enumKey={enumKey}\n                                enumValues={enumValues}\n                                size={size !== \"medium\" ? \"small\" : \"medium\"}/>\n                        </ErrorBoundary>\n                    );\n                }\n            )}\n        </div>\n    );\n}\n","import { ResolvedNumberProperty, ResolvedStringProperty } from \"../../types\";\nimport { ArrayEnumPreview } from \"../components/ArrayEnumPreview\";\nimport { PropertyPreviewProps } from \"../PropertyPreviewProps\";\n\n/**\n * @group Preview components\n */\nexport function ArrayPropertyEnumPreview({\n                                             propertyKey,\n                                             value,\n                                             property,\n                                             size\n                                         }: PropertyPreviewProps<string[] | number[]>) {\n\n    if (property.dataType !== \"array\")\n        throw Error(\"Picked wrong preview component ArrayEnumPreview\");\n\n    const ofProperty = property.of as ResolvedStringProperty | ResolvedNumberProperty;\n    if (!ofProperty.enumValues)\n        throw Error(\"Picked wrong preview component ArrayEnumPreview\");\n\n    if (!value) return null;\n\n    return <ArrayEnumPreview name={propertyKey}\n                             value={value}\n                             enumValues={ofProperty.enumValues}\n                             size={size}/>;\n}\n","import React from \"react\";\nimport { ResolvedStringProperty } from \"../../types\";\n\nimport { resolveArrayProperty } from \"../../util\";\nimport { PropertyPreviewProps, StringPropertyPreview } from \"../../preview\";\nimport { useCustomizationController } from \"../../hooks\";\nimport { ErrorBoundary } from \"../../components\";\n\n/**\n * @group Preview components\n */\nexport function ArrayOfStringsPreview({\n                                          propertyKey,\n                                          value,\n                                          property: inputProperty,\n                                          // entity,\n                                          size\n                                      }: PropertyPreviewProps<string[]>) {\n\n    const customizationController = useCustomizationController();\n    const property = resolveArrayProperty({\n        propertyKey,\n        property: inputProperty,\n        fields: customizationController.propertyConfigs\n    });\n\n    if (Array.isArray(property.of)) {\n        throw Error(\"Using array properties instead of single one in `of` in ArrayProperty\");\n    }\n    if (!property.of || property.dataType !== \"array\" || property.of.dataType !== \"string\")\n        throw Error(\"Picked wrong preview component ArrayOfStringsPreview\");\n\n    if (value && !Array.isArray(value)) {\n        return <div>{`Unexpected value: ${value}`}</div>;\n    }\n    const stringProperty = property.of as ResolvedStringProperty;\n\n    return (\n        <div className=\"flex flex-col gap-2\">\n            {value &&\n                value.map((v, index) =>\n                    <div key={`preview_array_strings_${propertyKey}_${index}`}>\n                        <ErrorBoundary>\n                            <StringPropertyPreview propertyKey={propertyKey}\n                                                   property={stringProperty}\n                                                   value={v}\n                                // entity={entity}\n                                                   size={size}/>\n                        </ErrorBoundary>\n                    </div>\n                )}\n        </div>\n    );\n}\n","import React from \"react\";\nimport { resolveArrayProperty } from \"../../util\";\nimport { ResolvedProperty } from \"../../types\";\nimport { useCustomizationController } from \"../../hooks\";\nimport { PreviewSize, PropertyPreviewProps } from \"../PropertyPreviewProps\";\nimport { PropertyPreview } from \"../PropertyPreview\";\nimport { cn, defaultBorderMixin } from \"@firecms/ui\";\nimport { DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE } from \"../../util/common\";\nimport { ErrorBoundary } from \"../../components\";\n\n/**\n * @group Preview components\n */\nexport function ArrayOneOfPreview({\n                                      propertyKey,\n                                      value,\n                                      property: inputProperty,\n                                      size,\n                                      // entity\n                                  }: PropertyPreviewProps<any[]>) {\n\n    const customizationController = useCustomizationController();\n    const property = resolveArrayProperty({\n        propertyKey,\n        property: inputProperty,\n        fields: customizationController.propertyConfigs\n    });\n\n    if (property?.dataType !== \"array\")\n        throw Error(\"Picked wrong preview component ArrayPreview\");\n\n    if (!property?.oneOf) {\n        throw Error(`You need to specify an 'of' or 'oneOf' prop (or specify a custom field) in your array property ${propertyKey}`);\n    }\n\n    const values = value;\n\n    if (!values) return null;\n\n    const childSize: PreviewSize = size === \"medium\" ? \"small\" : \"tiny\";\n\n    const typeField = property.oneOf.typeField ?? DEFAULT_ONE_OF_TYPE;\n    const valueField = property.oneOf.valueField ?? DEFAULT_ONE_OF_VALUE;\n    const properties = property.oneOf.properties;\n\n    return (\n        <div className={\"flex flex-col\"}>\n            {values &&\n                values.map((value, index) =>\n                    <React.Fragment\n                        key={\"preview_array_\" + value + \"_\" + index}>\n                        <div className={cn(defaultBorderMixin, \"m-1 border-b last:border-b-0\")}>\n                            <ErrorBoundary>\n                                {value && <PropertyPreview\n                                    propertyKey={propertyKey}\n                                    value={value[valueField]}\n                                    // entity={entity}\n                                    property={(property.resolvedProperties[index] ?? properties[value[typeField]]) as ResolvedProperty<any>}\n                                    size={childSize}/>}\n                            </ErrorBoundary>\n                        </div>\n                    </React.Fragment>\n                )}\n        </div>\n    );\n}\n","import React from \"react\";\n\nimport { ResolvedMapProperty } from \"../../types\";\nimport { PropertyPreviewProps } from \"../PropertyPreviewProps\";\nimport { PropertyPreview } from \"../PropertyPreview\";\nimport { cn, defaultBorderMixin, Typography } from \"@firecms/ui\";\nimport { ErrorBoundary } from \"../../components\";\nimport { EmptyValue } from \"../components/EmptyValue\";\n\n/**\n * @group Preview components\n */\nexport function MapPropertyPreview<T extends Record<string, any> = Record<string, any>>({\n                                                                                            propertyKey,\n                                                                                            value,\n                                                                                            property,\n                                                                                            // entity,\n                                                                                            size\n                                                                                        }: PropertyPreviewProps<T>) {\n\n    if (property.dataType !== \"map\") {\n        throw Error(\"Picked wrong preview component MapPropertyPreview\");\n    }\n\n    const mapProperty = property as ResolvedMapProperty;\n\n    if (!mapProperty.properties || Object.keys(mapProperty.properties ?? {}).length === 0) {\n        return (\n            <KeyValuePreview value={value}/>\n        );\n    }\n\n    if (!value) return null;\n\n    const mapPropertyKeys: string[] = Object.keys(mapProperty.properties)\n\n    if (size === \"tiny\")\n        return (\n            <div className=\"w-full flex flex-col space-y-1 md:space-y-2\">\n                {mapPropertyKeys.map((key, index) => (\n                    <div key={`map_${key}`}>\n                        <ErrorBoundary\n                            key={\"map_preview_\" + mapProperty.name + key + index}>\n                            <PropertyPreview propertyKey={key}\n                                             value={(value)[key]}\n                                             property={mapProperty.properties![key]}\n                                // entity={entity}\n                                             size={size}/>\n                        </ErrorBoundary>\n                    </div>\n                ))}\n            </div>\n        );\n\n    return (\n        <div\n            className=\"flex flex-col gap-1 w-full\">\n            {mapPropertyKeys &&\n                mapPropertyKeys.map((key, index) => {\n                    const childProperty = mapProperty.properties![key];\n                    return (\n                        <div\n                            key={`map_preview_table_${key}}`}\n                            className={cn(defaultBorderMixin, \"last:border-b-0 border-b\")}>\n                            <div\n                                className={\"flex flex-row pt-0.5 pb-0.5 gap-2\"}>\n                                <div\n                                    className=\"min-w-[140px] w-[25%] py-1\">\n                                    <Typography variant={\"caption\"}\n                                                className={\"font-mono break-words\"}\n                                                color={\"secondary\"}>\n                                        {childProperty.name}\n                                    </Typography>\n                                </div>\n                                <div\n                                    className=\"flex-grow max-w-[75%]\">\n                                    <ErrorBoundary>\n                                        {!(childProperty.dataType === \"map\" || childProperty === \"array\") &&\n                                            <PropertyPreview\n                                                propertyKey={key}\n                                                value={(value)[key]}\n                                                property={childProperty}\n                                                // entity={entity}\n                                                size={size}/>}\n                                    </ErrorBoundary>\n                                </div>\n                            </div>\n\n                            {(childProperty.dataType === \"map\" || childProperty === \"array\") &&\n                                <div className={cn(defaultBorderMixin, \"border-l pl-4 ml-2 my-2\")}>\n                                    <PropertyPreview\n                                        propertyKey={key}\n                                        value={(value)[key]}\n                                        property={childProperty}\n                                        // entity={entity}\n                                        size={size}/>\n                                </div>\n                            }\n                        </div>\n                    );\n                })}\n        </div>\n    );\n\n}\n\nexport function KeyValuePreview({ value }: { value: any }) {\n    if (typeof value !== \"object\") return null;\n    if (!value) return <EmptyValue/>;\n    return <div\n        className=\"flex flex-col gap-1 w-full\">\n        {\n            Object.entries(value).map(([key, childValue]) => (\n                <div\n                    key={`map_preview_table_${key}}`}\n                    className={cn(defaultBorderMixin, \"last:border-b-0 border-b\")}>\n                    <div\n                        className={\"flex flex-row pt-0.5 pb-0.5 gap-2\"}>\n                        <div\n                            key={`table-cell-title-${key}-${key}`}\n                            className=\"min-w-[140px] w-[25%] py-1\">\n                            <Typography variant={\"caption\"}\n                                        className={\"font-mono break-words\"}\n                                        color={\"secondary\"}>\n                                {key}\n                            </Typography>\n                        </div>\n                        <div\n                            className=\"flex-grow max-w-[75%]\">\n                            {typeof childValue !== \"object\" && <Typography>\n                                <ErrorBoundary>\n                                    {childValue && childValue.toString()}\n                                </ErrorBoundary>\n                            </Typography>}\n                        </div>\n                    </div>\n                    {typeof childValue === \"object\" &&\n                        <div className={cn(defaultBorderMixin, \"border-l pl-4\")}>\n                            <KeyValuePreview value={childValue}/>\n                        </div>\n                    }\n                </div>\n            ))\n        }\n    </div>;\n}\n","import React from \"react\";\n\nimport { format } from \"date-fns\";\nimport * as locales from \"date-fns/locale\";\nimport { useCustomizationController } from \"../../hooks\";\nimport { defaultDateFormat } from \"../../util\";\n\n/**\n * @group Preview components\n */\nexport function DatePreview({\n                                date\n                            }: { date: Date }): React.ReactElement {\n\n    const customizationController = useCustomizationController();\n    // @ts-ignore\n    const dateUtilsLocale = customizationController?.locale ? locales[customizationController?.locale] : undefined;\n    const dateFormat: string = customizationController?.dateTimeFormat ?? defaultDateFormat;\n    const formattedDate = date ? format(date, dateFormat, { locale: dateUtilsLocale }) : \"\";\n\n    return (\n        <>\n            {formattedDate}\n        </>\n    );\n}\n","import React from \"react\";\nimport { Checkbox, cn } from \"@firecms/ui\";\nimport { PreviewSize } from \"../PropertyPreviewProps\";\nimport { Property } from \"../../types\";\n\n/**\n * @group Preview components\n */\nexport function BooleanPreview({\n                                   value,\n                                   size,\n                                   property\n                               }: {\n    value: boolean,\n    size: PreviewSize,\n    property: Property,\n}): React.ReactElement {\n    return <div className={\"flex flex-row gap-2 items-center\"}>\n        <Checkbox checked={value}\n                  padding={false}\n                  size={size}\n                  color={\"secondary\"}/>\n        {property.name && <span\n            className={cn(\"text-text-secondary dark:text-text-secondary-dark\", size === \"tiny\" ? \"text-sm\" : \"\")}>{property.name}</span>}\n    </div>;\n}\n","import React from \"react\";\n\nimport { EnumValuesChip, PropertyPreviewProps } from \"../../preview\";\nimport { enumToObjectEntries } from \"../../util\";\n\n/**\n * @group Preview components\n */\nexport function NumberPropertyPreview({\n                                          value,\n                                          property,\n                                          size\n                                      }: PropertyPreviewProps<number>): React.ReactElement {\n\n    if (property.enumValues) {\n        const enumKey = value;\n        const enumValues = enumToObjectEntries(property.enumValues);\n        console.log(\"NumberPropertyPreview\", enumValues)\n        if (!enumValues)\n            return <>{value}</>;\n        return <EnumValuesChip\n            enumKey={enumKey}\n            enumValues={enumValues}\n            size={size !== \"medium\" ? \"small\" : \"medium\"}/>;\n    } else {\n        return <>{value}</>;\n    }\n}\n","import React, { createElement } from \"react\";\nimport equal from \"react-fast-compare\"\n\nimport {\n    CMSType,\n    EntityReference,\n    ResolvedArrayProperty,\n    ResolvedMapProperty,\n    ResolvedNumberProperty,\n    ResolvedStringProperty\n} from \"../types\";\n\nimport { resolveProperty } from \"../util\";\n\nimport { PropertyPreviewProps } from \"./PropertyPreviewProps\";\nimport { useCustomizationController } from \"../hooks\";\nimport { EmptyValue } from \"./components/EmptyValue\";\nimport { UrlComponentPreview } from \"./components/UrlComponentPreview\";\nimport { StorageThumbnail } from \"./components/StorageThumbnail\";\nimport { Markdown } from \"@firecms/ui\";\nimport { StringPropertyPreview } from \"./property_previews/StringPropertyPreview\";\nimport { ArrayPropertyPreview } from \"./property_previews/ArrayPropertyPreview\";\nimport { ArrayOfReferencesPreview } from \"./property_previews/ArrayOfReferencesPreview\";\nimport { ArrayOfStorageComponentsPreview } from \"./property_previews/ArrayOfStorageComponentsPreview\";\nimport { ArrayPropertyEnumPreview } from \"./property_previews/ArrayPropertyEnumPreview\";\nimport { ArrayOfStringsPreview } from \"./property_previews/ArrayOfStringsPreview\";\nimport { ArrayOneOfPreview } from \"./property_previews/ArrayOneOfPreview\";\nimport { MapPropertyPreview } from \"./property_previews/MapPropertyPreview\";\nimport { ReferencePreview } from \"./components/ReferencePreview\";\nimport { DatePreview } from \"./components/DatePreview\";\nimport { BooleanPreview } from \"./components/BooleanPreview\";\nimport { NumberPropertyPreview } from \"./property_previews/NumberPropertyPreview\";\nimport { ErrorView } from \"../components\";\n\n/**\n * @group Preview components\n */\nexport const PropertyPreview = React.memo(function PropertyPreview<T extends CMSType>(props: PropertyPreviewProps<T>) {\n\n    const customizationController = useCustomizationController();\n\n    let content: React.ReactNode | any;\n    const {\n        property: inputProperty,\n        propertyKey,\n        value,\n        size,\n        height,\n        width,\n        // entity\n    } = props;\n\n    const property = resolveProperty({\n        propertyKey,\n        propertyOrBuilder: inputProperty,\n        fields: customizationController.propertyConfigs\n    });\n\n    if (value === undefined || property === null) {\n        content = <EmptyValue/>;\n    } else if (property.Preview) {\n        content = createElement(property.Preview as React.ComponentType<PropertyPreviewProps>,\n            {\n                propertyKey,\n                value,\n                property,\n                size,\n                height,\n                width,\n                // entity,\n                customProps: property.customProps\n            });\n    } else if (value === null) {\n        content = <EmptyValue/>;\n    } else if (property.dataType === \"string\") {\n        const stringProperty = property as ResolvedStringProperty;\n        if (typeof value === \"string\") {\n            if (stringProperty.url) {\n                if (typeof stringProperty.url === \"boolean\")\n                    content =\n                        <UrlComponentPreview size={props.size}\n                                             url={value}/>;\n                else if (typeof stringProperty.url === \"string\")\n                    content =\n                        <UrlComponentPreview size={props.size}\n                                             url={value}\n                                             previewType={stringProperty.url}/>;\n            } else if (stringProperty.storage) {\n                content = <StorageThumbnail\n                    storeUrl={property.storage?.storeUrl ?? false}\n                    size={props.size}\n                    storagePathOrDownloadUrl={value}/>;\n            } else if (stringProperty.markdown) {\n                content = <Markdown source={value} size={\"small\"}/>;\n            } else {\n                content = <StringPropertyPreview {...props}\n                                                 property={stringProperty}\n                                                 value={value}/>;\n            }\n        } else {\n            content = buildWrongValueType(propertyKey, property.dataType, value);\n        }\n    } else if (property.dataType === \"array\") {\n        if (value instanceof Array) {\n            const arrayProperty = property as ResolvedArrayProperty;\n            if (!arrayProperty.of && !arrayProperty.oneOf) {\n                throw Error(`You need to specify an 'of' or 'oneOf' prop (or specify a custom field) in your array property ${propertyKey}`);\n            }\n\n            if (arrayProperty.of) {\n                if (Array.isArray(arrayProperty.of)) {\n                    content = <ArrayPropertyPreview {...props}\n                                                    value={value}\n                                                    property={property as ResolvedArrayProperty}/>;\n                } else if (arrayProperty.of.dataType === \"reference\") {\n                    content = <ArrayOfReferencesPreview {...props}\n                                                        value={value}\n                                                        property={property as ResolvedArrayProperty}/>;\n                } else if (arrayProperty.of.dataType === \"string\") {\n                    if (arrayProperty.of.enumValues) {\n                        content = <ArrayPropertyEnumPreview\n                            {...props}\n                            value={value as string[]}\n                            property={property as ResolvedArrayProperty}/>;\n                    } else if (arrayProperty.of.storage) {\n                        content = <ArrayOfStorageComponentsPreview\n                            {...props}\n                            value={value}\n                            property={property as ResolvedArrayProperty}/>;\n                    } else {\n                        content = <ArrayOfStringsPreview\n                            {...props}\n                            value={value as string[]}\n                            property={property as ResolvedArrayProperty}/>;\n                    }\n                } else if (arrayProperty.of.dataType === \"number\" && arrayProperty.of.enumValues) {\n                    content = <ArrayPropertyEnumPreview\n                        {...props}\n                        value={value as string[]}\n                        property={property as ResolvedArrayProperty}/>;\n                } else {\n                    content = <ArrayPropertyPreview {...props}\n                                                    value={value}\n                                                    property={property as ResolvedArrayProperty}/>;\n                }\n            } else if (arrayProperty.oneOf) {\n                content = <ArrayOneOfPreview {...props}\n                                             value={value}\n                                             property={property as ResolvedArrayProperty}/>;\n            }\n        } else {\n            content = buildWrongValueType(propertyKey, property.dataType, value);\n        }\n    } else if (property.dataType === \"map\") {\n        if (typeof value === \"object\") {\n            content =\n                <MapPropertyPreview {...props}\n                                    property={property as ResolvedMapProperty}/>;\n        } else {\n            content = buildWrongValueType(propertyKey, property.dataType, value);\n        }\n    } else if (property.dataType === \"date\") {\n        if (value instanceof Date) {\n            content = <DatePreview date={value}/>;\n        } else {\n            content = buildWrongValueType(propertyKey, property.dataType, value);\n        }\n    } else if (property.dataType === \"reference\") {\n        if (typeof property.path === \"string\") {\n            if (typeof value === \"object\" && \"isEntityReference\" in value && value.isEntityReference()) {\n                content = <ReferencePreview\n                    disabled={!property.path}\n                    previewProperties={property.previewProperties}\n                    size={props.size}\n                    // onClick={props.onClick}\n                    reference={value as EntityReference}\n                />;\n            } else {\n                content = buildWrongValueType(propertyKey, property.dataType, value);\n            }\n        } else {\n            content = <EmptyValue/>;\n        }\n\n    } else if (property.dataType === \"boolean\") {\n        if (typeof value === \"boolean\") {\n            content = <BooleanPreview value={value} size={size} property={property}/>;\n        } else {\n            content = buildWrongValueType(propertyKey, property.dataType, value);\n        }\n    } else if (property.dataType === \"number\") {\n        if (typeof value === \"number\") {\n            content = <NumberPropertyPreview {...props}\n                                             value={value}\n                                             property={property as ResolvedNumberProperty}/>;\n        } else {\n            content = buildWrongValueType(propertyKey, property.dataType, value);\n        }\n    } else {\n        content = JSON.stringify(value);\n    }\n\n    return content === undefined || content === null || (Array.isArray(content) && content.length === 0)\n        ? <EmptyValue/>\n        : content;\n}, equal);\n\nfunction buildWrongValueType(name: string | undefined, dataType: string, value: any) {\n    console.warn(`Unexpected value for property ${name}, of type ${dataType}`, value);\n    return (\n        <ErrorView title={\"Unexpected value\"}\n                   error={`${JSON.stringify(value)}`}/>\n    );\n}\n","import * as React from \"react\";\nimport { useEffect, useState } from \"react\";\nimport { Skeleton } from \"@firecms/ui\";\n\nexport interface AsyncPreviewComponentProps {\n    builder: Promise<React.ReactNode>;\n}\n\n/**\n * Utility component used to render the result of an async execution.\n * It shows a loading indicator while at it.\n *\n * @group Preview components\n */\nexport const AsyncPreviewComponent = React.memo(function AsyncPreviewComponentInternal<M extends Record<string, any>>(\n        {\n            builder\n        }: AsyncPreviewComponentProps) {\n\n        const [loading, setLoading] = useState<boolean>(true);\n        const [result, setResult] = useState<React.ReactNode>(null);\n\n        useEffect(() => {\n            let unmounted = false;\n            builder\n                .then((res) => {\n                    if (!unmounted) {\n                        setLoading(false);\n                        setResult(res);\n                    }\n                })\n                .catch(error => {\n                    setLoading(false);\n                    console.error(error);\n                });\n            return () => {\n                unmounted = true;\n            };\n        }, [builder]);\n\n        if (loading)\n            return <Skeleton/>;\n\n        return <React.Fragment>{result}</React.Fragment>;\n\n    }\n);\n","import React, { useMemo } from \"react\";\nimport { PropertyPreview } from \"../preview\";\nimport { Entity, EntityCollection, ResolvedEntityCollection, ResolvedProperties } from \"../types\";\nimport { resolveCollection } from \"../util\";\nimport { cn, defaultBorderMixin, IconButton, OpenInNewIcon } from \"@firecms/ui\";\nimport { CustomizationController } from \"../types/customization_controller\";\nimport { useCustomizationController } from \"../hooks/useCustomizationController\";\n\n/**\n * @group Components\n */\nexport interface EntityViewProps<M extends Record<string, any>> {\n    entity: Entity<M>;\n    collection: EntityCollection<M>;\n    path: string;\n    className?: string;\n}\n\nexport function EntityView<M extends Record<string, any>>(\n    {\n        entity,\n        collection,\n        path,\n        className\n    }: EntityViewProps<M>) {\n\n    const customizationController: CustomizationController = useCustomizationController();\n    const resolvedCollection: ResolvedEntityCollection<M> = useMemo(() => resolveCollection<M>({\n        collection,\n        path,\n        entityId: entity.id,\n        values: entity.values,\n        fields: customizationController.propertyConfigs\n    }), [collection, path, entity, customizationController.propertyConfigs]);\n\n    const properties: ResolvedProperties = resolvedCollection.properties;\n\n    return (\n        <div className={\"w-full \" + className}>\n            <div className={\"w-full mb-4\"}>\n                <div className={cn(defaultBorderMixin, \"flex justify-between py-2 border-b last:border-b-0\")}>\n                    <div className=\"flex items-center w-1/4\">\n                        <span className=\"pl-2 text-sm text-gray-600\">Id</span>\n                    </div>\n                    <div\n                        className=\"flex-grow p-2 ml-2 w-3/4 text-gray-900 dark:text-white min-h-[56px] flex items-center\">\n                        <span className=\"flex-grow mr-2\">{entity.id}</span>\n                        {customizationController?.entityLinkBuilder &&\n                            <a href={customizationController.entityLinkBuilder({ entity })}\n                               rel=\"noopener noreferrer\"\n                               target=\"_blank\">\n                                <IconButton>\n                                    <OpenInNewIcon\n                                        size={\"small\"}/>\n                                </IconButton>\n                            </a>}\n                    </div>\n                </div>\n                {Object.entries(properties)\n                    .map(([key, property]) => {\n                        const value = entity.values?.[key];\n                        return (\n                            <div\n                                key={`reference_previews_${key}`}\n                                className={cn(defaultBorderMixin, \"flex justify-between py-2 border-b last:border-b-0\")}>\n                                <div className=\"flex items-center w-1/4\">\n                                    <span className=\"pl-2 text-sm text-gray-600\">{property.name}</span>\n                                </div>\n                                <div\n                                    className=\"flex-grow p-2 ml-2 w-3/4 text-gray-900 dark:text-white min-h-[56px] flex items-center\">\n                                    <PropertyPreview\n                                        propertyKey={key}\n                                        value={value}\n                                        // entity={entity}\n                                        property={property}\n                                        size={\"medium\"}/>\n                                </div>\n                            </div>\n                        )\n                    })}\n            </div>\n        </div>\n    );\n}\n","import React, { useEffect, useRef, useState } from \"react\";\n\nimport { useDebouncedCallback } from \"../../../util\";\nimport { TextareaAutosize } from \"@firecms/ui\";\n\nexport function VirtualTableInput(props: {\n    error: Error | undefined;\n    value: string;\n    multiline: boolean;\n    focused: boolean;\n    disabled: boolean;\n    updateValue: (newValue: (string | null)) => void;\n}) {\n\n    const ref = React.useRef<HTMLTextAreaElement>(null);\n\n    const {\n        disabled,\n        value,\n        multiline,\n        updateValue,\n        focused\n    } = props;\n\n    const prevValue = useRef<string | null>(value);\n\n    const [internalValue, setInternalValue] = useState<typeof value>(value);\n    const focusedState = useRef<boolean>(false);\n\n    useEffect(() => {\n        if (prevValue.current !== value && value !== internalValue)\n            setInternalValue(value);\n        prevValue.current = value;\n    }, [value]);\n\n    const doUpdate = React.useCallback(() => {\n        const emptyInitialValue = !value;\n        if (emptyInitialValue && !internalValue)\n            return;\n        if (internalValue !== value) {\n            prevValue.current = internalValue;\n            updateValue(internalValue);\n        }\n    }, [internalValue, updateValue, value]);\n\n    useDebouncedCallback(internalValue, doUpdate, !focused, 2000);\n\n    useEffect(() => {\n        if (ref.current && focused && !focusedState.current) {\n            focusedState.current = true;\n            ref.current.focus({ preventScroll: true });\n            ref.current.selectionStart = ref.current.value.length;\n            ref.current.selectionEnd = ref.current.value.length;\n        } else {\n            focusedState.current = focused;\n        }\n    }, [focused, ref]);\n\n    return (\n        <TextareaAutosize\n            ref={ref}\n            style={{\n                padding: 0,\n                margin: 0,\n                width: \"100%\",\n                color: \"unset\",\n                fontWeight: \"unset\",\n                lineHeight: \"unset\",\n                fontSize: \"unset\",\n                fontFamily: \"unset\",\n                background: \"unset\",\n                border: \"unset\",\n                resize: \"none\",\n                outline: \"none\"\n            }}\n            value={internalValue ?? \"\"}\n            onChange={(evt) => {\n                const newValue = evt.target.value as string;\n                if (multiline || !newValue.endsWith(\"\\n\"))\n                    setInternalValue(newValue);\n            }}\n            onFocus={() => {\n                focusedState.current = true;\n            }}\n            onBlur={() => {\n                focusedState.current = false;\n                doUpdate();\n            }}\n        />\n    );\n}\n","import { EnumValueConfig } from \"../../../types\";\nimport { ArrayEnumPreview, EnumValuesChip } from \"../../../preview\";\nimport React, { useCallback, useEffect } from \"react\";\nimport { MultiSelect, MultiSelectItem, Select, SelectItem } from \"@firecms/ui\";\n\nexport function VirtualTableSelect(props: {\n    name: string;\n    enumValues: EnumValueConfig[];\n    error: Error | undefined;\n    multiple: boolean;\n    disabled: boolean;\n    small: boolean;\n    internalValue: string | number | string[] | number[] | undefined;\n    valueType: \"string\" | \"number\";\n    updateValue: (newValue: (string | number | string[] | number[] | null)) => void;\n    focused: boolean;\n    onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n}) {\n\n    const {\n        name,\n        enumValues,\n        error,\n        internalValue,\n        disabled,\n        small,\n        focused,\n        updateValue,\n        multiple,\n        valueType\n    } = props;\n\n    const validValue = (Array.isArray(internalValue) && multiple) ||\n        (!Array.isArray(internalValue) && !multiple);\n\n    const ref = React.useRef<HTMLButtonElement>(null);\n    useEffect(() => {\n        if (ref.current && focused) {\n            ref.current?.focus({ preventScroll: true });\n        }\n    }, [focused, ref]);\n\n    const onChange = useCallback((updatedValue: string | string[]) => {\n        if (valueType === \"number\") {\n            if (multiple) {\n                const newValue = (updatedValue as string[]).map((v) => parseFloat(v));\n                updateValue(newValue);\n            } else {\n                updateValue(parseFloat(updatedValue as string));\n            }\n        } else if (valueType === \"string\") {\n            if (!updatedValue)\n                updateValue(null)\n            else\n                updateValue(updatedValue);\n        } else {\n            throw Error(\"Missing mapping in TableSelect\");\n        }\n    }, [multiple, updateValue, valueType]);\n\n    const renderValue = (enumKey: string | number, index: number) => {\n        if (multiple && Array.isArray(enumKey)) {\n            return <ArrayEnumPreview\n                key={`${enumKey}-${index}`}\n                value={enumKey}\n                name={name}\n                enumValues={enumValues}\n                size={small ? \"small\" : \"medium\"}/>;\n        } else {\n            return <EnumValuesChip\n                key={`${enumKey}-${index}`}\n                enumKey={enumKey}\n                enumValues={enumValues}\n                size={small ? \"small\" : \"medium\"}/>;\n        }\n    };\n    return (\n        multiple\n            ? <MultiSelect\n                inputRef={ref}\n                containerClassName=\"w-full h-full\"\n                className=\"w-full h-full p-0 bg-transparent\"\n                position={\"item-aligned\"}\n                disabled={disabled}\n                padding={false}\n                includeFocusOutline={false}\n                value={validValue\n                    ? ((internalValue as any[]).map(v => v.toString()))\n                    : ([])}\n                onMultiValueChange={onChange}\n                renderValue={renderValue}>\n                {enumValues?.map((enumConfig) => (\n                    <MultiSelectItem\n                        key={enumConfig.id}\n                        value={String(enumConfig.id)}>\n                        <EnumValuesChip\n                            enumKey={enumConfig.id}\n                            enumValues={enumValues}\n                            size={small ? \"small\" : \"medium\"}/>\n                    </MultiSelectItem>\n                ))}\n            </MultiSelect>\n            : <Select\n                inputRef={ref}\n                className=\"w-full h-full p-0 bg-transparent\"\n                position={\"item-aligned\"}\n                disabled={disabled}\n                multiple={multiple}\n                padding={false}\n                includeFocusOutline={false}\n                value={validValue\n                    ? (multiple ? (internalValue as any[]).map(v => v.toString()) : internalValue?.toString())\n                    : (multiple ? [] : \"\")}\n                onValueChange={onChange}\n                onMultiValueChange={onChange}\n                renderValue={renderValue}>\n                {enumValues?.map((enumConfig) => (\n                    <SelectItem\n                        key={enumConfig.id}\n                        value={String(enumConfig.id)}>\n                        <EnumValuesChip\n                            enumKey={enumConfig.id}\n                            enumValues={enumValues}\n                            size={small ? \"small\" : \"medium\"}/>\n                    </SelectItem>\n                ))}\n            </Select>\n\n    );\n}\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { useDebouncedCallback } from \"../../../util\";\n\nexport function VirtualTableNumberInput(props: {\n    error: Error | undefined;\n    value: number;\n    align: \"right\" | \"left\" | \"center\";\n    updateValue: (newValue: (number | null)) => void;\n    focused: boolean;\n    disabled: boolean;\n}) {\n\n    const {\n        align,\n        value,\n        updateValue,\n        focused,\n    } = props;\n    const propStringValue = (value && typeof value === \"number\") ? value.toString() : \"\";\n    const [internalValue, setInternalValue] = useState<string | null>(propStringValue);\n\n    const prevValue = useRef<number | null>(value);\n\n    useEffect(() => {\n        if (prevValue.current !== value && String(value) !== internalValue)\n            setInternalValue(value ? value.toString() : null);\n        prevValue.current = value;\n    }, [value]);\n\n    const doUpdate = React.useCallback(() => {\n        if (internalValue !== propStringValue) {\n            if (internalValue !== undefined && internalValue !== null) {\n                const numberValue = parseFloat(internalValue);\n                if (isNaN(numberValue))\n                    return;\n                if (numberValue !== undefined && numberValue !== null)\n                    updateValue(numberValue);\n            } else {\n                updateValue(null);\n            }\n        }\n\n    }, [internalValue, value]);\n\n    useDebouncedCallback(internalValue, doUpdate, !focused, 2000);\n\n    useEffect(\n        () => {\n            if (!focused && propStringValue !== internalValue)\n                setInternalValue(value !== undefined && value !== null ? value.toString() : null);\n        },\n        [value, focused]\n    );\n\n    const ref = React.useRef<HTMLInputElement>(null);\n\n    useEffect(() => {\n        if (ref.current && focused) {\n            ref.current.focus({ preventScroll: true });\n        }\n    }, [focused, ref]);\n\n    const regexp = /^-?[0-9]+[,.]?[0-9]*$/;\n\n    return (\n        <input\n            ref={ref}\n            className=\"w-full text-right p-0 m-0 bg-transparent border-none resize-none outline-none font-normal leading-normal text-unset\"\n            style={{\n                textAlign: align\n            }}\n            value={internalValue ?? \"\"}\n            onChange={(evt) => {\n                const newValue = evt.target.value.replace(\",\", \".\");\n                if (newValue.length === 0)\n                    setInternalValue(null);\n                if (regexp.test(newValue) || newValue.startsWith(\"-\"))\n                    setInternalValue(newValue);\n            }}\n        />\n    );\n}\n","import React, { useEffect } from \"react\";\nimport { BooleanSwitch } from \"@firecms/ui\";\n\nexport function VirtualTableSwitch(props: {\n    error: Error | undefined;\n    internalValue?: boolean;\n    focused: boolean;\n    disabled: boolean;\n    updateValue: (newValue: (boolean | null)) => void;\n}) {\n    const {\n        internalValue,\n        updateValue,\n        focused\n    } = props;\n    const ref = React.useRef<HTMLButtonElement>(null);\n\n    useEffect(() => {\n        if (ref.current && focused) {\n            ref.current.focus({ preventScroll: true });\n        }\n    }, [focused, ref]);\n\n    return (\n        <BooleanSwitch\n            ref={ref}\n            size={\"small\"}\n            value={Boolean(internalValue)}\n            onValueChange={updateValue}\n        />\n    );\n}\n","import React from \"react\";\nimport { DateTimeField } from \"@firecms/ui\";\nimport { useCustomizationController } from \"../../../hooks\";\n\nexport function VirtualTableDateField(props: {\n    name: string;\n    error: Error | undefined;\n    mode?: \"date\" | \"date_time\";\n    internalValue: Date | undefined | null;\n    updateValue: (newValue: (Date | null)) => void;\n    focused: boolean;\n    disabled: boolean;\n    onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n}) {\n\n    const { locale } = useCustomizationController();\n    const {\n        disabled,\n        error,\n        mode,\n        internalValue,\n        updateValue\n    } = props;\n\n    return (\n        <DateTimeField\n            value={internalValue ?? undefined}\n            onChange={(dateValue) => updateValue(dateValue ?? null)}\n            size={\"medium\"}\n            invisible={true}\n            className={\"w-full h-full\"}\n            inputClassName={\"w-full h-full\"}\n            mode={mode}\n            locale={locale}\n        />\n    );\n}\n","import React, { ErrorInfo, PropsWithChildren } from \"react\";\n\nimport { ErrorIcon, Typography } from \"@firecms/ui\";\n\nexport class ErrorBoundary extends React.Component<PropsWithChildren<Record<string, unknown>>, {\n    error: Error | null\n}> {\n    constructor(props: any) {\n        super(props);\n        this.state = { error: null };\n    }\n\n    // eslint-disable-next-line n/handle-callback-err\n    static getDerivedStateFromError(error: Error) {\n        return { error };\n    }\n\n    componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n        console.error(error);\n        // logErrorToMyService(error, errorInfo);\n    }\n\n    render() {\n        if (this.state.error) {\n            return (\n                <div className=\"flex flex-col m-2\">\n                    <div className=\"flex items-center m-2\">\n                        <ErrorIcon color={\"error\"} size={\"small\"}/>\n                        <div className=\"ml-4\">Error</div>\n                    </div>\n                    <Typography variant={\"caption\"}>\n                        {this.state.error?.message ?? \"See the error in the console\"}\n                    </Typography>\n                </div>\n            );\n        }\n\n        return this.props.children;\n    }\n}\n","import {\n    EntityValues,\n    ResolvedArrayProperty,\n    ResolvedStringProperty,\n    StorageConfig,\n    UploadedFileContext\n} from \"../types\";\nimport { randomString } from \"./strings\";\n\nexport async function resolveFilenameString<M extends object>(\n    input: string | ((context: UploadedFileContext) => Promise<string> | string),\n    storage: StorageConfig,\n    values: EntityValues<M>,\n    entityId: string,\n    path: string,\n    property: ResolvedStringProperty | ResolvedArrayProperty<string[]>,\n    file: File,\n    propertyKey: string): Promise<string> {\n    let result;\n    if (typeof input === \"function\") {\n        result = await input({\n            path,\n            entityId,\n            values,\n            property,\n            file,\n            storage,\n            propertyKey\n        });\n        if (!result)\n            console.warn(\"Storage callback returned empty result. Using default name value\")\n    } else {\n        result = replacePlaceholders(file, input, entityId, propertyKey, path);\n    }\n\n    if (!result)\n        result = randomString() + \"_\" + file.name;\n\n    return result;\n}\n\nexport function resolveStoragePathString<M extends object>(\n    input: string | ((context: UploadedFileContext) => string),\n    storage: StorageConfig,\n    values: EntityValues<M>,\n    entityId: string,\n    path: string,\n    property: ResolvedStringProperty | ResolvedArrayProperty<string[]>,\n    file: File,\n    propertyKey: string): string {\n    let result;\n    if (typeof input === \"function\") {\n        result = input({\n            path,\n            entityId,\n            values,\n            property,\n            file,\n            storage,\n            propertyKey\n        });\n        if (!result)\n            console.warn(\"Storage callback returned empty result. Using default name value\")\n    } else {\n        result = replacePlaceholders(file, input, entityId, propertyKey, path);\n    }\n\n    if (!result)\n        result = randomString() + \"_\" + file.name;\n\n    return result;\n}\n\nfunction replacePlaceholders(file: File, input: string, entityId: string, propertyKey: string, path: string) {\n    const ext = file.name.split(\".\").pop();\n    let result = input.replace(\"{entityId}\", entityId)\n        .replace(\"{propertyKey}\", propertyKey)\n        .replace(\"{rand}\", randomString())\n        .replace(\"{file}\", file.name)\n        .replace(\"{file.type}\", file.type)\n        .replace(\"{path}\", path);\n    if (ext) {\n        result = result.replace(\"{file.ext}\", ext);\n        const name = file.name.replace(`.${ext}`, \"\");\n        result = result.replace(\"{file.name}\", name)\n    }\n\n    if (!result)\n        result = randomString() + \"_\" + file.name;\n\n    return result;\n}\n","import Resizer from \"react-image-file-resizer\";\nimport equal from \"react-fast-compare\";\n\nimport {\n    EntityValues,\n    ImageCompression,\n    Property,\n    ResolvedArrayProperty,\n    ResolvedStringProperty,\n    StorageConfig,\n    StorageSource,\n    StringProperty\n} from \"../types\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { PreviewSize } from \"../preview\";\nimport { randomString } from \"./strings\";\nimport { resolveFilenameString, resolveStoragePathString } from \"./storage\";\n\n/**\n * Internal representation of an item in the storage\n * It can have two states, having a storagePathOrDownloadUrl set,\n * which means the file has been uploaded, and it is rendered as a preview\n * Or have a pending file being uploaded.\n */\nexport interface StorageFieldItem {\n    id: number; // generated on the fly for internal use only\n    storagePathOrDownloadUrl?: string;\n    file?: File;\n    fileName?: string;\n    metadata?: any,\n    size: PreviewSize\n}\n\nexport function useStorageUploadController<M extends object>({\n                                                                 entityId,\n                                                                 entityValues,\n                                                                 path,\n                                                                 value,\n                                                                 property,\n                                                                 propertyKey,\n                                                                 storageSource,\n                                                                 disabled,\n                                                                 onChange\n                                                             }:\n                                                                 {\n                                                                     entityId: string,\n                                                                     entityValues: EntityValues<M>,\n                                                                     value: string | string[] | null;\n                                                                     path: string,\n                                                                     propertyKey: string,\n                                                                     property: ResolvedStringProperty | ResolvedArrayProperty<string[]>,\n                                                                     storageSource: StorageSource,\n                                                                     disabled: boolean,\n                                                                     onChange: (value: string | string[] | null) => void\n                                                                 }) {\n\n    const storage: StorageConfig | undefined = property.dataType === \"string\"\n        ? property.storage\n        : property.dataType === \"array\" &&\n        (property.of as Property).dataType === \"string\"\n            ? (property.of as StringProperty).storage\n            : undefined;\n\n    const multipleFilesSupported = property.dataType === \"array\";\n\n    if (!storage)\n        throw Error(\"Storage meta must be specified\");\n\n    const metadata: Record<string, any> | undefined = storage?.metadata;\n    const size = multipleFilesSupported ? \"small\" : \"medium\";\n\n    const compression: ImageCompression | undefined = storage?.imageCompression;\n\n    const internalInitialValue: StorageFieldItem[] =\n        (multipleFilesSupported\n            ? (value ?? []) as string[]\n            : value ? [value as string] : []).map(entry => (\n            {\n                id: getRandomId(),\n                storagePathOrDownloadUrl: entry,\n                metadata,\n                size\n            }\n        ));\n\n    const [initialValue, setInitialValue] = useState<string | string[] | null>(value);\n    const [internalValue, setInternalValue] = useState<StorageFieldItem[]>(internalInitialValue);\n\n    useEffect(() => {\n        if (!equal(initialValue, value)) {\n            setInitialValue(value);\n            setInternalValue(internalInitialValue);\n        }\n    }, [internalInitialValue, value, initialValue]);\n\n    const fileNameBuilder = useCallback(async (file: File) => {\n        if (storage.fileName) {\n            const fileName = await resolveFilenameString(storage.fileName, storage, entityValues, entityId, path, property, file, propertyKey);\n            if (!fileName || fileName.length === 0) {\n                throw Error(\"You need to return a valid filename\");\n            }\n            return fileName;\n        }\n        return randomString() + \"_\" + file.name;\n    }, [entityId, entityValues, path, property, propertyKey, storage]);\n\n    const storagePathBuilder = useCallback((file: File) => {\n        return resolveStoragePathString(storage.storagePath, storage, entityValues, entityId, path, property, file, propertyKey) ?? \"/\";\n    }, [entityId, entityValues, path, property, propertyKey, storage]);\n\n    const onFileUploadComplete = useCallback(async (uploadedPath: string,\n                                                    entry: StorageFieldItem,\n                                                    metadata?: any) => {\n\n        console.debug(\"onFileUploadComplete\", uploadedPath, entry);\n\n        let uploadPathOrDownloadUrl: string | null = uploadedPath;\n        if (storage.storeUrl) {\n            uploadPathOrDownloadUrl = (await storageSource.getDownloadURL(uploadedPath)).url;\n        }\n        if (storage.postProcess && uploadPathOrDownloadUrl) {\n            uploadPathOrDownloadUrl = await storage.postProcess(uploadPathOrDownloadUrl);\n        }\n\n        if (!uploadPathOrDownloadUrl) {\n            console.warn(\"uploadPathOrDownloadUrl is null\")\n            return;\n        }\n\n        let newValue: StorageFieldItem[];\n\n        entry.storagePathOrDownloadUrl = uploadPathOrDownloadUrl;\n        entry.metadata = metadata;\n        newValue = [...internalValue];\n\n        newValue = removeDuplicates(newValue);\n        setInternalValue(newValue);\n\n        const fieldValue = newValue\n            .filter(e => !!e.storagePathOrDownloadUrl)\n            .map(e => e.storagePathOrDownloadUrl as string);\n\n        if (multipleFilesSupported) {\n            onChange(fieldValue);\n        } else {\n            onChange(fieldValue ? fieldValue[0] : null);\n        }\n    }, [internalValue, multipleFilesSupported, onChange, storage, storageSource]);\n\n    const onFilesAdded = useCallback(async (acceptedFiles: File[]) => {\n\n        if (!acceptedFiles.length || disabled)\n            return;\n\n        let newInternalValue: StorageFieldItem[];\n        if (multipleFilesSupported) {\n            newInternalValue = [...internalValue,\n                ...(await Promise.all(acceptedFiles.map(async file => {\n                    if (compression && compressionFormat(file)) {\n                        file = await resizeAndCompressImage(file, compression)\n                    }\n\n                    return {\n                        id: getRandomId(),\n                        file,\n                        fileName: await fileNameBuilder(file),\n                        metadata,\n                        size\n                    } as StorageFieldItem;\n                })))];\n        } else {\n            let file = acceptedFiles[0]\n            if (compression && compressionFormat(file)) {\n                file = await resizeAndCompressImage(file, compression)\n            }\n\n            newInternalValue = [{\n                id: getRandomId(),\n                file,\n                fileName: await fileNameBuilder(file),\n                metadata,\n                size\n            }];\n        }\n\n        // Remove either storage path or file duplicates\n        newInternalValue = removeDuplicates(newInternalValue);\n        setInternalValue(newInternalValue);\n    }, [disabled, fileNameBuilder, internalValue, metadata, multipleFilesSupported, size]);\n\n    return {\n        internalValue,\n        setInternalValue,\n        storage,\n        fileNameBuilder,\n        storagePathBuilder,\n        onFileUploadComplete,\n        onFilesAdded,\n        multipleFilesSupported\n    }\n}\n\nfunction removeDuplicates(items: StorageFieldItem[]) {\n    return items.filter(\n        (item, i) => {\n            return ((items.map((v) => v.storagePathOrDownloadUrl).indexOf(item.storagePathOrDownloadUrl) === i) || !item.storagePathOrDownloadUrl) &&\n                ((items.map((v) => v.file).indexOf(item.file) === i) || !item.file);\n        }\n    );\n}\n\nfunction getRandomId() {\n    return Math.floor(Math.random() * Math.floor(Number.MAX_SAFE_INTEGER));\n}\n\nconst supportedTypes: Record<string, string> = {\n    \"image/jpeg\": \"JPEG\",\n    \"image/png\": \"PNG\",\n    \"image/webp\": \"WEBP\"\n}\nconst compressionFormat = (file: File) => supportedTypes[file.type] ? supportedTypes[file.type] : null;\n\nconst defaultQuality = 100;\nconst resizeAndCompressImage = (file: File, compression: ImageCompression) => new Promise<File>((resolve) => {\n\n    const inputQuality = compression.quality === undefined ? defaultQuality : compression.quality;\n    const quality = inputQuality >= 0 ? inputQuality <= 100 ? inputQuality : 100 : 100;\n\n    const format = compressionFormat(file);\n    if (!format) {\n        throw Error(\"resizeAndCompressImage: Unsupported image format\");\n    }\n    Resizer.imageFileResizer(\n        file,\n        compression.maxWidth || Number.MAX_VALUE,\n        compression.maxHeight || Number.MAX_VALUE,\n        format,\n        quality,\n        0,\n        (file: string | Blob | File | ProgressEvent<FileReader>) => resolve(file as File),\n        \"file\"\n    )\n});\n","import React, { useCallback } from \"react\";\n\nimport { useSnackbarController, useStorageSource } from \"../../hooks\";\nimport { StorageFieldItem } from \"../../util/useStorageUploadController\";\nimport { ErrorView } from \"../../components\";\nimport { cn, paperMixin, Skeleton } from \"@firecms/ui\";\nimport { EntityCollection, StorageSource } from \"../../types\";\n\nexport interface StorageUploadItemProps {\n    storagePath: string;\n    metadata?: any,\n    entry: StorageFieldItem,\n    onFileUploadComplete: (value: string,\n                           entry: StorageFieldItem,\n                           metadata?: any) => Promise<void>;\n    imageSize: number;\n    simple: boolean;\n}\n\nexport function StorageUploadProgress({\n                                          storagePath,\n                                          entry,\n                                          metadata,\n                                          onFileUploadComplete,\n                                          imageSize,\n                                          simple,\n                                      }: StorageUploadItemProps) {\n\n    const storageSource = useStorageSource();\n\n    const snackbarController = useSnackbarController();\n\n    const [error, setError] = React.useState<Error | undefined>();\n    const [loading, setLoading] = React.useState<boolean>(false);\n    const mounted = React.useRef(false);\n    const uploading = React.useRef(false);\n\n    const upload = useCallback((file: File, fileName?: string) => {\n\n        if (uploading.current) return;\n        uploading.current = true;\n        setError(undefined);\n        setLoading(true);\n\n        storageSource.uploadFile({\n            file,\n            fileName,\n            path: storagePath,\n            metadata\n        })\n            .then(async ({ path }) => {\n                console.debug(\"Upload successful\", path);\n                await onFileUploadComplete(path, entry, metadata);\n                if (mounted.current)\n                    setLoading(false);\n            })\n            .catch((e) => {\n                console.warn(\"Upload error\", e);\n                if (mounted.current) {\n                    setError(e);\n                    setLoading(false);\n                    snackbarController.open({\n                        type: \"error\",\n                        message: \"Error uploading file: \" + e.message\n                    });\n                }\n            })\n            .finally(() => {\n                uploading.current = false;\n            });\n    }, [entry, metadata, onFileUploadComplete, storageSource, storagePath]);\n\n    React.useEffect(() => {\n        mounted.current = true;\n        if (entry.file)\n            upload(entry.file, entry.fileName);\n        return () => {\n            mounted.current = false;\n        };\n    }, [entry.file, entry.fileName, upload]);\n\n    if (simple) {\n        return <div className={`m-4 w-${imageSize} h-${imageSize}`}>\n\n            {loading && <Skeleton className={`w-${imageSize} h-${imageSize}`}/>}\n\n        </div>\n    }\n    return (\n\n        <div className={cn(paperMixin,\n            \"relative m-4 border-box flex items-center justify-center\",\n            `min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>\n\n            {loading &&\n                <Skeleton className=\"w-full h-full\"/>}\n\n            {error && <ErrorView title={\"Error uploading file\"}\n                                 error={error}/>}\n\n        </div>\n\n    );\n\n}\n","import { ErrorOutlineIcon, IconButton } from \"@firecms/ui\";\nimport { ErrorTooltip } from \"../../ErrorTooltip\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nexport interface EntityTableCellActionsProps {\n    showError: false | Error | undefined;\n    disabled: boolean;\n    showExpandIcon: boolean | undefined;\n    selected: boolean | undefined;\n    openPopup?: (cellRect: DOMRect | undefined) => void;\n    children?: React.ReactNode;\n}\n\nexport function EntityTableCellActions({ showError, disabled, showExpandIcon, selected, openPopup, children }: EntityTableCellActionsProps) {\n\n    const ref = useRef<HTMLDivElement>(null);\n    const doOpenPopup = useCallback(() => {\n        if (openPopup) {\n            const cellRect = ref && ref?.current?.getBoundingClientRect();\n            openPopup(cellRect);\n        }\n    }, []);\n\n    const iconRef = useRef<HTMLButtonElement>();\n    useEffect(() => {\n        if (iconRef.current && selected) {\n            iconRef.current.focus({ preventScroll: true });\n        }\n    }, [selected]);\n\n    return <>\n        {(showError || (!disabled && showExpandIcon)) &&\n            <div ref={ref} className=\"absolute top-0.5 right-0.5 flex items-center\">\n                {selected && children}\n\n                {selected && !disabled && showExpandIcon &&\n                    <IconButton\n                        ref={iconRef}\n                        color={\"inherit\"}\n                        size={\"small\"}\n                        onClick={doOpenPopup}>\n                        <svg\n                            fill={\"#888\"}\n                            width=\"20\"\n                            height=\"20\"\n                            viewBox=\"0 0 24 24\">\n                            <path className=\"cls-2\"\n                                  d=\"M20,5a1,1,0,0,0-1-1L14,4h0a1,1,0,0,0,0,2h2.57L13.29,9.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0L18,7.42V10a1,1,0,0,0,1,1h0a1,1,0,0,0,1-1Z\"/>\n                            <path className=\"cls-2\"\n                                  d=\"M10.71,13.29a1,1,0,0,0-1.42,0L6,16.57V14a1,1,0,0,0-1-1H5a1,1,0,0,0-1,1l0,5a1,1,0,0,0,1,1h5a1,1,0,0,0,0-2H7.42l3.29-3.29A1,1,0,0,0,10.71,13.29Z\"/>\n                        </svg>\n                    </IconButton>\n                }\n\n                {showError && <ErrorTooltip\n                    side={\"left\"}\n                    className={\"flex items-center justify-center\"}\n                    style={{ width: 32, height: 32 }}\n                    title={showError.message}>\n                    <ErrorOutlineIcon\n                        size={\"small\"}\n                        color={\"error\"}\n                    />\n                </ErrorTooltip>\n                }\n\n            </div>\n        }\n    </>;\n}\n","import * as React from \"react\";\nimport { useMemo, useState } from \"react\";\n\nimport { Entity, ResolvedArrayProperty, ResolvedStringProperty, StorageConfig } from \"../../../types\";\nimport { useDropzone } from \"react-dropzone\";\nimport { PreviewSize, PropertyPreview } from \"../../../preview\";\nimport { ErrorBoundary } from \"../../ErrorBoundary\";\nimport { useSnackbarController, useStorageSource } from \"../../../hooks\";\nimport { getThumbnailMeasure } from \"../../../preview/util\";\nimport { StorageFieldItem, useStorageUploadController } from \"../../../util/useStorageUploadController\";\nimport { StorageUploadProgress } from \"../../../form/components/StorageUploadProgress\";\nimport { cn, EditIcon, IconButton, Typography } from \"@firecms/ui\";\nimport { EntityTableCellActions } from \"../internal/EntityTableCellActions\";\n\nconst dropZoneClasses = \"max-w-full box-border relative pt-[2px] items-center border border-transparent outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid\";\nconst activeDropClasses = \"pt-0 border-2 border-solid\"\nconst acceptDropClasses = \"transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-green-500 bg-green-50 dark:bg-green-900\"\nconst rejectDropClasses = \"transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-red-500 bg-red-50 dark:bg-red-900\"\n\n/**\n * Field that allows to upload files to Google Cloud Storage.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function TableStorageUpload(props: {\n    propertyKey: string;\n    error: Error | undefined;\n    disabled: boolean;\n    value: string | string[] | null;\n    updateValue: (newValue: (string | string[] | null)) => void;\n    selected: boolean;\n    focused: boolean;\n    property: ResolvedStringProperty | ResolvedArrayProperty<string[]>;\n    entity: Entity<any>;\n    path: string;\n    previewSize: PreviewSize;\n    openPopup?: (cellRect?: DOMRect) => void;\n    onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n}) {\n\n    const {\n        propertyKey,\n        error,\n        selected,\n        openPopup,\n        value,\n        disabled,\n        property,\n        entity,\n        path,\n        previewSize,\n        updateValue,\n    } = props;\n\n    const storageSource = useStorageSource();\n\n    const {\n        internalValue,\n        setInternalValue,\n        onFilesAdded,\n        storage,\n        onFileUploadComplete,\n        storagePathBuilder,\n        multipleFilesSupported\n    } = useStorageUploadController({\n        entityValues: entity.values,\n        entityId: entity.id,\n        path,\n        property,\n        propertyKey,\n        storageSource,\n        onChange: updateValue,\n        value,\n        disabled\n    });\n\n    return (\n\n        <StorageUpload\n            internalValue={internalValue}\n            setInternalValue={setInternalValue}\n            name={propertyKey}\n            disabled={disabled}\n            autoFocus={false}\n            openPopup={openPopup}\n            error={error}\n            selected={selected}\n            property={property}\n            onChange={updateValue}\n            entity={entity}\n            storagePathBuilder={storagePathBuilder}\n            storage={storage}\n            multipleFilesSupported={multipleFilesSupported}\n            onFilesAdded={onFilesAdded}\n            onFileUploadComplete={onFileUploadComplete}\n            previewSize={previewSize}/>\n\n    );\n}\n\ninterface StorageUploadProps {\n    internalValue: StorageFieldItem[];\n    setInternalValue: (v: StorageFieldItem[]) => void;\n    name: string;\n    error?: Error;\n    property: ResolvedStringProperty | ResolvedArrayProperty<string[]>;\n    onChange: (value: string | string[] | null) => void;\n    multipleFilesSupported: boolean;\n    autoFocus: boolean;\n    selected: boolean;\n    disabled: boolean;\n    entity: Entity<any>;\n    previewSize: PreviewSize;\n    storage: StorageConfig;\n    onFilesAdded: (acceptedFiles: File[]) => void;\n    storagePathBuilder: (file: File) => string;\n    openPopup?: (cellRect?: DOMRect) => void;\n    onFileUploadComplete: (uploadedPath: string, entry: StorageFieldItem, fileMetadata?: any) => Promise<void>;\n}\n\nfunction StorageUpload({\n                           property,\n                           name,\n                           internalValue,\n                           setInternalValue,\n                           openPopup,\n                           entity,\n                           selected,\n                           error,\n                           onChange,\n                           multipleFilesSupported,\n                           previewSize: previewSizeInput,\n                           disabled,\n                           autoFocus,\n                           storage,\n                           onFilesAdded,\n                           onFileUploadComplete,\n                           storagePathBuilder,\n                       }: StorageUploadProps) {\n\n    const [onHover, setOnHover] = useState(false);\n\n    const previewSize = multipleFilesSupported && previewSizeInput === \"medium\" ? \"small\" : previewSizeInput;\n    if (multipleFilesSupported) {\n        const arrayProperty = property as ResolvedArrayProperty<string[]>;\n        if (Array.isArray(arrayProperty.of)) {\n            throw Error(\"Using array properties instead of single one in `of` in ArrayProperty\");\n        }\n        if (arrayProperty.of) {\n            if (arrayProperty.of.dataType !== \"string\") {\n                throw Error(\"Storage field using array must be of data type string\");\n            }\n        } else {\n            throw Error(\"Storage field using array must be of data type string\");\n        }\n    }\n\n    const metadata: any | undefined = storage?.metadata;\n    const hasValue = Boolean(internalValue);\n\n    const snackbarContext = useSnackbarController();\n\n    const {\n        open,\n        getRootProps,\n        getInputProps,\n        isDragActive,\n        isDragAccept,\n        isDragReject\n    } = useDropzone({\n            accept: storage.acceptedFiles ? storage.acceptedFiles.map(e => ({ [e]: [] })).reduce((a, b) => ({ ...a, ...b }), {}) : undefined,\n            disabled,\n            maxSize: storage.maxSize,\n            noClick: true,\n            noKeyboard: true,\n            onDrop: onFilesAdded,\n            onDropRejected: (fileRejections, event) => {\n                for (const fileRejection of fileRejections) {\n                    for (const error of fileRejection.errors) {\n                        snackbarContext.open({\n                            type: \"error\",\n                            message: `Error uploading file: File is larger than ${storage.maxSize} bytes`\n                        });\n                    }\n                }\n            }\n        }\n    );\n\n    const { ...rootProps } = getRootProps();\n\n    const helpText = multipleFilesSupported\n        ? \"Drag 'n' drop some files here, or click here to edit\"\n        : \"Drag 'n' drop a file here, or click here edit\";\n\n    const renderProperty = multipleFilesSupported\n        ? (property as ResolvedArrayProperty<string[]>).of as ResolvedStringProperty\n        : property as ResolvedStringProperty;\n\n    const imageSize = useMemo(() => getThumbnailMeasure(previewSize), [previewSize]);\n    const showError = !disabled && error;\n\n    return (\n        <div {...rootProps}\n             onMouseEnter={() => setOnHover(true)}\n             onMouseMove={() => setOnHover(true)}\n             onMouseLeave={() => setOnHover(false)}\n             className={cn(dropZoneClasses,\n                 \"relative w-full h-full flex\",\n                 `justify-${hasValue ? \"start\" : \"center\"}`,\n                 isDragActive ? activeDropClasses : \"\",\n                 isDragAccept ? acceptDropClasses : \"\",\n                 isDragReject ? rejectDropClasses : \"\"\n             )}\n        >\n\n            <input autoFocus={autoFocus} {...getInputProps()} />\n\n            {internalValue.map((entry, index) => {\n                let child;\n                if (entry.storagePathOrDownloadUrl) {\n                    child = (\n                        <TableStorageItemPreview\n                            key={`storage_preview_${index}`}\n                            property={renderProperty}\n                            value={entry.storagePathOrDownloadUrl}\n                            entity={entity}\n                            size={previewSize}/>\n                    );\n                } else if (entry.file) {\n                    child = (\n                        <StorageUploadProgress\n                            key={`storage_progress_${index}`}\n                            entry={entry}\n                            metadata={metadata}\n                            storagePath={storagePathBuilder(entry.file)}\n                            onFileUploadComplete={onFileUploadComplete}\n                            imageSize={imageSize}\n                            simple={true}\n                        />\n                    );\n                }\n\n                return child;\n            })\n            }\n\n            {!internalValue && <div\n                className=\"flex-grow m-2 max-w-[200px]\"\n                onClick={open}>\n                <Typography\n                    className=\"text-gray-400 dark:text-gray-600\"\n                    variant={\"body2\"}\n                    align={\"center\"}>\n                    {helpText}\n                </Typography>\n            </div>}\n\n            <EntityTableCellActions\n                showError={showError}\n                disabled={disabled}\n                showExpandIcon={true}\n                selected={selected}\n                openPopup={!disabled ? openPopup : undefined}>\n                <IconButton\n                    color={\"inherit\"}\n                    size={\"small\"}\n                    onClick={open}>\n                    <EditIcon size={\"small\"} className={\"text-gray-500\"}/>\n                </IconButton>\n            </EntityTableCellActions>\n\n        </div>\n    );\n\n}\n\ninterface TableStorageItemPreviewProps {\n    property: ResolvedStringProperty;\n    value: string,\n    size: PreviewSize;\n    entity: Entity<any>;\n}\n\nexport function TableStorageItemPreview({\n                                            property,\n                                            value,\n                                            size,\n                                            entity\n                                        }: TableStorageItemPreviewProps) {\n\n    return (\n        <div\n            className={\"relative p-2 max-w-full\"}\n        >\n\n            {value &&\n                <ErrorBoundary>\n                    <PropertyPreview\n                        propertyKey={\"ignore\"} // TODO: Fix this\n                        value={value}\n                        property={property}\n                        // entity={entity}\n                        size={size}/>\n                </ErrorBoundary>\n            }\n\n        </div>\n    );\n\n}\n","import React, { useCallback, useState } from \"react\";\nimport equal from \"react-fast-compare\"\n\nimport { ReferencePreview } from \"../../../preview\";\nimport { CollectionSize, Entity, EntityCollection, EntityReference, FilterValues } from \"../../../types\";\n\nimport { getPreviewSizeFrom } from \"../../../preview/util\";\nimport { getReferenceFrom } from \"../../../util\";\nimport { useCustomizationController, useNavigationController, useReferenceDialog } from \"../../../hooks\";\nimport { ErrorView } from \"../../ErrorView\";\nimport { Button } from \"@firecms/ui\";\nimport { EntityPreviewContainer } from \"../../EntityPreview\";\n\ntype TableReferenceFieldProps = {\n    name: string;\n    disabled: boolean;\n    internalValue: EntityReference | EntityReference[] | undefined | null;\n    updateValue: (newValue: (EntityReference | EntityReference [] | null)) => void;\n    size: CollectionSize;\n    multiselect: boolean;\n    previewProperties?: string[];\n    title?: string;\n    path: string;\n    forceFilter?: FilterValues<string>;\n};\n\nexport function TableReferenceField(props: TableReferenceFieldProps) {\n    const customizationController = useCustomizationController();\n\n    const navigationController = useNavigationController();\n    const { path } = props;\n    const collection = navigationController.getCollection(path);\n    if (!collection) {\n        if (customizationController.components?.missingReference) {\n            return <customizationController.components.missingReference path={path}/>;\n        } else {\n            throw Error(`Couldn't find the corresponding collection view for the path: ${path}`);\n        }\n    }\n    return <TableReferenceFieldSuccess {...props} collection={collection}/>;\n}\n\nexport const TableReferenceFieldSuccess = React.memo(\n    function TableReferenceFieldSuccess(props: TableReferenceFieldProps & {\n        collection: EntityCollection;\n    }) {\n        const {\n            name,\n            internalValue,\n            updateValue,\n            multiselect,\n            path,\n            size,\n            previewProperties,\n            title,\n            disabled,\n            forceFilter,\n            collection\n        } = props;\n\n        const onSingleEntitySelected = useCallback((entity: Entity<any>) => {\n            updateValue(entity ? getReferenceFrom(entity) : null);\n        }, [updateValue]);\n\n        const onMultipleEntitiesSelected = useCallback((entities: Entity<any>[]) => {\n            updateValue(entities.map((e) => getReferenceFrom(e)));\n        }, [updateValue]);\n\n        const selectedEntityIds = internalValue\n            ? (Array.isArray(internalValue)\n                ? internalValue.map((ref) => ref.id)\n                : internalValue.id ? [internalValue.id] : [])\n            : [];\n\n        const referenceDialogController = useReferenceDialog({\n                multiselect,\n                path,\n                collection,\n                onMultipleEntitiesSelected,\n                onSingleEntitySelected,\n                selectedEntityIds,\n                forceFilter\n            }\n        );\n\n        const handleOpen = useCallback(() => {\n            if (disabled)\n                return;\n            referenceDialogController.open();\n        }, [disabled, referenceDialogController]);\n\n        const valueNotSet = !internalValue || (Array.isArray(internalValue) && internalValue.length === 0);\n\n        const buildSingleReferenceField = () => {\n            if (internalValue && !Array.isArray(internalValue) && internalValue.isEntityReference && internalValue.isEntityReference())\n                return <ReferencePreview\n                    onClick={disabled ? undefined : handleOpen}\n                    size={getPreviewSizeFrom(size)}\n                    reference={internalValue as EntityReference}\n                    hover={!disabled}\n                    disabled={!path}\n                    previewProperties={previewProperties}\n                />;\n            else\n                return <EntityPreviewContainer\n                    onClick={disabled ? undefined : handleOpen}\n                    size={getPreviewSizeFrom(size)}>\n                    <ErrorView title=\"Value is not a reference.\" error={\"Click to edit\"}/>\n                </EntityPreviewContainer>;\n        };\n\n        const buildMultipleReferenceField = () => {\n            if (Array.isArray(internalValue))\n                return <>\n                    {internalValue.map((reference, index) =>\n                        <div className=\"w-full my-0.5\"\n                             key={`preview_array_ref_${name}_${index}`}>\n                            <ReferencePreview\n                                onClick={disabled ? undefined : handleOpen}\n                                size={\"tiny\"}\n                                reference={reference}\n                                hover={!disabled}\n                                disabled={!path}\n                                previewProperties={previewProperties}\n                            />\n                        </div>\n                    )\n                    }\n                </>;\n            else\n                return <ErrorView error={\"Data is not an array of references\"}/>;\n        };\n\n        if (!collection)\n            return <ErrorView error={\"The specified collection does not exist\"}/>;\n\n        return (\n            <div className=\"w-full group\">\n\n                {internalValue && !multiselect && buildSingleReferenceField()}\n\n                {internalValue && multiselect && buildMultipleReferenceField()}\n\n                {valueNotSet &&\n                    <Button\n                        onClick={handleOpen}\n                        size={\"small\"}\n                        variant=\"outlined\"\n                        color=\"primary\">\n                        Edit {title}\n                    </Button>}\n\n            </div>\n        );\n    }, equal);\n","import {\n    CMSType,\n    EntityReference,\n    GeoPoint,\n    ResolvedArrayProperty,\n    ResolvedMapProperty,\n    ResolvedProperties,\n    ResolvedProperty\n} from \"../types\";\nimport * as yup from \"yup\";\nimport { AnySchema, ArraySchema, BooleanSchema, DateSchema, NumberSchema, ObjectSchema, StringSchema } from \"yup\";\nimport { enumToObjectEntries, getValueInPath, hydrateRegExp, isPropertyBuilder } from \"../util\";\n\n// Add custom unique function for array values\ndeclare module \"yup\" {\n    // tslint:disable-next-line\n    interface ArraySchema<T> {\n        uniqueInArray(mapper: (a: T) => T, message: string): ArraySchema<T>;\n    }\n}\nyup.addMethod(yup.array, \"uniqueInArray\", function (\n    mapper = (a: any) => a,\n    message: string\n) {\n    return this.test(\"uniqueInArray\", message, values => {\n        return !values || values.length === new Set(values.map(mapper)).size;\n    });\n});\n\nexport type CustomFieldValidator = (props: {\n    name: string,\n    value: any,\n    property: ResolvedProperty,\n    entityId?: string,\n    parentProperty?: ResolvedMapProperty | ResolvedArrayProperty,\n}) => Promise<boolean>;\n\ninterface PropertyContext<T extends CMSType> {\n    property: ResolvedProperty<T>,\n    parentProperty?: ResolvedMapProperty | ResolvedArrayProperty,\n    entityId: string,\n    customFieldValidator?: CustomFieldValidator,\n    name?: any\n}\n\nexport function getYupEntitySchema<M extends Record<string, any>>(\n    entityId: string,\n    properties: ResolvedProperties<M>,\n    customFieldValidator?: CustomFieldValidator): ObjectSchema<any> {\n    const objectSchema: any = {};\n    Object.entries(properties as Record<string, ResolvedProperty>)\n        .forEach(([name, property]) => {\n            objectSchema[name] = mapPropertyToYup({\n                property: property as ResolvedProperty<any>,\n                customFieldValidator,\n                name,\n                entityId\n            });\n        });\n    return yup.object().shape(objectSchema);\n}\n\nexport function mapPropertyToYup<T extends CMSType>(propertyContext: PropertyContext<T>): AnySchema<unknown> {\n\n    const property = propertyContext.property;\n    if (isPropertyBuilder(property)) {\n        console.error(\"Error in property\", propertyContext);\n        throw Error(\"Trying to create a yup mapping from a property builder. Please use resolved properties only\");\n    }\n\n    if (property.dataType === \"string\") {\n        return getYupStringSchema(propertyContext as PropertyContext<string>);\n    } else if (property.dataType === \"number\") {\n        return getYupNumberSchema(propertyContext as PropertyContext<number>);\n    } else if (property.dataType === \"boolean\") {\n        return getYupBooleanSchema(propertyContext as PropertyContext<boolean>);\n    } else if (property.dataType === \"map\") {\n        return getYupMapObjectSchema(propertyContext as PropertyContext<object>);\n    } else if (property.dataType === \"array\") {\n        return getYupArraySchema(propertyContext as PropertyContext<any[]>);\n    } else if (property.dataType === \"date\") {\n        return getYupDateSchema(propertyContext as PropertyContext<Date>);\n    } else if (property.dataType === \"geopoint\") {\n        return getYupGeoPointSchema(propertyContext as PropertyContext<GeoPoint>);\n    } else if (property.dataType === \"reference\") {\n        return getYupReferenceSchema(propertyContext as PropertyContext<EntityReference>);\n    }\n    console.error(\"Unsupported data type in yup mapping\", property)\n    throw Error(\"Unsupported data type in yup mapping\");\n}\n\nexport function getYupMapObjectSchema({\n                                                                         property,\n                                                                         entityId,\n                                                                         customFieldValidator,\n                                                                         name\n                                                                     }: PropertyContext<Record<string, any>>): ObjectSchema<any> {\n    const objectSchema: any = {};\n    const validation = property.validation;\n    if (property.properties)\n        Object.entries(property.properties).forEach(([childName, childProperty]: [string, ResolvedProperty]) => {\n            objectSchema[childName] = mapPropertyToYup<any>({\n                property: childProperty,\n                parentProperty: property as ResolvedMapProperty,\n                customFieldValidator,\n                name: `${name}[${childName}]`,\n                entityId\n            });\n        });\n\n    const shape = yup.object().shape(objectSchema);\n    if (validation?.required) {\n        return shape.required(validation?.requiredMessage ? validation.requiredMessage : \"Required\").nullable(true);\n    }\n    return shape.nullable(true);\n    // const object: ObjectSchema<any> = yup.object().shape(objectSchema);\n    // return validation?.required\n    //     ? object.required(validation?.requiredMessage ? validation.requiredMessage : \"Required\").nullable(true)\n    //     : yup.object().optional().default(undefined).notRequired().nullable(true).test(\n    //         \"empty-check\",\n    //         \"Optional map can be empty\",\n    //         (o: any, testContext: any) => {\n    //             try {\n    //                 if (!o || Object.keys(o).length === 0) return true;\n    //                 return object.validateSync(o);\n    //             } catch (e) {\n    //                 testContext.createError(e);\n    //                 console.error(e);\n    //                 return false;\n    //             }\n    //         });\n}\n\nfunction getYupStringSchema({\n                                property,\n                                parentProperty,\n                                customFieldValidator,\n                                name,\n                                entityId\n                            }: PropertyContext<string>): StringSchema {\n    let collection: StringSchema<any> = yup.string();\n    const validation = property.validation;\n    if (property.enumValues) {\n        if (validation?.required)\n            collection = collection.required(validation?.requiredMessage ? validation.requiredMessage : \"Required\");\n        const entries = enumToObjectEntries(property.enumValues);\n        collection = collection.oneOf(\n            (validation?.required ? entries : [...entries, null])\n                .map((enumValueConfig) => enumValueConfig?.id ?? null)\n        ).nullable(true);\n    }\n    if (validation) {\n        collection = validation.required\n            ? collection.required(validation?.requiredMessage ? validation.requiredMessage : \"Required\").nullable(true)\n            : collection.notRequired().nullable(true);\n        if (validation.unique && customFieldValidator && name)\n            collection = collection.test(\"unique\", \"This value already exists and should be unique\",\n                (value, context) =>\n                    customFieldValidator({\n                        name,\n                        property,\n                        parentProperty,\n                        value,\n                        entityId\n                    }));\n        if (validation.min || validation.min === 0) collection = collection.min(validation.min, `${property.name} must be min ${validation.min} characters long`);\n        if (validation.max || validation.max === 0) collection = collection.max(validation.max, `${property.name} must be max ${validation.max} characters long`);\n        if (validation.matches) {\n            const regExp = typeof validation.matches === \"string\" ? hydrateRegExp(validation.matches) : validation.matches;\n            if (regExp) {\n                collection = collection.matches(regExp, validation.matchesMessage ? { message: validation.matchesMessage } : undefined)\n            }\n        }\n        if (validation.trim) collection = collection.trim();\n        if (validation.lowercase) collection = collection.lowercase();\n        if (validation.uppercase) collection = collection.uppercase();\n        if (property.email) collection = collection.email(`${property.name} must be an email`);\n        if (property.url) collection = collection.url(`${property.name} must be a url`);\n    } else {\n        collection = collection.notRequired().nullable(true);\n    }\n    return collection;\n}\n\nfunction getYupNumberSchema({\n                                property,\n                                parentProperty,\n                                customFieldValidator,\n                                name,\n                                entityId\n                            }: PropertyContext<number>): NumberSchema {\n    const validation = property.validation;\n    let collection: NumberSchema<any> = yup.number().typeError(\"Must be a number\");\n    if (validation) {\n        collection = validation.required\n            ? collection.required(validation.requiredMessage ? validation.requiredMessage : \"Required\").nullable(true)\n            : collection.notRequired().nullable(true);\n        if (validation.unique && customFieldValidator && name)\n            collection = collection.test(\"unique\",\n                \"This value already exists and should be unique\",\n                (value) => customFieldValidator({\n                    name,\n                    property,\n                    parentProperty,\n                    value,\n                    entityId\n                }));\n        if (validation.min || validation.min === 0) collection = collection.min(validation.min, `${property.name} must be higher or equal to ${validation.min}`);\n        if (validation.max || validation.max === 0) collection = collection.max(validation.max, `${property.name} must be lower or equal to ${validation.max}`);\n        if (validation.lessThan || validation.lessThan === 0) collection = collection.lessThan(validation.lessThan, `${property.name} must be higher than ${validation.lessThan}`);\n        if (validation.moreThan || validation.moreThan === 0) collection = collection.moreThan(validation.moreThan, `${property.name} must be lower than ${validation.moreThan}`);\n        if (validation.positive) collection = collection.positive(`${property.name} must be positive`);\n        if (validation.negative) collection = collection.negative(`${property.name} must be negative`);\n        if (validation.integer) collection = collection.integer(`${property.name} must be an integer`);\n    } else {\n        collection = collection.notRequired().nullable(true);\n    }\n    return collection;\n}\n\nfunction getYupGeoPointSchema({\n                                  property,\n                                  parentProperty,\n                                  customFieldValidator,\n                                  name,\n                                  entityId\n                              }: PropertyContext<GeoPoint>): AnySchema {\n    let collection: ObjectSchema<any> = yup.object();\n    const validation = property.validation;\n    if (validation?.unique && customFieldValidator && name)\n        collection = collection.test(\"unique\",\n            \"This value already exists and should be unique\",\n            (value) => customFieldValidator({\n                name,\n                property,\n                parentProperty,\n                value,\n                entityId\n            }));\n    if (validation?.required) {\n        collection = collection.required(validation.requiredMessage).nullable(true);\n    } else {\n        collection = collection.notRequired().nullable(true);\n    }\n    return collection;\n}\n\nfunction getYupDateSchema({\n                              property,\n                              parentProperty,\n                              customFieldValidator,\n                              name,\n                              entityId\n                          }: PropertyContext<Date>): AnySchema | DateSchema {\n    if (property.autoValue) {\n        return yup.object().nullable();\n    }\n    let collection: DateSchema<any> = yup.date();\n    const validation = property.validation;\n    if (validation) {\n        collection = validation.required\n            ? collection.required(validation?.requiredMessage ? validation.requiredMessage : \"Required\")\n            : collection.notRequired();\n        if (validation.unique && customFieldValidator && name)\n            collection = collection.test(\"unique\",\n                \"This value already exists and should be unique\",\n                (value) => customFieldValidator({\n                    name,\n                    property,\n                    parentProperty,\n                    value,\n                    entityId\n                }));\n        if (validation.min) collection = collection.min(validation.min, `${property.name} must be after ${validation.min}`);\n        if (validation.max) collection = collection.max(validation.max, `${property.name} must be before ${validation.min}`);\n    } else {\n        collection = collection.notRequired();\n    }\n    return collection\n        .transform((v: any) => (v instanceof Date ? v : null))\n        .nullable();\n}\n\nfunction getYupReferenceSchema({\n                                   property,\n                                   parentProperty,\n                                   customFieldValidator,\n                                   name,\n                                   entityId\n                               }: PropertyContext<EntityReference>): AnySchema {\n    let collection: ObjectSchema<any> = yup.object();\n    const validation = property.validation;\n    if (validation) {\n        collection = validation.required\n            ? collection.required(validation?.requiredMessage ? validation.requiredMessage : \"Required\").nullable(true)\n            : collection.notRequired().nullable(true);\n        if (validation.unique && customFieldValidator && name)\n            collection = collection.test(\"unique\",\n                \"This value already exists and should be unique\",\n                (value) => customFieldValidator({\n                    name,\n                    property,\n                    parentProperty,\n                    value,\n                    entityId\n                }));\n    } else {\n        collection = collection.notRequired().nullable(true);\n    }\n    return collection;\n}\n\nfunction getYupBooleanSchema({\n                                 property,\n                                 parentProperty,\n                                 customFieldValidator,\n                                 name,\n                                 entityId\n                             }: PropertyContext<boolean>): BooleanSchema {\n    let collection: BooleanSchema<any> = yup.boolean();\n    const validation = property.validation;\n    if (validation) {\n        collection = validation.required\n            ? collection.required(validation?.requiredMessage ? validation.requiredMessage : \"Required\").nullable(true)\n            : collection.notRequired().nullable(true);\n        if (validation.unique && customFieldValidator && name)\n            collection = collection.test(\"unique\",\n                \"This value already exists and should be unique\",\n                (value) => customFieldValidator({\n                    name,\n                    property,\n                    parentProperty,\n                    value,\n                    entityId\n                }));\n    } else {\n        collection = collection.notRequired().nullable(true);\n    }\n    return collection;\n}\n\nfunction hasUniqueInArrayModifier(property: ResolvedProperty): boolean | [string, ResolvedProperty][] {\n    if (property.validation?.uniqueInArray) {\n        return true;\n    } else if (property.dataType === \"map\" && property.properties) {\n        return Object.entries(property.properties)\n            .filter(([key, childProperty]) => childProperty.validation?.uniqueInArray);\n    }\n    return false;\n}\n\nfunction getYupArraySchema({\n                               property,\n                               parentProperty,\n                               customFieldValidator,\n                               name,\n                               entityId\n                           }: PropertyContext<any[]>): AnySchema<any> {\n\n    let arraySchema: ArraySchema<any> = yup.array();\n\n    if (property.of) {\n        if (Array.isArray(property.of)) {\n            const yupProperties = (property.of as ResolvedProperty[]).map((p, index) => ({\n                [`${name}[${index}]`]: mapPropertyToYup({\n                    property: p as ResolvedProperty<any>,\n                    parentProperty: property,\n                    entityId\n                })\n            })).reduce((a, b) => ({ ...a, ...b }), {});\n            return yup.array().of(\n                yup.mixed().test(\n                    \"Dynamic object validation\",\n                    \"Dynamic object validation error\",\n                    (object, context) => {\n                        const yupProperty = getValueInPath(yupProperties, context.path);\n                        return yupProperty.validate(object);\n                    }\n                )\n            );\n        } else {\n            arraySchema = arraySchema.of(mapPropertyToYup({\n                property: property.of,\n                parentProperty: property,\n                entityId\n            }));\n            const arrayUniqueFields = hasUniqueInArrayModifier(property.of);\n            if (arrayUniqueFields) {\n                if (typeof arrayUniqueFields === \"boolean\") {\n                    arraySchema = arraySchema.uniqueInArray(v => v, `${property.name} should have unique values within the array`);\n                } else if (Array.isArray(arrayUniqueFields)) {\n                    arrayUniqueFields.forEach(([name, childProperty]) => {\n                            arraySchema = arraySchema.uniqueInArray(v => v && v[name], `${property.name} → ${childProperty.name ?? name}: should have unique values within the array`);\n                        }\n                    );\n                }\n            }\n        }\n    }\n    const validation = property.validation;\n\n    if (validation) {\n        arraySchema = validation.required\n            ? arraySchema.required(validation?.requiredMessage ? validation.requiredMessage : \"Required\").nullable(true)\n            : arraySchema.notRequired().nullable(true);\n        if (validation.min || validation.min === 0) arraySchema = arraySchema.min(validation.min, `${property.name} should be min ${validation.min} entries long`);\n        if (validation.max) arraySchema = arraySchema.max(validation.max, `${property.name} should be max ${validation.max} entries long`);\n    } else {\n        arraySchema = arraySchema.notRequired().nullable(true);\n    }\n    return arraySchema;\n}\n","import { VirtualTableSize } from \"./VirtualTableProps\";\n\nexport function getRowHeight(size: VirtualTableSize): number {\n    switch (size) {\n        case \"xl\":\n            return 400;\n        case \"l\":\n            return 280;\n        case \"m\":\n            return 140;\n        case \"s\":\n            return 80;\n        case \"xs\":\n            return 54;\n        default:\n            throw Error(\"Missing mapping for collection size -> height\");\n    }\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport useMeasure from \"react-use-measure\";\n\nimport { VirtualTableSize } from \"../../VirtualTable\";\nimport { getRowHeight } from \"../../VirtualTable/common\";\nimport { cn, RemoveCircleIcon, Tooltip } from \"@firecms/ui\";\nimport { ErrorBoundary } from \"../../../components\";\n\ninterface EntityTableCellProps {\n    children: React.ReactNode;\n    actions?: React.ReactNode;\n    /**\n     * The value is used only to check changes and force re-renders\n     */\n    value?: any;\n    disabled: boolean;\n    saved?: boolean;\n    error?: Error;\n    allowScroll?: boolean;\n    align: \"right\" | \"left\" | \"center\";\n    size: VirtualTableSize;\n    disabledTooltip?: string;\n    width: number;\n    showExpandIcon?: boolean;\n    removePadding?: boolean;\n    fullHeight?: boolean;\n    selected?: boolean;\n    hideOverflow?: boolean;\n    onSelect?: (cellRect: DOMRect | undefined) => void;\n}\n\ntype TableCellInnerProps = {\n    justifyContent: string;\n    scrollable: boolean;\n    faded: boolean;\n    fullHeight: boolean;\n    children: React.ReactNode;\n}\n\nconst TableCellInner = ({\n                            justifyContent,\n                            scrollable,\n                            faded,\n                            fullHeight,\n                            children\n                        }: TableCellInnerProps) => {\n    return (\n        <div\n            className={cn(\"flex flex-col max-h-full w-full\",\n                {\n                    \"items-start\": faded || scrollable\n                })}\n            style={{\n                justifyContent,\n                height: fullHeight ? \"100%\" : undefined,\n                overflow: scrollable ? \"auto\" : undefined,\n                WebkitMaskImage: faded\n                    ? \"linear-gradient(to bottom, black 60%, transparent 100%)\"\n                    : undefined,\n                maskImage: faded\n                    ? \"linear-gradient(to bottom, black 60%, transparent 100%)\"\n                    : undefined\n            }}\n        >\n            {children}\n        </div>\n    );\n};\n\nexport const EntityTableCell = React.memo<EntityTableCellProps>(\n    function EntityTableCell({\n                                 children,\n                                 actions,\n                                 size,\n                                 selected,\n                                 disabled,\n                                 disabledTooltip,\n                                 saved,\n                                 error,\n                                 align,\n                                 allowScroll,\n                                 removePadding,\n                                 fullHeight,\n                                 onSelect,\n                                 width,\n                                 hideOverflow = true,\n                                 showExpandIcon = true\n                             }: EntityTableCellProps) {\n\n        const [measureRef, bounds] = useMeasure();\n        const ref = useRef<HTMLDivElement>(null);\n\n        const maxHeight = useMemo(() => getRowHeight(size), [size]);\n\n        const [onHover, setOnHover] = useState(false);\n        const [internalSaved, setInternalSaved] = useState(saved);\n\n        const showError = !disabled && Boolean(error);\n\n        useEffect(() => {\n            if (saved) {\n                setInternalSaved(true);\n            }\n            const handler = setTimeout(() => {\n                setInternalSaved(false);\n            }, 800);\n            return () => {\n                clearTimeout(handler);\n            };\n        }, [saved]);\n\n        let p = 0;\n        if (!removePadding) {\n            switch (size) {\n                case \"l\":\n                case \"xl\":\n                    p = 4;\n                    break;\n                case \"m\":\n                    p = 2;\n                    break;\n                case \"s\":\n                default:\n                    p = 1;\n                    break;\n            }\n        }\n\n        let justifyContent;\n        switch (align) {\n            case \"right\":\n                justifyContent = \"flex-end\";\n                break;\n            case \"center\":\n                justifyContent = \"center\";\n                break;\n            case \"left\":\n            default:\n                justifyContent = \"flex-start\";\n        }\n\n        // const onClick = useCallback((event: React.MouseEvent<HTMLDivElement>) => {\n        //     if (event.detail === 3) {\n        //         doOpenPopup();\n        //     }\n        // }, [doOpenPopup]);\n\n        const onSelectCallback = useCallback(() => {\n            if (!onSelect) return;\n            const cellRect = ref && ref?.current?.getBoundingClientRect();\n            if (disabled) {\n                onSelect(undefined);\n            } else if (!selected && cellRect) {\n                onSelect(cellRect);\n            }\n        }, [ref, onSelect, selected, disabled]);\n\n        const onFocus = useCallback((event: React.SyntheticEvent<HTMLDivElement>) => {\n            onSelectCallback();\n            event.stopPropagation();\n        }, [onSelectCallback]);\n\n        const isOverflowing = useMemo(() => {\n            if (bounds) {\n                return bounds.height > maxHeight;\n            }\n            return false;\n        }, [bounds, maxHeight]);\n\n        const isSelected = !showError && selected;\n\n        const scrollable = !disabled && allowScroll && isOverflowing;\n        const faded = !disabled && !allowScroll && isOverflowing;\n\n        const setOnHoverTrue = useCallback(() => setOnHover(true), []);\n        const setOnHoverFalse = useCallback(() => setOnHover(false), []);\n\n        const borderClass = showError\n            ? \"border-red-500\"\n            : internalSaved\n                ? \"border-green-500\"\n                : isSelected\n                    ? \"border-primary\"\n                    : \"border-transparent\";\n\n        return (\n            <div\n                className={cn(\n                    \"transition-colors duration-100 ease-in-out\",\n                    `flex relative h-full rounded-md p-${p} border border-4  border-opacity-75`,\n                    onHover && !disabled ? \"bg-gray-50 dark:bg-gray-900\" : \"\",\n                    saved ? \"bg-gray-100 bg-opacity-75 dark:bg-gray-800 dark:bg-opacity-75\" : \"\",\n                    hideOverflow ? \"overflow-hidden\" : \"\",\n                    isSelected ? \"bg-gray-50 dark:bg-gray-900\" : \"\",\n                    borderClass\n                )}\n                ref={ref}\n                style={{\n                    justifyContent,\n                    alignItems: disabled || !isOverflowing ? \"center\" : undefined,\n                    width: width ?? \"100%\",\n                    textAlign: align\n                }}\n                tabIndex={selected || disabled ? undefined : 0}\n                onFocus={onFocus}\n                // onClick={onClick}\n                onMouseEnter={setOnHoverTrue}\n                onMouseMove={setOnHoverTrue}\n                onMouseLeave={setOnHoverFalse}\n                // contain={scrollable ? \"content\" : \"size\"}\n            >\n\n                <ErrorBoundary>\n\n                    {fullHeight && !faded && children}\n\n                    {(!fullHeight || faded) && <TableCellInner\n                        fullHeight={fullHeight ?? false}\n                        justifyContent={justifyContent}\n                        scrollable={scrollable ?? false}\n                        faded={faded}>\n\n                        {!fullHeight && <div ref={measureRef}\n                                             style={{\n                                                 display: \"flex\",\n                                                 width: \"100%\",\n                                                 justifyContent,\n                                                 height: fullHeight ? \"100%\" : undefined\n                                             }}>\n                            {children}\n                        </div>}\n\n                    </TableCellInner>}\n                </ErrorBoundary>\n\n                {actions}\n\n                {disabled && onHover && disabledTooltip &&\n                    <div className=\"absolute top-1 right-1 text-xs\">\n                        <Tooltip title={disabledTooltip}>\n                            <RemoveCircleIcon size={\"smallest\"} color={\"disabled\"} className={\"text-gray-500\"}/>\n                        </Tooltip>\n                    </div>}\n\n            </div>\n        );\n    }, (a, b) => {\n        return a.error === b.error &&\n            a.value === b.value &&\n            a.disabled === b.disabled &&\n            a.saved === b.saved &&\n            a.allowScroll === b.allowScroll &&\n            a.align === b.align &&\n            a.size === b.size &&\n            a.disabledTooltip === b.disabledTooltip &&\n            a.width === b.width &&\n            a.showExpandIcon === b.showExpandIcon &&\n            a.removePadding === b.removePadding &&\n            a.fullHeight === b.fullHeight &&\n            a.selected === b.selected;\n    }) as React.FunctionComponent<EntityTableCellProps>;\n","import React, { useContext } from \"react\";\nimport { EntityCollectionTableController } from \"../common/types\";\n\nexport const SelectableTableContext = React.createContext<EntityCollectionTableController<any>>({} as any);\n\nexport const useSelectableTableController = () => useContext<EntityCollectionTableController<any>>(SelectableTableContext);\n","import { useEffect, useRef } from \"react\";\nimport { CMSType, ResolvedProperty } from \"../types\";\n\n/**\n * Hook we use to restore a value after it has been cleared\n * @param property\n * @param value\n * @param setValue\n * @ignore\n */\nexport function useClearRestoreValue<T extends CMSType>({\n                                                            property,\n                                                            value,\n                                                            setValue\n                                                        }:\n                                                            {\n                                                                property: ResolvedProperty<T>,\n                                                                value: T,\n                                                                setValue: (value: T | null, shouldValidate?: boolean) => void\n                                                            }) {\n\n    const clearedValueRef = useRef<T | null>(null);\n    useEffect(() => {\n        const shouldClearValueIfDisabled = typeof property.disabled === \"object\" && Boolean(property.disabled.clearOnDisabled);\n        if (shouldClearValueIfDisabled) {\n            if (value != null) {\n                clearedValueRef.current = value;\n                setValue(null);\n            }\n        } else if (clearedValueRef.current) {\n            setValue(clearedValueRef.current);\n            clearedValueRef.current = null;\n        }\n    }, [property]);\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport equal from \"react-fast-compare\"\nimport {\n    CMSType,\n    Entity,\n    EntityReference,\n    ResolvedArrayProperty,\n    ResolvedNumberProperty,\n    ResolvedProperty,\n    ResolvedStringProperty\n} from \"../../types\";\n\nimport { VirtualTableInput } from \"../VirtualTable/fields/VirtualTableInput\";\nimport { VirtualTableSelect } from \"../VirtualTable/fields/VirtualTableSelect\";\nimport { VirtualTableNumberInput } from \"../VirtualTable/fields/VirtualTableNumberInput\";\nimport { VirtualTableSwitch } from \"../VirtualTable/fields/VirtualTableSwitch\";\nimport { VirtualTableDateField } from \"../VirtualTable/fields/VirtualTableDateField\";\n\nimport { TableStorageUpload } from \"./fields/TableStorageUpload\";\nimport { TableReferenceField } from \"./fields/TableReferenceField\";\n\nimport { PropertyPreview } from \"../../preview\";\nimport { getPreviewSizeFrom } from \"../../preview/util\";\nimport { isReadOnly } from \"../../util\";\n\nimport { CustomFieldValidator, mapPropertyToYup } from \"../../form/validation\";\nimport { useFireCMSContext } from \"../../hooks\";\n\nimport { EntityTableCell } from \"./internal/EntityTableCell\";\nimport { EntityTableCellActions } from \"./internal/EntityTableCellActions\";\n\nimport { getRowHeight } from \"../VirtualTable/common\";\nimport { useSelectableTableController } from \"../SelectableTable/SelectableTableContext\";\nimport { useClearRestoreValue } from \"../../form/useClearRestoreValue\";\n\nexport interface PropertyTableCellProps<T extends CMSType> {\n    propertyKey: string;\n    columnIndex: number;\n    align: \"right\" | \"left\" | \"center\";\n    customFieldValidator?: CustomFieldValidator;\n    value: T;\n    readonly: boolean;\n    property: ResolvedProperty<T>;\n    height: number;\n    width: number;\n    entity: Entity<any>;\n    path: string;\n    disabled: boolean;\n    enablePopupIcon?: boolean;\n}\n\nfunction isStorageProperty(property: ResolvedProperty) {\n    if (property.dataType === \"string\" && (property as ResolvedStringProperty).storage)\n        return true;\n    if (property.dataType === \"array\") {\n        if (Array.isArray(property.of)) {\n            return false;\n        } else {\n            return ((property as ResolvedArrayProperty).of as ResolvedProperty)?.dataType === \"string\" &&\n                ((property as ResolvedArrayProperty).of as ResolvedStringProperty)?.storage\n        }\n    }\n    return false;\n}\n\nexport const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(\n    function PropertyTableCell<T extends CMSType, M extends Record<string, any>>({\n                                                                                     propertyKey,\n                                                                                     customFieldValidator,\n                                                                                     value,\n                                                                                     property,\n                                                                                     align,\n                                                                                     width,\n                                                                                     height,\n                                                                                     path,\n                                                                                     entity,\n                                                                                     readonly,\n                                                                                     disabled: disabledProp,\n                                                                                     enablePopupIcon = true\n                                                                                 }: PropertyTableCellProps<T>) {\n\n        const {\n            onValueChange,\n            size,\n            selectedCell,\n            select,\n            setPopupCell\n        } = useSelectableTableController();\n\n        const selected = selectedCell?.propertyKey === propertyKey &&\n            selectedCell?.entity.path === entity.path &&\n            selectedCell?.entity.id === entity.id;\n\n        const [internalValue, setInternalValue] = useState<any | null>(value);\n        const internalValueRef = useRef(value);\n\n        const [error, setError] = useState<Error | undefined>();\n        const [validationError, setValidationError] = useState<Error | undefined>();\n        const [saved, setSaved] = useState<boolean>(false);\n\n        const onValueUpdated = useCallback(() => {\n            setSaved(true)\n            setTimeout(() => {\n                setSaved(false);\n            }, 100);\n        }, []);\n\n        const customField = Boolean(property.Field);\n        const customPreview = Boolean(property.Preview);\n        const readOnlyProperty = isReadOnly(property);\n        const disabledTooltip: string | undefined = typeof property.disabled === \"object\" ? property.disabled.disabledMessage : undefined;\n        const disabled = readonly || disabledProp || Boolean(property.disabled);\n\n        const validation = useMemo(() => mapPropertyToYup({\n            property,\n            entityId: entity.id,\n            customFieldValidator,\n            name: propertyKey\n        }), [entity.id, property, propertyKey]);\n\n        useEffect(\n            () => {\n                if (!equal(value, internalValueRef.current)) {\n                    setValidationError(undefined);\n                    setInternalValue(value);\n                    internalValueRef.current = value;\n                    onValueUpdated();\n                }\n            },\n            [onValueUpdated, value]\n        );\n\n        const saveValues = (value: any) => {\n            if (equal(value, internalValueRef.current))\n                return;\n            setSaved(false);\n            validation\n                .validate(value)\n                .then(() => {\n                    setValidationError(undefined);\n                    internalValueRef.current = value;\n                    if (onValueChange) {\n                        try {\n                            onValueChange({\n                                value,\n                                propertyKey,\n                                setError,\n                                onValueUpdated,\n                                data: entity,\n                            });\n                        } catch (e:any) {\n                            console.error(\"onValueChange error\", e);\n                            setError(e);\n                        }\n\n                    }\n                })\n                .catch((e) => {\n                    setValidationError(e);\n                });\n        };\n\n        useEffect(() => {\n            validation\n                .validate(internalValue)\n                .then(() => setValidationError(undefined))\n                .catch(setValidationError);\n        }, [internalValue, validation, propertyKey, property, entity]);\n\n        const updateValue = (newValue: any | null) => {\n\n            let updatedValue: any;\n            if (newValue === undefined) {\n                updatedValue = null;\n            } else {\n                updatedValue = newValue;\n            }\n            setInternalValue(updatedValue);\n            saveValues(updatedValue);\n        };\n\n        useClearRestoreValue<any>({\n            property,\n            value: internalValue,\n            setValue: updateValue\n        });\n\n        const onSelect = useCallback((cellRect: DOMRect | undefined) => {\n            if (!cellRect) {\n                select(undefined);\n            } else {\n                select({\n                    width,\n                    height,\n                    entity,\n                    cellRect,\n                    propertyKey: propertyKey as Extract<keyof M, string>\n                });\n            }\n        }, [entity, height, propertyKey, select, width]);\n\n        const openPopup = (cellRect: DOMRect | undefined) => {\n            if (!setPopupCell)\n                return;\n            if (!cellRect) {\n                setPopupCell(undefined);\n            } else {\n                setPopupCell({\n                    width,\n                    height,\n                    entity,\n                    cellRect,\n                    propertyKey: propertyKey as Extract<keyof M, string>\n                });\n            }\n        };\n\n        let innerComponent: React.ReactNode | undefined;\n        let allowScroll = false;\n        let showExpandIcon = false;\n        let hideOverflow = true;\n        let removePadding = false;\n        let fullHeight = false;\n        let includeActions = true;\n        const showError = !disabled && error;\n\n        if (readonly || readOnlyProperty) {\n            return <EntityTableCell\n                size={size}\n                width={width}\n                saved={saved}\n                key={`${propertyKey}_${entity.path}_${entity.id}`}\n                value={internalValue}\n                align={align ?? \"left\"}\n                fullHeight={false}\n                disabledTooltip={disabledTooltip ?? (readOnlyProperty ? \"Read only\" : undefined)}\n                disabled={true}>\n                <PropertyPreview\n                    width={width}\n                    height={getRowHeight(size)}\n                    propertyKey={propertyKey}\n                    property={property}\n                    value={internalValue}\n                    size={getPreviewSizeFrom(size)}\n                />\n            </EntityTableCell>;\n        }\n\n        if (!customField && (!customPreview || selected)) {\n            const isAStorageProperty = isStorageProperty(property);\n            if (isAStorageProperty) {\n                innerComponent = <TableStorageUpload error={validationError ?? error}\n                                                     disabled={disabled}\n                                                     focused={selected}\n                                                     selected={selected}\n                                                     openPopup={setPopupCell ? openPopup : undefined}\n                                                     property={property as ResolvedStringProperty | ResolvedArrayProperty<string[]>}\n                                                     entity={entity}\n                                                     path={path}\n                                                     value={internalValue}\n                                                     previewSize={getPreviewSizeFrom(size)}\n                                                     updateValue={updateValue}\n                                                     propertyKey={propertyKey as string}\n                />;\n                includeActions = false;\n                showExpandIcon = true;\n                fullHeight = true;\n                removePadding = true;\n            } else if (selected && property.dataType === \"number\") {\n                const numberProperty = property as ResolvedNumberProperty;\n                if (numberProperty.enumValues) {\n                    innerComponent = <VirtualTableSelect name={propertyKey as string}\n                                                         multiple={false}\n                                                         disabled={disabled}\n                                                         focused={selected}\n                                                         valueType={\"number\"}\n                                                         small={getPreviewSizeFrom(size) !== \"medium\"}\n                                                         enumValues={numberProperty.enumValues}\n                                                         error={validationError ?? error}\n                                                         internalValue={internalValue as string | number}\n                                                         updateValue={updateValue}\n                    />;\n                    fullHeight = true;\n                } else {\n                    innerComponent = <VirtualTableNumberInput\n                        align={align}\n                        error={validationError ?? error}\n                        focused={selected}\n                        disabled={disabled}\n                        value={internalValue as number}\n                        updateValue={updateValue}\n                    />;\n                    allowScroll = true;\n                }\n            } else if (selected && property.dataType === \"string\") {\n                const stringProperty = property as ResolvedStringProperty;\n                if (stringProperty.enumValues) {\n                    innerComponent = <VirtualTableSelect name={propertyKey as string}\n                                                         multiple={false}\n                                                         focused={selected}\n                                                         disabled={disabled}\n                                                         valueType={\"string\"}\n                                                         small={getPreviewSizeFrom(size) !== \"medium\"}\n                                                         enumValues={stringProperty.enumValues}\n                                                         error={validationError ?? error}\n                                                         internalValue={internalValue as string | number}\n                                                         updateValue={updateValue}\n                    />;\n                    fullHeight = true;\n                } else if (!stringProperty.storage) {\n                    const multiline = Boolean(stringProperty.multiline) || Boolean(stringProperty.markdown);\n                    innerComponent = <VirtualTableInput error={validationError ?? error}\n                                                        disabled={disabled}\n                                                        multiline={multiline}\n                                                        focused={selected}\n                                                        value={internalValue as string}\n                                                        updateValue={updateValue}\n                    />;\n                    allowScroll = true;\n                }\n            } else if (property.dataType === \"boolean\") {\n                innerComponent = <VirtualTableSwitch error={validationError ?? error}\n                                                     disabled={disabled}\n                                                     focused={selected}\n                                                     internalValue={internalValue as boolean}\n                                                     updateValue={updateValue}\n                />;\n            } else if (property.dataType === \"date\") {\n                innerComponent = <VirtualTableDateField name={propertyKey as string}\n                                                        error={validationError ?? error}\n                                                        disabled={disabled}\n                                                        mode={property.mode}\n                                                        focused={selected}\n                                                        internalValue={internalValue as Date}\n                                                        updateValue={updateValue}\n                />;\n                fullHeight = true;\n                hideOverflow = false;\n                allowScroll = false;\n            } else if (property.dataType === \"reference\") {\n                if (typeof property.path === \"string\") {\n                    innerComponent =\n                        <TableReferenceField name={propertyKey as string}\n                                             internalValue={internalValue as EntityReference}\n                                             updateValue={updateValue}\n                                             disabled={disabled}\n                                             size={size}\n                                             path={property.path}\n                                             multiselect={false}\n                                             previewProperties={property.previewProperties}\n                                             title={property.name}\n                                             forceFilter={property.forceFilter}\n                        />;\n                }\n                allowScroll = false;\n            } else if (property.dataType === \"array\") {\n                const arrayProperty = (property as ResolvedArrayProperty);\n\n                if (!arrayProperty.of && !arrayProperty.oneOf) {\n                    throw Error(`You need to specify an 'of' or 'oneOf' prop (or specify a custom field) in your array property ${propertyKey}`);\n                }\n                if (arrayProperty.of && !Array.isArray(arrayProperty.of)) {\n                    if (arrayProperty.of.dataType === \"string\" || arrayProperty.of.dataType === \"number\") {\n                        if (selected && arrayProperty.of.enumValues) {\n                            innerComponent =\n                                <VirtualTableSelect name={propertyKey as string}\n                                                    multiple={true}\n                                                    disabled={disabled}\n                                                    focused={selected}\n                                                    small={getPreviewSizeFrom(size) !== \"medium\"}\n                                                    valueType={arrayProperty.of.dataType}\n                                                    enumValues={arrayProperty.of.enumValues}\n                                                    error={validationError ?? error}\n                                                    internalValue={internalValue as string | number}\n                                                    updateValue={updateValue}\n                                />;\n                            allowScroll = true;\n                            fullHeight = true;\n                            hideOverflow = false;\n                        }\n                    } else if (arrayProperty.of.dataType === \"reference\") {\n                        if (typeof arrayProperty.of.path === \"string\") {\n                            innerComponent =\n                                <TableReferenceField\n                                    name={propertyKey as string}\n                                    disabled={disabled}\n                                    internalValue={internalValue as EntityReference[]}\n                                    updateValue={updateValue}\n                                    size={size}\n                                    multiselect={true}\n                                    path={arrayProperty.of.path}\n                                    previewProperties={arrayProperty.of.previewProperties}\n                                    title={arrayProperty.name}\n                                    forceFilter={arrayProperty.of.forceFilter}\n                                />;\n                        }\n                        allowScroll = false;\n                    }\n                }\n\n            }\n        }\n\n        if (!innerComponent) {\n            allowScroll = false;\n            showExpandIcon = enablePopupIcon && selected && !innerComponent && !disabled && !readOnlyProperty;\n            innerComponent = (\n                <PropertyPreview width={width}\n                                 height={height}\n                                 propertyKey={propertyKey as string}\n                                 value={internalValue}\n                                 property={property}\n                                 size={getPreviewSizeFrom(size)}\n                />\n            );\n        }\n\n        return (\n            <EntityTableCell\n                key={`cell_${propertyKey}_${entity.path}_${entity.id}`}\n                size={size}\n                width={width}\n                onSelect={onSelect}\n                selected={selected}\n                disabled={disabled || readOnlyProperty}\n                disabledTooltip={disabledTooltip ?? \"Disabled\"}\n                removePadding={removePadding}\n                fullHeight={fullHeight}\n                saved={saved}\n                error={validationError ?? error}\n                align={align}\n                allowScroll={allowScroll}\n                showExpandIcon={showExpandIcon}\n                value={internalValue}\n                hideOverflow={hideOverflow}\n                actions={includeActions && <EntityTableCellActions\n                    showError={showError}\n                    disabled={disabled}\n                    showExpandIcon={showExpandIcon}\n                    selected={selected}\n                    openPopup={!disabled ? openPopup : undefined}/>}\n            >\n\n                {innerComponent}\n\n            </EntityTableCell>\n        );\n\n    },\n    areEqual) as React.FunctionComponent<PropertyTableCellProps<any>>;\n\nfunction areEqual(prevProps: PropertyTableCellProps<any>, nextProps: PropertyTableCellProps<any>) {\n    return prevProps.height === nextProps.height &&\n        prevProps.propertyKey === nextProps.propertyKey &&\n        prevProps.align === nextProps.align &&\n        prevProps.width === nextProps.width &&\n        equal(prevProps.property, nextProps.property) &&\n        equal(prevProps.value, nextProps.value) &&\n        equal(prevProps.entity.id, nextProps.entity.id) &&\n        equal(prevProps.entity.values, nextProps.entity.values)\n        ;\n}\n","import React, { MouseEvent, useCallback } from \"react\";\n\nimport { CollectionSize, Entity, EntityAction, EntityCollection, SelectionController } from \"../../types\";\nimport { Checkbox, cn, IconButton, Menu, MenuItem, MoreVertIcon, Skeleton, Tooltip, Typography } from \"@firecms/ui\";\nimport { useFireCMSContext, useLargeLayout } from \"../../hooks\";\n\n/**\n *\n * @param entity\n * @param width\n * @param frozen\n * @param isSelected\n * @param selectionEnabled\n * @param size\n * @param toggleEntitySelection\n * @param hideId\n * @constructor\n *\n * @group Collection components\n */\nexport const EntityCollectionRowActions = function EntityCollectionRowActions({\n                                                                                  entity,\n                                                                                  collection,\n                                                                                  fullPath,\n                                                                                  width,\n                                                                                  frozen,\n                                                                                  isSelected,\n                                                                                  selectionEnabled,\n                                                                                  size,\n                                                                                  highlightEntity,\n                                                                                  onCollectionChange,\n                                                                                  unhighlightEntity,\n                                                                                  actions = [],\n                                                                                  hideId,\n                                                                                  selectionController,\n                                                                              }:\n                                                                                  {\n                                                                                      entity: Entity<any>,\n                                                                                      collection?: EntityCollection<any>,\n                                                                                      fullPath?: string,\n                                                                                      width: number,\n                                                                                      frozen?: boolean,\n                                                                                      size: CollectionSize,\n                                                                                      isSelected?: boolean,\n                                                                                      selectionEnabled?: boolean,\n                                                                                      actions?: EntityAction[],\n                                                                                      hideId?: boolean,\n                                                                                      onCollectionChange?: () => void,\n                                                                                      selectionController?: SelectionController;\n                                                                                      highlightEntity?: (entity: Entity<any>) => void;\n                                                                                      unhighlightEntity?: (entity: Entity<any>) => void;\n                                                                                  }) {\n\n    const largeLayout = useLargeLayout();\n\n    const context = useFireCMSContext();\n\n    const onCheckedChange = useCallback((checked: boolean) => {\n        selectionController?.toggleEntitySelection(entity);\n    }, [entity, selectionController?.toggleEntitySelection]);\n\n    const onClick = useCallback((event: MouseEvent) => {\n        event.stopPropagation();\n        selectionController?.toggleEntitySelection(entity);\n    }, [entity, selectionController?.toggleEntitySelection]);\n\n    const hasActions = actions.length > 0;\n    const hasCollapsedActions = actions.some(a => a.collapsed || a.collapsed === undefined);\n\n    const collapsedActions = actions.filter(a => a.collapsed || a.collapsed === undefined);\n    const uncollapsedActions = actions.filter(a => a.collapsed === false);\n    return (\n        <div\n            onClick={onClick}\n            className={cn(\n                \"h-full flex items-center justify-center flex-col bg-gray-50 dark:bg-gray-900 bg-opacity-90 dark:bg-opacity-90 z-10\",\n                frozen ? \"sticky left-0\" : \"\"\n            )}\n            style={{\n                width,\n                position: frozen ? \"sticky\" : \"initial\",\n                left: frozen ? 0 : \"initial\",\n                contain: \"strict\"\n            }}>\n\n            {(hasActions || selectionEnabled) &&\n                <div className=\"w-34 flex justify-center\">\n\n                    {uncollapsedActions.map((action, index) => (\n                        <Tooltip key={index} title={action.name}>\n                            <IconButton\n                                onClick={(event: MouseEvent) => {\n                                    event.stopPropagation();\n                                    action.onClick({\n                                        entity,\n                                        fullPath,\n                                        collection,\n                                        context,\n                                        selectionController,\n                                        highlightEntity,\n                                        unhighlightEntity,\n                                        onCollectionChange,\n                                    });\n                                }}\n                                size={largeLayout ? \"medium\" : \"small\"}>\n                                {action.icon}\n                            </IconButton>\n                        </Tooltip>\n                    ))}\n\n                    {hasCollapsedActions &&\n                        <Menu\n                            trigger={<IconButton\n                                size={largeLayout ? \"medium\" : \"small\"}>\n                                <MoreVertIcon/>\n                            </IconButton>}>\n                            {collapsedActions.map((action, index) => (\n                                <MenuItem\n                                    key={index}\n                                    onClick={(e) => {\n                                        e.stopPropagation();\n                                        action.onClick({\n                                            entity,\n                                            fullPath,\n                                            collection,\n                                            context,\n                                            selectionController,\n                                            highlightEntity,\n                                            unhighlightEntity,\n                                            onCollectionChange,\n                                        });\n                                    }}>\n                                    {action.icon}\n                                    {action.name}\n                                </MenuItem>\n                            ))}\n                        </Menu>\n                    }\n\n                    {selectionEnabled &&\n                        <Tooltip title={`Select ${entity.id}`}>\n                            <Checkbox\n                                size={largeLayout ? \"medium\" : \"small\"}\n                                checked={Boolean(isSelected)}\n                                onCheckedChange={onCheckedChange}\n                            />\n                        </Tooltip>}\n\n                </div>}\n\n            {!hideId && size !== \"xs\" && (\n                <div className=\"w-[138px] text-center overflow-hidden truncate\">\n\n                    {entity\n                        ? <Typography\n                            onClick={(event) => {\n                                event.stopPropagation();\n                            }}\n                            className={\"font-mono select-all\"}\n                            variant={\"caption\"}\n                            color={\"secondary\"}> {entity.id} </Typography>\n                        : <Skeleton/>\n                    }\n                </div>\n            )}\n\n        </div>\n    );\n\n};\n","import React, { useEffect } from \"react\";\n\nimport {\n    Button,\n    CircularProgress,\n    cn,\n    defaultBorderMixin,\n    FilterListOffIcon,\n    SearchBar,\n    Select,\n    SelectItem,\n    Tooltip\n} from \"@firecms/ui\";\nimport { CollectionSize } from \"../../../types\";\nimport { useLargeLayout } from \"../../../hooks\";\n\ninterface CollectionTableToolbarProps {\n    size: CollectionSize;\n    loading: boolean;\n    actionsStart?: React.ReactNode;\n    actions?: React.ReactNode;\n    title?: React.ReactNode,\n    onTextSearchClick?: () => void;\n    onTextSearch?: (searchString?: string) => void;\n    onSizeChanged: (size: CollectionSize) => void;\n    textSearchLoading?: boolean;\n}\n\nexport function CollectionTableToolbar({\n                                           actions,\n                                           actionsStart,\n                                           loading,\n                                           onSizeChanged,\n                                           onTextSearch,\n                                           onTextSearchClick,\n                                           size,\n                                           textSearchLoading,\n                                           title\n                                       }: CollectionTableToolbarProps) {\n\n    const searchInputRef = React.useRef<HTMLInputElement>(null);\n    const largeLayout = useLargeLayout();\n\n    const searchLoading = React.useRef<boolean>(false);\n\n    useEffect(() => {\n        if (searchInputRef.current && searchLoading.current && !textSearchLoading) {\n            searchInputRef.current.focus();\n        }\n        searchLoading.current = textSearchLoading ?? false;\n    }, [textSearchLoading]);\n\n\n    const sizeSelect = (\n        <Tooltip title={\"Table row size\"} side={\"right\"} sideOffset={4}>\n            <Select\n                value={size as string}\n                className=\"w-16 h-10\"\n                size={\"small\"}\n                onValueChange={(v) => onSizeChanged(v as CollectionSize)}\n                renderValue={(v) => <div className={\"font-medium\"}>{v.toUpperCase()}</div>}\n            >\n                {[\"xs\", \"s\", \"m\", \"l\", \"xl\"].map((size) => (\n                    <SelectItem key={size} value={size} className={\"w-12 font-medium text-center\"}>\n                        {size.toUpperCase()}\n                    </SelectItem>\n                ))}\n            </Select>\n        </Tooltip>\n    );\n\n    return (\n        <div\n            className={cn(defaultBorderMixin, \"no-scrollbar min-h-[56px] overflow-x-auto px-2 md:px-4 bg-gray-50 dark:bg-gray-900 border-b flex flex-row justify-between items-center w-full\")}>\n\n            <div className=\"flex items-center gap-2 md:mr-4 mr-2\">\n\n                {title && <div className={\"hidden lg:block\"}>\n                    {title}\n                </div>}\n\n                {sizeSelect}\n\n                {actionsStart}\n\n            </div>\n\n            <div className=\"flex items-center gap-2\">\n\n                {largeLayout && <div className=\"w-[22px]\">\n                    {loading &&\n                        <CircularProgress size={\"small\"}/>}\n                </div>}\n\n                {(onTextSearch || onTextSearchClick) &&\n                    <SearchBar\n                        key={\"search-bar\"}\n                        inputRef={searchInputRef}\n                        loading={textSearchLoading}\n                        disabled={Boolean(onTextSearchClick)}\n                        onClick={onTextSearchClick}\n                        onTextSearch={onTextSearchClick ? undefined : onTextSearch}\n                        expandable={true}/>}\n\n                {actions}\n\n            </div>\n\n        </div>\n    );\n}\n","import { EntityCollection, Property, ResolvedArrayProperty, ResolvedProperty } from \"../../../types\";\n\nexport function getTableCellAlignment(property: Property | ResolvedProperty): \"right\" | \"left\" | \"center\" {\n    if (property.dataType === \"boolean\") {\n        return \"center\";\n    } else if (property.dataType === \"number\") {\n        if (property.enumValues)\n            return \"left\";\n        return \"right\";\n    } else if (property.dataType === \"date\") {\n        return \"right\";\n    } else {\n        return \"left\";\n    }\n}\n\nexport function getTablePropertyColumnWidth(property: ResolvedProperty): number {\n\n    if (property.columnWidth) {\n        return property.columnWidth;\n    }\n\n    if (property.dataType === \"string\") {\n        if (property.url) {\n            return 280;\n        } else if (property.storage) {\n            return 160;\n        } else if (property.enumValues) {\n            return 200;\n        } else if (property.multiline) {\n            return 300;\n        } else if (property.markdown) {\n            return 300;\n        } else if (property.email) {\n            return 200;\n        } else {\n            return 200;\n        }\n    } else if (property.dataType === \"array\") {\n        const arrayProperty = property as ResolvedArrayProperty;\n        if (arrayProperty.of) {\n            if (Array.isArray(property.of)) {\n                return 300;\n            } else {\n                return getTablePropertyColumnWidth(arrayProperty.of as ResolvedProperty);\n            }\n        } else {\n            return 300;\n        }\n    } else if (property.dataType === \"number\") {\n        if (property.enumValues) {\n            return 200;\n        }\n        return 140;\n    } else if (property.dataType === \"map\") {\n        return 360;\n    } else if (property.dataType === \"date\") {\n        return 200;\n    } else if (property.dataType === \"reference\") {\n        return 220;\n    } else if (property.dataType === \"boolean\") {\n        return 140;\n    } else {\n        return 200;\n    }\n}\n\nexport function getSubcollectionColumnId(collection: EntityCollection) {\n    return `subcollection:${collection.id ?? collection.path}`;\n}\n","import { useMemo } from \"react\";\nimport { EntityCollection, ResolvedEntityCollection, ResolvedProperty } from \"../../types\";\nimport { getSubcollectionColumnId } from \"../EntityCollectionTable/internal/common\";\nimport { PropertyColumnConfig } from \"../EntityCollectionTable/EntityCollectionTableProps\";\n\nconst COLLECTION_GROUP_PARENT_ID = \"collectionGroupParent\";\n\nexport function useColumnIds<M extends Record<string, any>>(collection: ResolvedEntityCollection<M>, includeSubcollections: boolean): PropertyColumnConfig[] {\n    return useMemo(() => {\n        if (collection.propertiesOrder) {\n            const propertyColumnConfigs = hideAndExpandKeys(collection, collection.propertiesOrder);\n            if (collection.collectionGroup) {\n                propertyColumnConfigs.push({\n                    key: COLLECTION_GROUP_PARENT_ID,\n                    disabled: true\n                });\n            }\n            return propertyColumnConfigs;\n        }\n        return getDefaultColumnKeys(collection, includeSubcollections);\n    }, [collection, includeSubcollections]);\n}\n\nfunction hideAndExpandKeys<M extends Record<string, any>>(collection: ResolvedEntityCollection<M>, keys: string[]): PropertyColumnConfig[] {\n\n    return keys.flatMap((key) => {\n        const property = collection.properties[key];\n        if (property) {\n            if (property.hideFromCollection)\n                return [null];\n            if (property.disabled && typeof property.disabled === \"object\" && property.disabled.hidden)\n                return [null];\n            if (property.dataType === \"map\" && property.spreadChildren && property.properties) {\n                return getColumnKeysForProperty(property, key);\n            }\n            return [{\n                key,\n                disabled: Boolean(property.disabled) || Boolean(property.readOnly)\n            }];\n        }\n\n        const additionalField = collection.additionalFields?.find(field => field.key === key);\n        if (additionalField) {\n            return [{\n                key,\n                disabled: true\n            }];\n        }\n\n        if (collection.subcollections) {\n            const subCollection = collection.subcollections.find(subCol => getSubcollectionColumnId(subCol) === key);\n            if (subCollection) {\n                return [{\n                    key,\n                    disabled: true\n                }];\n            }\n        }\n\n        if (collection.collectionGroup && key === COLLECTION_GROUP_PARENT_ID) {\n            return [{\n                key,\n                disabled: true\n            }];\n        }\n\n        return [null];\n    }).filter(Boolean) as PropertyColumnConfig[];\n}\n\nfunction getDefaultColumnKeys<M extends Record<string, any> = any>(collection: ResolvedEntityCollection<M>, includeSubCollections: boolean) {\n    const propertyKeys = Object.keys(collection.properties);\n\n    const additionalFields = collection.additionalFields ?? [];\n    const subCollections: EntityCollection[] = collection.subcollections ?? [];\n\n    const columnIds: string[] = [\n        ...propertyKeys,\n        ...additionalFields.map((field) => field.key)\n    ];\n\n    if (includeSubCollections) {\n        const subCollectionIds = subCollections\n            .map((collection) => getSubcollectionColumnId(collection));\n        columnIds.push(...subCollectionIds.filter((subColId) => !columnIds.includes(subColId)));\n    }\n\n    if (collection.collectionGroup) {\n        columnIds.push(COLLECTION_GROUP_PARENT_ID);\n    }\n\n    return hideAndExpandKeys(collection, columnIds);\n}\n\nexport function getColumnKeysForProperty(property: ResolvedProperty, key: string, disabled?: boolean): PropertyColumnConfig[] {\n    if (property.dataType === \"map\" && property.spreadChildren && property.properties) {\n        return Object.entries(property.properties)\n            .flatMap(([childKey, childProperty]) => getColumnKeysForProperty(\n                childProperty,\n                `${key}.${childKey}`,\n                disabled || Boolean(property.disabled) || Boolean(property.readOnly))\n            );\n    }\n    return [{\n        key,\n        disabled: disabled || Boolean(property.disabled) || Boolean(property.readOnly)\n    }];\n}\n","import React from \"react\";\nimport { getTableCellAlignment, getTablePropertyColumnWidth } from \"./internal/common\";\nimport { FilterValues, ResolvedProperties, ResolvedProperty } from \"../../types\";\nimport { VirtualTableColumn } from \"../VirtualTable\";\nimport { getIconForProperty, getResolvedPropertyInPath } from \"../../util\";\nimport { getColumnKeysForProperty } from \"../common/useColumnsIds\";\n\nexport function buildIdColumn(largeLayout?: boolean): VirtualTableColumn {\n    return {\n        key: \"id_ewcfedcswdf3\",\n        width: (largeLayout ? 160 : 130),\n        title: \"ID\",\n        resizable: false,\n        frozen: largeLayout ?? false,\n        headerAlign: \"center\",\n        align: \"center\",\n    };\n}\n\nexport interface PropertiesToColumnsParams<M extends Record<string, any>> {\n    properties: ResolvedProperties<M>;\n    sortable?: boolean;\n    forceFilter?: FilterValues<keyof M extends string ? keyof M : never>;\n    AdditionalHeaderWidget?: React.ComponentType<{\n        property: ResolvedProperty,\n        propertyKey: string,\n        onHover: boolean,\n    }>;\n}\n\nexport function propertiesToColumns<M extends Record<string, any>>({ properties, sortable, forceFilter, AdditionalHeaderWidget }: PropertiesToColumnsParams<M>): VirtualTableColumn[] {\n    const disabledFilter = Boolean(forceFilter);\n    return Object.entries<ResolvedProperty>(properties)\n        .flatMap(([key, property]) => getColumnKeysForProperty(property, key))\n        .map(({\n                  key,\n                  disabled\n              }) => {\n            const property = getResolvedPropertyInPath(properties, key);\n            if (!property)\n                throw Error(\"Internal error: no property found in path \" + key);\n            const filterable = filterableProperty(property);\n            return {\n                key: key as string,\n                align: getTableCellAlignment(property),\n                icon: getIconForProperty(property, \"small\"),\n                title: property.name ?? key as string,\n                sortable: sortable,\n                filter: !disabledFilter && filterable,\n                width: getTablePropertyColumnWidth(property),\n                resizable: true,\n                custom: {\n                    resolvedProperty: property,\n                    disabled\n                },\n                AdditionalHeaderWidget: AdditionalHeaderWidget\n                    ? ({ onHover }) => <AdditionalHeaderWidget property={property} propertyKey={key} onHover={onHover}/>\n                    : undefined\n            } satisfies VirtualTableColumn;\n        });\n}\n\nfunction filterableProperty(property: ResolvedProperty, partOfArray = false): boolean {\n    if (partOfArray) {\n        return [\"string\", \"number\", \"date\", \"reference\"].includes(property.dataType);\n    }\n    if (property.dataType === \"array\") {\n        if (property.of)\n            return filterableProperty(property.of, true);\n        else\n            return false;\n    }\n    return [\"string\", \"number\", \"boolean\", \"date\", \"reference\", \"array\"].includes(property.dataType);\n}\n","import React from \"react\";\nimport { CircularProgress, CircularProgressProps, Typography } from \"@firecms/ui\";\n\n/**\n *\n * @param text\n * @param props\n * @constructor\n * @ignore\n */\nexport function CircularProgressCenter({ text, ...props }: CircularProgressProps & {\n    text?: string\n}) {\n    return (\n        <div\n            className=\"flex w-full h-screen max-h-full max-w-full bg-gray-50 dark:bg-gray-900 gap-4\">\n            <div className=\"m-auto flex flex-col gap-2 items-center\">\n                <CircularProgress {...props}/>\n                {text && <Typography\n                    color={\"secondary\"}\n                    variant={\"caption\"}\n                    className=\"text-center\">{text}</Typography>}\n            </div>\n        </div>\n    );\n}\n","import React, { RefObject, useCallback, useEffect, useState } from \"react\";\nimport equal from \"react-fast-compare\";\n\nimport { VirtualTableColumn, VirtualTableSort, VirtualTableWhereFilterOp } from \"./VirtualTableProps\";\nimport { ErrorBoundary } from \"../ErrorBoundary\";\nimport {\n    ArrowUpwardIcon,\n    Badge,\n    Button,\n    cn,\n    defaultBorderMixin,\n    FilterListIcon,\n    IconButton,\n    Popover\n} from \"@firecms/ui\";\n\ninterface FilterFormProps<T> {\n    column: VirtualTableColumn<T>;\n    onFilterUpdate: (filter?: [VirtualTableWhereFilterOp, any], newOpenFilterState?: boolean) => void;\n    filter?: [VirtualTableWhereFilterOp, any];\n    onHover: boolean,\n    createFilterField: (props: FilterFormFieldProps<T>) => React.ReactNode;\n    hidden: boolean;\n    setHidden: (hidden: boolean) => void;\n}\n\nexport type FilterFormFieldProps<CustomProps> = {\n    id: React.Key,\n    filterValue: [VirtualTableWhereFilterOp, any] | undefined,\n    setFilterValue: (filterValue?: [VirtualTableWhereFilterOp, any]) => void;\n    column: VirtualTableColumn<CustomProps>;\n    hidden: boolean;\n    setHidden: (hidden: boolean) => void;\n};\n\ntype VirtualTableHeaderProps<M extends Record<string, any>> = {\n    resizeHandleRef: RefObject<HTMLDivElement>;\n    columnIndex: number;\n    isResizingIndex: number;\n    column: VirtualTableColumn<any>;\n    onColumnSort: (key: Extract<keyof M, string>) => void;\n    filter?: [VirtualTableWhereFilterOp, any];\n    sort: VirtualTableSort;\n    onFilterUpdate: (column: VirtualTableColumn, filterForProperty?: [VirtualTableWhereFilterOp, any]) => void;\n    onClickResizeColumn?: (columnIndex: number, column: VirtualTableColumn) => void;\n    createFilterField?: (props: FilterFormFieldProps<any>) => React.ReactNode;\n    AdditionalHeaderWidget?: (props: { onHover: boolean }) => React.ReactNode;\n};\n\nexport const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(\n    function VirtualTableHeader<M extends Record<string, any>>({\n                                                                   resizeHandleRef,\n                                                                   columnIndex,\n                                                                   isResizingIndex,\n                                                                   sort,\n                                                                   onColumnSort,\n                                                                   onFilterUpdate,\n                                                                   filter,\n                                                                   column,\n                                                                   onClickResizeColumn,\n                                                                   createFilterField,\n                                                                   AdditionalHeaderWidget\n                                                               }: VirtualTableHeaderProps<M>) {\n\n        const [onHover, setOnHover] = useState(false);\n\n        const [openFilter, setOpenFilter] = React.useState(false);\n        const [hidden, setHidden] = React.useState(false);\n\n        const handleSettingsClick = useCallback((event: any) => {\n            setOpenFilter(true);\n        }, []);\n\n        const update = useCallback((filterForProperty?: [VirtualTableWhereFilterOp, any], newOpenFilterState?: boolean) => {\n            onFilterUpdate(column, filterForProperty);\n            if (newOpenFilterState !== undefined)\n                setOpenFilter(newOpenFilterState);\n        }, [column, onFilterUpdate]);\n\n        const thisColumnIsResizing = isResizingIndex === columnIndex;\n        const anotherColumnIsResizing = isResizingIndex !== columnIndex && isResizingIndex > 0;\n\n        const hovered = !anotherColumnIsResizing && (onHover || thisColumnIsResizing);\n\n        return (\n            <ErrorBoundary>\n                <div\n                    className={cn(\"flex py-0 px-3 h-full text-xs uppercase font-semibold relative select-none items-center bg-gray-50 dark:bg-gray-900\",\n                        \"text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200 \",\n                        \"hover:bg-gray-100 dark:hover:bg-gray-800 hover:bg-opacity-50 dark:hover:bg-opacity-50\",\n                        column.frozen ? \"sticky left-0 z-10\" : \"relative z-0\"\n                    )}\n                    style={{\n                        // transition: \"color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms\",\n                        // fontSize: \"0.750rem\",\n                        left: column.frozen ? 0 : undefined,\n                        minWidth: column.width,\n                        maxWidth: column.width\n                    }}\n                    onMouseEnter={() => setOnHover(true)}\n                    onMouseMove={() => setOnHover(true)}\n                    onMouseLeave={() => setOnHover(false)}\n                >\n\n                    <div className=\"overflow-hidden flex-grow\">\n                        <div\n                            className={`flex items-center justify-${column.headerAlign} flex-row`}>\n\n                            {column.icon}\n\n                            <div\n                                className=\"truncate -webkit-box w-full mx-1 overflow-hidden\"\n                                style={{\n                                    WebkitBoxOrient: \"vertical\",\n                                    WebkitLineClamp: 2,\n                                    justifyContent: column.align\n                                }}>\n                                {column.title}\n                            </div>\n\n                        </div>\n                    </div>\n                    <>\n\n                        {AdditionalHeaderWidget &&\n                            <AdditionalHeaderWidget onHover={onHover || openFilter}/>}\n\n                        {column.sortable && (sort || hovered || openFilter) &&\n                            <Badge color=\"secondary\"\n                                   invisible={!sort}>\n                                <IconButton\n                                    size={\"small\"}\n                                    className={onHover || openFilter ? \"bg-white dark:bg-gray-950\" : undefined}\n                                    onClick={() => {\n                                        onColumnSort(column.key as Extract<keyof M, string>);\n                                    }}\n                                >\n                                    {!sort &&\n                                        <ArrowUpwardIcon/>}\n                                    {sort === \"asc\" &&\n                                        <ArrowUpwardIcon/>}\n                                    {sort === \"desc\" &&\n                                        <ArrowUpwardIcon className={\"rotate-180\"}/>}\n                                </IconButton>\n                            </Badge>\n                        }\n                    </>\n\n                    {column.filter && createFilterField && <div>\n                        <Badge color=\"secondary\"\n                               invisible={!filter}>\n\n                            <Popover\n                                open={openFilter}\n                                onOpenChange={setOpenFilter}\n                                className={hidden ? \"hidden\" : undefined}\n                                modal={true}\n                                trigger={\n                                    <IconButton\n                                        className={onHover || openFilter ? \"bg-white dark:bg-gray-950\" : undefined}\n                                        size={\"small\"}\n                                        onClick={handleSettingsClick}>\n                                        <FilterListIcon size={\"small\"}/>\n                                    </IconButton>}\n                            >\n                                <FilterForm column={column}\n                                            filter={filter}\n                                            onHover={onHover}\n                                            onFilterUpdate={update}\n                                            createFilterField={createFilterField}\n                                            hidden={hidden}\n                                            setHidden={setHidden}/>\n\n                            </Popover>\n\n                        </Badge>\n\n                    </div>}\n\n                    {column.resizable && <div\n                        ref={resizeHandleRef}\n                        className={cn(\n                            \"absolute h-full w-[6px] top-0 right-0 cursor-col-resize\",\n                            hovered && \"bg-gray-300 dark:bg-gray-700\"\n                        )}\n                        onMouseDown={onClickResizeColumn ? () => onClickResizeColumn(columnIndex, column) : undefined}\n                    />}\n                </div>\n\n            </ErrorBoundary>\n        );\n    }, equal) as React.FunctionComponent<VirtualTableHeaderProps<any>>;\n\nfunction FilterForm<M>({\n                           column,\n                           onFilterUpdate,\n                           filter,\n                           onHover,\n                           createFilterField,\n                           hidden,\n                           setHidden\n                       }: FilterFormProps<M>) {\n\n    const id = column.key;\n\n    const [filterInternal, setFilterInternal] = useState<[VirtualTableWhereFilterOp, any] | undefined>(filter);\n\n    useEffect(() => {\n        setFilterInternal(filter);\n    }, [filter]);\n\n    if (!column.filter) return null;\n\n    const submit = () => {\n        onFilterUpdate(filterInternal, false);\n    };\n\n    const reset = (e: any) => {\n        onFilterUpdate(undefined, false);\n    };\n\n    const filterIsSet = !!filter;\n\n    const filterField = createFilterField({\n        id,\n        filterValue: filterInternal,\n        setFilterValue: setFilterInternal,\n        column,\n        hidden,\n        setHidden\n    });\n\n    if (!filterField) return null;\n    return (\n        <form noValidate={true}\n              onSubmit={(e) => {\n                  e.stopPropagation();\n                  e.preventDefault();\n                  submit();\n              }}\n              className={\"text-gray-900 dark:text-white\"}>\n            <div\n                className={cn(defaultBorderMixin, \"py-4 px-6 text-xs font-semibold uppercase border-b\")}>\n                {column.title ?? id}\n            </div>\n            {filterField && <div className=\"m-4\">\n                {filterField}\n            </div>}\n            <div className=\"flex justify-end m-4\">\n                <Button\n                    className=\"mr-4\"\n                    disabled={!filterIsSet}\n                    variant={\"text\"}\n                    color=\"primary\"\n                    type=\"reset\"\n                    aria-label=\"filter clear\"\n                    onClick={reset}>Clear</Button>\n                <Button\n                    variant=\"outlined\"\n                    color=\"primary\"\n                    type=\"submit\">Filter</Button>\n            </div>\n        </form>\n    );\n\n}\n","import React, { createRef, useCallback, useEffect, useState } from \"react\";\n\nimport { VirtualTableColumn, VirtualTableWhereFilterOp } from \"./VirtualTableProps\";\nimport { ErrorBoundary } from \"../ErrorBoundary\";\nimport { VirtualTableHeader } from \"./VirtualTableHeader\";\nimport { VirtualTableContextProps } from \"./types\";\nimport { cn, defaultBorderMixin } from \"@firecms/ui\";\n\nexport const VirtualTableHeaderRow = ({\n                                          columns,\n                                          currentSort,\n                                          onColumnSort,\n                                          onFilterUpdate,\n                                          sortByProperty,\n                                          filter,\n                                          onColumnResize,\n                                          onColumnResizeEnd,\n                                          createFilterField,\n                                          AddColumnComponent\n                                      }: VirtualTableContextProps<any>) => {\n\n    const columnRefs = columns.map(() => createRef<HTMLDivElement>());\n    const [isResizing, setIsResizing] = useState(-1);\n\n    const adjustWidthColumn = useCallback((index: number, width: number, end: boolean) => {\n        const column = columns[index];\n        const minWidth = 100;\n        const maxWidth = 800;\n        const newWidth = width > maxWidth ? maxWidth : (width < minWidth ? minWidth : width);\n        const params = {\n            width: newWidth,\n            key: column.key as string,\n            column: {\n                ...column,\n                width: newWidth\n            } as VirtualTableColumn\n        };\n        if (!end)\n            onColumnResize(params);\n        else\n            onColumnResizeEnd(params);\n    }, [columns, onColumnResize, onColumnResizeEnd]);\n\n    const getEventNewWidth = useCallback((e: MouseEvent) => {\n        if (isResizing >= 0) {\n            const left = columnRefs[isResizing].current?.parentElement?.getBoundingClientRect().left;\n            if (!left) return;\n            return e.clientX - left;\n        }\n        return undefined;\n    }, [columnRefs, isResizing]);\n\n    const setCursorDocument = useCallback((isResizing: boolean) => {\n        document.body.style.cursor = isResizing ? \"col-resize\" : \"auto\";\n    }, []);\n\n    const handleOnMouseMove = useCallback((e: MouseEvent) => {\n        e.stopPropagation();\n        e.preventDefault();\n        const newWidth = getEventNewWidth(e);\n        if (newWidth)\n            adjustWidthColumn(isResizing, newWidth, false);\n    }, [adjustWidthColumn, getEventNewWidth, isResizing]);\n\n    const handleOnMouseUp = useCallback((e: MouseEvent) => {\n        e.stopPropagation();\n        e.preventDefault();\n        const newWidth = getEventNewWidth(e);\n        if (newWidth)\n            adjustWidthColumn(isResizing, newWidth, true);\n        setIsResizing(-1);\n        setCursorDocument(false);\n    }, [adjustWidthColumn, getEventNewWidth, isResizing, setCursorDocument]);\n\n    const removeResizingListeners = useCallback(() => {\n        document.removeEventListener(\"mousemove\", handleOnMouseMove);\n        document.removeEventListener(\"mouseup\", handleOnMouseUp);\n    }, [handleOnMouseMove, handleOnMouseUp]);\n\n    const attachResizeListeners = useCallback(() => {\n        document.addEventListener(\"mousemove\", handleOnMouseMove);\n        document.addEventListener(\"mouseup\", handleOnMouseUp);\n    }, [handleOnMouseMove, handleOnMouseUp]);\n\n    useEffect(() => {\n        if (isResizing >= 0) {\n            attachResizeListeners();\n        } else {\n            removeResizingListeners();\n        }\n        return () => {\n            removeResizingListeners();\n        };\n    }, [attachResizeListeners, isResizing, removeResizingListeners]);\n\n    const onClickResizeColumn = useCallback((index: number) => {\n        setIsResizing(index);\n        setCursorDocument(true);\n    }, [setCursorDocument]);\n\n    return (\n        <div\n            className={cn(defaultBorderMixin, \"z-20 sticky min-w-full flex w-fit flex-row top-0 left-0 h-12 border-b bg-gray-50 dark:bg-gray-900\")}>\n            {columns.map((c, columnIndex) => {\n                const column = columns[columnIndex];\n\n                const filterForThisProperty: [VirtualTableWhereFilterOp, any] | undefined =\n                    column && filter && filter[column.key]\n                        ? filter[column.key]\n                        : undefined;\n                return <ErrorBoundary key={\"header_\" + column.key}>\n                    <VirtualTableHeader\n                        resizeHandleRef={columnRefs[columnIndex]}\n                        columnIndex={columnIndex}\n                        isResizingIndex={isResizing}\n                        onFilterUpdate={onFilterUpdate}\n                        filter={filterForThisProperty}\n                        sort={sortByProperty === column.key ? currentSort : undefined}\n                        onColumnSort={onColumnSort}\n                        onClickResizeColumn={onClickResizeColumn}\n                        column={column}\n                        createFilterField={createFilterField}\n                        AdditionalHeaderWidget={column.AdditionalHeaderWidget}/>\n                </ErrorBoundary>;\n            })}\n\n            {AddColumnComponent && <AddColumnComponent/>}\n\n        </div>\n    );\n};\n","import React, { useCallback } from \"react\";\n\nimport equal from \"react-fast-compare\"\n\nimport { getRowHeight } from \"./common\";\nimport { VirtualTableRowProps } from \"./types\";\nimport { cn } from \"@firecms/ui\";\n\nexport const VirtualTableRow = React.memo<VirtualTableRowProps<any>>(\n    function VirtualTableRow<T>({\n                                    rowData,\n                                    rowIndex,\n                                    children,\n                                    onRowClick,\n                                    size,\n                                    style,\n                                    hoverRow,\n                                    rowClassName\n                                }: VirtualTableRowProps<T>) {\n\n        const onClick = useCallback((event: React.SyntheticEvent) => {\n            if (onRowClick)\n                onRowClick({\n                    rowData,\n                    rowIndex,\n                    event\n                })\n        }, [onRowClick, rowData, rowIndex]);\n\n        return (\n            <div\n                className={cn(\n                    \"flex min-w-full text-sm border-b border-gray-200 dark:border-gray-800 border-opacity-40 dark:border-opacity-40\",\n                    rowClassName ? rowClassName(rowData) : \"\",\n                    {\n                        \"hover:bg-opacity-95\": hoverRow,\n                        \"cursor-pointer\": onRowClick\n                    }\n                )}\n                onClick={onClick}\n                style={{\n                    ...(style),\n                    height: getRowHeight(size),\n                    width: \"fit-content\"\n                }}\n            >\n                {children}\n            </div>\n        );\n\n    },\n    equal\n);\n","import React from \"react\";\n\nimport equal from \"react-fast-compare\"\n\nimport { CellRendererParams, VirtualTableColumn } from \"./VirtualTableProps\";\n\ntype VirtualTableCellProps<T extends any> = {\n    dataKey: string;\n    column: VirtualTableColumn;\n    columns: VirtualTableColumn[];\n    rowData: any;\n    cellData: any;\n    rowIndex: any;\n    columnIndex: number;\n    cellRenderer: React.ComponentType<CellRendererParams<T>>;\n};\n\nexport const VirtualTableCell = React.memo<VirtualTableCellProps<any>>(\n    function VirtualTableCell<T extends any>(props: VirtualTableCellProps<T>) {\n        // @ts-ignore\n        return props.rowData && props.cellRenderer(\n            {\n                cellData: props.cellData,\n                rowData: props.rowData,\n                rowIndex: props.rowIndex,\n                isScrolling: false,\n                column: props.column,\n                columns: props.columns,\n                columnIndex: props.columnIndex,\n                width: props.column.width\n            } as CellRendererParams<T>\n        );\n        // return props.rowData && <props.cellRenderer\n        //     rowData={props.rowData}\n        //     rowIndex={props.rowIndex}\n        //     isScrolling={false}\n        //     column={props.column}\n        //     columns={props.columns}\n        //     columnIndex={props.columnIndex}\n        //     width={props.column.width}/>\n    },\n    (a, b) => {\n        return equal(a.rowData, b.rowData) &&\n            equal(a.column, b.column) &&\n            equal(a.cellData, b.cellData) &&\n            equal(a.rowIndex, b.rowIndex) &&\n            equal(a.cellRenderer, b.cellRenderer) &&\n            equal(a.columnIndex, b.columnIndex)\n    }\n);\n","import React, { createContext, forwardRef, RefObject, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport equal from \"react-fast-compare\"\n\n// @ts-ignore\nimport { FixedSizeList as List } from \"react-window\";\nimport useMeasure from \"react-use-measure\";\n\nimport { CircularProgressCenter } from \"../CircularProgressCenter\";\nimport {\n    OnVirtualTableColumnResizeParams,\n    VirtualTableColumn,\n    VirtualTableFilterValues,\n    VirtualTableProps,\n    VirtualTableWhereFilterOp\n} from \"./VirtualTableProps\";\n\nimport { getRowHeight } from \"./common\";\nimport { VirtualTableContextProps } from \"./types\";\nimport { VirtualTableHeaderRow } from \"./VirtualTableHeaderRow\";\nimport { VirtualTableRow } from \"./VirtualTableRow\";\nimport { VirtualTableCell } from \"./VirtualTableCell\";\nimport { AssignmentIcon, CenteredView, cn, Typography } from \"@firecms/ui\";\n\nconst VirtualListContext = createContext<VirtualTableContextProps<any>>({} as any);\nVirtualListContext.displayName = \"VirtualListContext\";\n\ntype InnerElementProps = {\n    children: React.ReactNode,\n    style: any\n};\n\n// eslint-disable-next-line react/display-name\nconst innerElementType = forwardRef<HTMLDivElement, InnerElementProps>(({\n                                                                            children,\n                                                                            ...rest\n                                                                        }: InnerElementProps, ref) => {\n\n        return (\n            <VirtualListContext.Consumer>\n                {(virtualTableProps) => {\n                    const customView = virtualTableProps.customView;\n                    return (\n                        <>\n                            <div\n                                id={\"virtual-table\"}\n                                style={{\n                                    position: \"relative\",\n                                    height: \"100%\"\n                                }}>\n                                <div\n                                    ref={ref}\n                                    {...rest}\n                                    style={{\n                                        ...rest?.style,\n                                        minHeight: \"100%\",\n                                        position: \"relative\"\n                                    }}>\n                                    <VirtualTableHeaderRow {...virtualTableProps}/>\n                                    {!customView && children}\n                                </div>\n\n                            </div>\n\n                            {customView && <div style={{\n                                position: \"sticky\",\n                                top: \"56px\",\n                                flexGrow: 1,\n                                height: \"calc(100% - 56px)\",\n                                marginTop: \"calc(56px - 100vh)\",\n                                left: 0\n                            }}>{customView}</div>}\n\n                        </>\n                    );\n                }}\n            </VirtualListContext.Consumer>\n        );\n    })\n;\n\n/**\n * This is a Table component that allows displaying arbitrary data, not\n * necessarily related to entities or properties. It is the component\n * that powers the entity collections but has a generic API, so it\n * can be reused.\n *\n * @group Components\n */\nexport const VirtualTable = React.memo<VirtualTableProps<any>>(\n    function VirtualTable<T extends Record<string, any>>({\n                                                             data,\n                                                             onResetPagination,\n                                                             onEndReached,\n                                                             size = \"m\",\n                                                             columns: columnsProp,\n                                                             onRowClick,\n                                                             onColumnResize,\n                                                             filter: filterInput,\n                                                             checkFilterCombination,\n                                                             onFilterUpdate,\n                                                             sortBy,\n                                                             error,\n                                                             emptyComponent,\n                                                             onSortByUpdate,\n                                                             loading,\n                                                             cellRenderer,\n                                                             hoverRow,\n                                                             createFilterField,\n                                                             rowClassName,\n                                                             className,\n                                                             endAdornment,\n                                                             AddColumnComponent\n                                                         }: VirtualTableProps<T>) {\n\n        const sortByProperty: string | undefined = sortBy ? sortBy[0] : undefined;\n        const currentSort: \"asc\" | \"desc\" | undefined = sortBy ? sortBy[1] : undefined;\n\n        const [columns, setColumns] = useState(columnsProp);\n\n        const tableRef = useRef<HTMLDivElement>(null);\n        const endReachCallbackThreshold = useRef<number>(0);\n\n        useEffect(() => {\n            setColumns(columnsProp);\n        }, [columnsProp]);\n\n        const [measureRef, bounds] = useMeasure();\n\n        const onColumnResizeInternal = useCallback((params: OnVirtualTableColumnResizeParams) => {\n            setColumns(columns.map((column) => column.key === params.column.key ? params.column : column));\n        }, [columns]);\n\n        const onColumnResizeEndInternal = useCallback((params: OnVirtualTableColumnResizeParams) => {\n            setColumns(columns.map((column) => column.key === params.column.key ? params.column : column));\n            if (onColumnResize) {\n                onColumnResize(params);\n            }\n        }, [columns, onColumnResize]);\n\n        // saving the current filter as a ref as a workaround for header closure\n        const filterRef = useRef<VirtualTableFilterValues<any> | undefined>();\n\n        useEffect(() => {\n            filterRef.current = filterInput;\n        }, [filterInput]);\n\n        const scrollToTop = useCallback(() => {\n            endReachCallbackThreshold.current = 0;\n            if (tableRef.current) {\n                // scrollRef.current = [scrollRef.current[0], 0];\n                tableRef.current.scrollTo(tableRef.current?.scrollLeft, 0);\n            }\n        }, []);\n\n        const onColumnSort = useCallback((key: string) => {\n\n            const isDesc = sortByProperty === key && currentSort === \"desc\";\n            const isAsc = sortByProperty === key && currentSort === \"asc\";\n            const newSort = isAsc ? \"desc\" : (isDesc ? undefined : \"asc\");\n            const newSortProperty: string | undefined = isDesc ? undefined : key;\n\n            const filter = filterRef.current;\n\n            const newSortBy: [string, \"asc\" | \"desc\"] | undefined = newSort && newSortProperty ? [newSortProperty, newSort] : undefined;\n            if (filter) {\n                if (checkFilterCombination && !checkFilterCombination(filter, newSortBy)) {\n                    if (onFilterUpdate)\n                        onFilterUpdate(undefined);\n                }\n            }\n\n            if (onResetPagination) {\n                onResetPagination();\n            }\n\n            if (onSortByUpdate) {\n                onSortByUpdate(newSortBy);\n            }\n\n            scrollToTop();\n        }, [checkFilterCombination, currentSort, onFilterUpdate, onResetPagination, onSortByUpdate, scrollToTop, sortByProperty]);\n\n        const resetSort = useCallback(() => {\n            endReachCallbackThreshold.current = 0;\n            if (onSortByUpdate)\n                onSortByUpdate(undefined);\n        }, [onSortByUpdate]);\n\n        const maxScroll = Math.max((data?.length ?? 0) * getRowHeight(size) - bounds.height, 0);\n        const onEndReachedInternal = useCallback((scrollOffset: number) => {\n            if (onEndReached && (data?.length ?? 0) > 0 && scrollOffset > endReachCallbackThreshold.current + 600) {\n                endReachCallbackThreshold.current = scrollOffset;\n                onEndReached();\n            }\n        }, [data?.length, onEndReached]);\n\n        const onScroll = useCallback(({\n                                          scrollOffset,\n                                          scrollUpdateWasRequested\n                                      }: {\n            scrollDirection: \"forward\" | \"backward\",\n            scrollOffset: number,\n            scrollUpdateWasRequested: boolean;\n        }) => {\n            if (!scrollUpdateWasRequested && (scrollOffset >= maxScroll - 600))\n                onEndReachedInternal(scrollOffset);\n        }, [maxScroll, onEndReachedInternal]);\n\n        const onFilterUpdateInternal = useCallback((column: VirtualTableColumn, filterForProperty?: [VirtualTableWhereFilterOp, any]) => {\n\n            endReachCallbackThreshold.current = 0;\n            const filter = filterRef.current;\n            let newFilterValue: VirtualTableFilterValues<any> = filter ? { ...filter } : {};\n\n            if (!filterForProperty) {\n                delete newFilterValue[column.key];\n            } else {\n                newFilterValue[column.key] = filterForProperty;\n            }\n            const newSortBy: [string, \"asc\" | \"desc\"] | undefined = sortByProperty && currentSort ? [sortByProperty, currentSort] : undefined;\n            const isNewFilterCombinationValid = !checkFilterCombination || checkFilterCombination(newFilterValue, newSortBy);\n            if (!isNewFilterCombinationValid) {\n                newFilterValue = filterForProperty ? { [column.key]: filterForProperty } as VirtualTableFilterValues<Extract<keyof T, string>> : {};\n            }\n\n            if (onFilterUpdate) onFilterUpdate(newFilterValue);\n        }, [checkFilterCombination, currentSort, onFilterUpdate, sortByProperty]);\n\n        const buildEmptyView = useCallback(() => {\n            if (loading)\n                return <CircularProgressCenter/>;\n            return <div\n                className=\"flex flex-col overflow-auto items-center justify-center p-2 gap-2 h-full\">\n                <AssignmentIcon/>\n                {emptyComponent}\n            </div>;\n        }, [emptyComponent, loading]);\n\n        const empty = !loading && (data?.length ?? 0) === 0;\n        const customView = error\n            ? <CenteredView maxWidth={\"2xl\"}\n                className=\"flex flex-col gap-2\">\n\n                <Typography variant={\"h6\"}>\n                    {\"Error fetching data from the data source\"}\n                </Typography>\n\n                {error?.message && <SafeLinkRenderer text={error.message}/>}\n\n            </CenteredView>\n            : (empty ? buildEmptyView() : undefined);\n\n        const virtualListController = {\n            data,\n            size,\n            cellRenderer,\n            columns,\n            currentSort,\n            onRowClick,\n            customView,\n            onColumnResize: onColumnResizeInternal,\n            onColumnResizeEnd: onColumnResizeEndInternal,\n            filter: filterRef.current,\n            onColumnSort,\n            onFilterUpdate: onFilterUpdateInternal,\n            sortByProperty,\n            hoverRow: hoverRow ?? false,\n            createFilterField,\n            rowClassName,\n            endAdornment,\n            AddColumnComponent\n        };\n\n        // useTraceUpdate(virtualListController);\n        return (\n            <div\n                ref={measureRef}\n                className={cn(\"h-full w-full\", className)}>\n                <VirtualListContext.Provider\n                    value={virtualListController}>\n\n                    <MemoizedList\n                        outerRef={tableRef}\n                        key={size}\n                        width={bounds.width}\n                        height={bounds.height}\n                        itemCount={(data?.length ?? 0) + (endAdornment ? 1 : 0)}\n                        onScroll={onScroll}\n                        includeAddColumn={Boolean(AddColumnComponent)}\n                        itemSize={getRowHeight(size)}/>\n\n                </VirtualListContext.Provider>\n            </div>\n        );\n    },\n    equal\n);\n\nfunction MemoizedList({\n                          outerRef,\n                          width,\n                          height,\n                          itemCount,\n                          onScroll,\n                          itemSize,\n                          includeAddColumn\n                      }: {\n    outerRef: RefObject<HTMLDivElement>;\n    width: number;\n    height: number;\n    itemCount: number;\n    onScroll: (params: {\n        scrollDirection: \"forward\" | \"backward\",\n        scrollOffset: number,\n        scrollUpdateWasRequested: boolean;\n    }) => void;\n    itemSize: number;\n    includeAddColumn?: boolean;\n}) {\n\n    const Row = useCallback(({\n                                 index,\n                                 style\n                             }: any) => {\n        return <VirtualListContext.Consumer>\n            {({\n                  onRowClick,\n                  data,\n                  columns,\n                  size = \"m\",\n                  cellRenderer,\n                  hoverRow,\n                  rowClassName,\n                  endAdornment\n              }) => {\n\n                if (endAdornment && index === (data ?? []).length) {\n                    return <div style={{\n                        ...style,\n                        height: \"auto\",\n                        position: \"sticky\",\n                        bottom: 0,\n                        zIndex: 1\n                    }}>\n                        {endAdornment}\n                    </div>;\n                }\n\n                const rowData = data && data[index];\n                return (\n                    <VirtualTableRow\n                        key={`row_${index}`}\n                        rowData={rowData}\n                        rowIndex={index}\n                        onRowClick={onRowClick}\n                        columns={columns}\n                        hoverRow={hoverRow}\n                        rowClassName={rowClassName}\n                        style={{\n                            ...style,\n                            top: `calc(${style.top}px + 48px)`\n                        }}\n                        size={size}>\n\n                        {columns.map((column: VirtualTableColumn, columnIndex: number) => {\n                            const cellData = rowData && rowData[column.key];\n                            return <VirtualTableCell\n                                key={`cell_${column.key}`}\n                                dataKey={column.key}\n                                cellRenderer={cellRenderer}\n                                column={column}\n                                columns={columns}\n                                rowData={rowData}\n                                cellData={cellData}\n                                rowIndex={index}\n                                columnIndex={columnIndex}/>;\n                        })}\n\n                        {includeAddColumn && <div className={\"w-20\"}/>}\n\n                    </VirtualTableRow>\n                );\n            }}\n        </VirtualListContext.Consumer>;\n    }, []);\n\n    return <List\n        outerRef={outerRef}\n        innerElementType={innerElementType}\n        width={width}\n        height={height}\n        overscanCount={4}\n        itemCount={itemCount}\n        onScroll={onScroll}\n        itemSize={itemSize}>\n        {Row}\n    </List>;\n}\n\nconst SafeLinkRenderer: React.FC<{\n    text: string;\n}> = ({ text }) => {\n    const urlRegex = /https?:\\/\\/[^\\s]+/g;\n    const htmlContent = text.replace(urlRegex, (url) => {\n        // For each URL found, replace it with an HTML <a> tag\n        return `<a href=\"${url}\" class=\"underline\" target=\"_blank\">Link</a><br/>`;\n    });\n\n    return (\n        <div className={\"break-all\"} dangerouslySetInnerHTML={{ __html: htmlContent }}/>\n    );\n};\n","import React, { useMemo, useState } from \"react\";\nimport { VirtualTableWhereFilterOp } from \"../../VirtualTable\";\nimport { Entity, EntityCollection, EntityReference } from \"../../../types\";\nimport { ReferencePreview } from \"../../../preview\";\nimport { getReferenceFrom } from \"../../../util\";\nimport { useNavigationController, useReferenceDialog } from \"../../../hooks\";\nimport { Button, Checkbox, Label, Select, SelectItem } from \"@firecms/ui\";\n\ninterface ReferenceFilterFieldProps {\n    name: string,\n    value?: [op: VirtualTableWhereFilterOp, fieldValue: any];\n    setValue: (filterValue?: [VirtualTableWhereFilterOp, any]) => void;\n    isArray?: boolean;\n    path?: string;\n    title?: string;\n    previewProperties?: string[];\n    hidden: boolean;\n    setHidden: (hidden: boolean) => void;\n}\n\nconst operationLabels = {\n    \"==\": \"==\",\n    \"!=\": \"!=\",\n    \">\": \">\",\n    \"<\": \"<\",\n    \">=\": \">=\",\n    \"<=\": \"<=\",\n    in: \"In\",\n    \"not-in\": \"Not in\",\n    \"array-contains\": \"Contains\",\n    \"array-contains-any\": \"Contains Any\"\n};\n\nconst multipleSelectOperations = [\"array-contains-any\", \"in\", \"not-in\"];\n\nexport function ReferenceFilterField({\n                                         name,\n                                         value,\n                                         setValue,\n                                         isArray,\n                                         path,\n                                         title,\n                                         previewProperties,\n                                         setHidden\n                                     }: ReferenceFilterFieldProps) {\n\n    const possibleOperations: (keyof typeof operationLabels) [] = isArray\n        ? [\"array-contains\"]\n        : [\"==\", \"!=\", \">\", \"<\", \">=\", \"<=\"];\n\n    isArray\n        ? possibleOperations.push(\"array-contains-any\")\n        : possibleOperations.push(\"in\", \"not-in\");\n\n    const [fieldOperation, fieldValue] = value || [possibleOperations[0], undefined];\n    const [operation, setOperation] = useState<VirtualTableWhereFilterOp>(fieldOperation);\n    const [internalValue, setInternalValue] = useState<EntityReference | EntityReference[] | undefined | null>(fieldValue);\n\n    const selectedEntityIds = internalValue\n        ? (Array.isArray(internalValue) ? internalValue.map((ref) => {\n            if (!(ref?.isEntityReference && ref?.isEntityReference())) {\n                return null;\n            }\n            return ref.id;\n        }).filter(Boolean) as string[] : [internalValue.id])\n        : [];\n\n    function updateFilter(op: VirtualTableWhereFilterOp, val?: EntityReference | EntityReference[] | null) {\n\n        const prevOpIsArray = multipleSelectOperations.includes(operation);\n        const newOpIsArray = multipleSelectOperations.includes(op);\n        let newValue = val;\n        if (prevOpIsArray !== newOpIsArray) {\n            // @ts-ignore\n            newValue = newOpIsArray ? (newValue?.isEntityReference && newValue?.isEntityReference() ? [newValue] : []) : undefined\n        }\n\n        setOperation(op);\n        setInternalValue(newValue);\n\n        const hasNewValue = newValue !== null && Array.isArray(newValue)\n            ? newValue.length > 0\n            : newValue !== undefined;\n        if (op && hasNewValue) {\n            setValue(\n                [op, newValue]\n            );\n        } else {\n            setValue(\n                undefined\n            );\n        }\n    }\n\n    const navigationController = useNavigationController();\n    const collection: EntityCollection | undefined = useMemo(() => {\n        return path ? navigationController.getCollection(path) : undefined;\n    }, [path]);\n\n    const onSingleEntitySelected = (entity: Entity<any>) => {\n        updateFilter(operation, getReferenceFrom(entity));\n    };\n\n    const onMultipleEntitiesSelected = (entities: Entity<any>[]) => {\n        updateFilter(operation, entities.map(e => getReferenceFrom(e)));\n    };\n\n    const multiple = multipleSelectOperations.includes(operation);\n\n    const referenceDialogController = useReferenceDialog({\n            multiselect: multiple,\n            path,\n            collection,\n            onSingleEntitySelected,\n            onMultipleEntitiesSelected,\n            selectedEntityIds,\n            onClose: () => {\n                setHidden(false);\n            }\n        }\n    );\n\n    const doOpenDialog = () => {\n        setHidden(true);\n        referenceDialogController.open();\n    };\n\n    const buildEntry = (reference: EntityReference) => {\n        return (\n            <ReferencePreview\n                disabled={!path}\n                previewProperties={previewProperties}\n                size={\"medium\"}\n                onClick={doOpenDialog}\n                reference={reference}\n                hover={true}\n                allowEntityNavigation={false}\n            />\n        );\n    };\n\n    return (\n\n        <div className=\"flex w-[440px] flex-row\">\n            <div className=\"w-[140px]\">\n                <Select value={operation}\n                        onValueChange={(value) => {\n                            updateFilter(value as VirtualTableWhereFilterOp, internalValue);\n                        }}\n                        renderValue={(op) => operationLabels[op as VirtualTableWhereFilterOp]}>\n                    {possibleOperations.map((op) => (\n                        <SelectItem key={op} value={op}>\n                            {operationLabels[op]}\n                        </SelectItem>\n                    ))}\n                </Select>\n            </div>\n\n            <div className=\"flex-grow ml-2 h-full gap-2 flex flex-col\">\n\n                {internalValue && Array.isArray(internalValue) && <div>\n                    {internalValue.map((ref, index) => buildEntry(ref))}\n                </div>}\n\n                {internalValue && !Array.isArray(internalValue) && <div>\n                    {buildEntry(internalValue)}\n                </div>}\n\n                {(!internalValue || (Array.isArray(internalValue) && internalValue.length === 0)) &&\n                    <Button onClick={doOpenDialog}\n                            variant={\"outlined\"}\n                            size={\"large\"}\n                            className=\"h-full w-full\">\n                        {multiple ? \"Select references\" : \"Select reference\"}\n                    </Button>\n                }\n\n                {!isArray && <Label\n                    className=\"border cursor-pointer rounded-md p-2 flex items-center gap-2 [&:has(:checked)]:bg-gray-100 dark:[&:has(:checked)]:bg-gray-800\"\n                    htmlFor=\"null-filter\"\n                >\n                    <Checkbox id=\"null-filter\"\n                              checked={internalValue === null}\n                              size={\"small\"}\n                              onCheckedChange={(checked) => {\n                                  if (internalValue !== null)\n                                      updateFilter(operation, null);\n                                  else updateFilter(operation, undefined);\n                              }}/>\n                    Filter for null values\n                </Label>}\n\n            </div>\n\n        </div>\n    );\n\n}\n","import React, { useState } from \"react\";\nimport { EnumValuesChip } from \"../../../preview\";\nimport { VirtualTableWhereFilterOp } from \"../../VirtualTable\";\nimport { Checkbox, ClearIcon, IconButton, Label, Select, SelectItem, TextField } from \"@firecms/ui\";\nimport { EnumValueConfig } from \"../../../types\";\n\ninterface StringNumberFilterFieldProps {\n    name: string,\n    dataType: \"string\" | \"number\";\n    value?: [op: VirtualTableWhereFilterOp, fieldValue: any];\n    setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: any]) => void;\n    isArray?: boolean;\n    enumValues?: EnumValueConfig[];\n    title?: string;\n}\n\nconst operationLabels = {\n    \"==\": \"==\",\n    \"!=\": \"!=\",\n    \">\": \">\",\n    \"<\": \"<\",\n    \">=\": \">=\",\n    \"<=\": \"<=\",\n    in: \"In\",\n    \"not-in\": \"Not in\",\n    \"array-contains\": \"Contains\",\n    \"array-contains-any\": \"Any\"\n};\n\nconst multipleSelectOperations = [\"array-contains-any\", \"in\", \"not-in\"];\n\nexport function StringNumberFilterField({\n                                            name,\n                                            value,\n                                            setValue,\n                                            dataType,\n                                            isArray,\n                                            enumValues,\n                                            title\n                                        }: StringNumberFilterFieldProps) {\n\n    const possibleOperations: (keyof typeof operationLabels) [] = isArray\n        ? [\"array-contains\"]\n        : [\"==\", \"!=\", \">\", \"<\", \">=\", \"<=\"];\n\n    if (enumValues)\n        isArray\n            ? possibleOperations.push(\"array-contains-any\")\n            : possibleOperations.push(\"in\", \"not-in\");\n\n    const [fieldOperation, fieldValue] = value || [possibleOperations[0], undefined];\n    const [operation, setOperation] = useState<VirtualTableWhereFilterOp>(fieldOperation);\n    const [internalValue, setInternalValue] = useState<string | number | string[] | number[] | null | undefined>(fieldValue);\n\n    function updateFilter(op: VirtualTableWhereFilterOp, val: string | number | string[] | number[] | null | undefined) {\n        let newValue = val;\n        const prevOpIsArray = multipleSelectOperations.includes(operation);\n        const newOpIsArray = multipleSelectOperations.includes(op);\n        if (prevOpIsArray !== newOpIsArray) {\n            // @ts-ignore\n            newValue = newOpIsArray ? (typeof val === \"string\" || typeof val === \"number\" ? [val] : []) : undefined;\n        }\n\n        if (typeof newValue === \"number\" && isNaN(newValue))\n            newValue = undefined;\n\n        setOperation(op);\n        setInternalValue(newValue);\n\n        const hasNewValue = newValue !== null && Array.isArray(newValue)\n            ? newValue.length > 0\n            : newValue !== undefined;\n        if (op && hasNewValue) {\n            setValue(\n                [op, newValue]\n            );\n        } else {\n            setValue(\n                undefined\n            );\n        }\n    }\n\n    const multiple = multipleSelectOperations.includes(operation);\n    return (\n\n        <div className=\"flex w-[440px]\">\n            <div className={\"w-[80px]\"}>\n                <Select value={operation}\n                        position={\"item-aligned\"}\n                        onValueChange={(value) => {\n                            updateFilter(value as VirtualTableWhereFilterOp, internalValue);\n                        }}\n                        renderValue={(op) => operationLabels[op as VirtualTableWhereFilterOp]}>\n                    {possibleOperations.map((op) => (\n                        <SelectItem key={op} value={op}>\n                            {operationLabels[op]}\n                        </SelectItem>\n                    ))}\n                </Select>\n            </div>\n\n            <div className=\"flex-grow ml-2 flex flex-col gap-2\">\n\n                {!enumValues && <TextField\n                    type={dataType === \"number\" ? \"number\" : undefined}\n                    value={internalValue !== undefined && internalValue != null ? String(internalValue) : \"\"}\n                    onChange={(evt) => {\n                        const val = dataType === \"number\"\n                            ? parseFloat(evt.target.value)\n                            : evt.target.value;\n                        updateFilter(operation, val);\n                    }}\n                    endAdornment={internalValue && <IconButton\n                        onClick={(e) => updateFilter(operation, undefined)}>\n                        <ClearIcon/>\n                    </IconButton>}\n                />}\n\n                {enumValues &&\n                    <Select\n                        position={\"item-aligned\"}\n                        value={internalValue !== undefined\n                            ? (Array.isArray(internalValue) ? internalValue.map(e => String(e)) : String(internalValue))\n                            : isArray ? [] : \"\"}\n                        onValueChange={(value) => {\n                            if (value !== \"\")\n                                updateFilter(operation, dataType === \"number\" ? parseInt(value as string) : value as string)\n                        }}\n                        multiple={multiple}\n                        endAdornment={internalValue && <IconButton\n                            className=\"absolute right-2 top-3\"\n                            onClick={(e) => updateFilter(operation, undefined)}>\n                            <ClearIcon/>\n                        </IconButton>}\n                        renderValue={(enumKey) => {\n                            if (enumKey === null)\n                                return \"Filter for null values\";\n\n                            return <EnumValuesChip\n                                key={`select_value_${name}_${enumKey}`}\n                                enumKey={enumKey}\n                                enumValues={enumValues}\n                                size={\"small\"}/>;\n                        }}>\n                        {enumValues.map((enumConfig) => (\n                            <SelectItem key={`select_value_${name}_${enumConfig.id}`}\n                                        value={String(enumConfig.id)}>\n                                <EnumValuesChip\n                                    enumKey={String(enumConfig.id)}\n                                    enumValues={enumValues}\n                                    size={\"small\"}/>\n                            </SelectItem>\n                        ))}\n                    </Select>\n                }\n\n                {!isArray && <Label\n                    className=\"border cursor-pointer rounded-md p-2 flex items-center gap-2 [&:has(:checked)]:bg-gray-100 dark:[&:has(:checked)]:bg-gray-800\"\n                    htmlFor=\"null-filter\"\n                >\n                    <Checkbox id=\"null-filter\"\n                              checked={internalValue === null}\n                              size={\"small\"}\n                              onCheckedChange={(checked) => {\n                                  if (internalValue !== null)\n                                      updateFilter(operation, null);\n                                  else updateFilter(operation, undefined);\n                              }}/>\n                    Filter for null values\n                </Label>}\n\n            </div>\n\n        </div>\n    );\n\n}\n","import React from \"react\";\nimport { VirtualTableWhereFilterOp } from \"../../VirtualTable\";\nimport { BooleanSwitchWithLabel } from \"@firecms/ui\";\n\ninterface BooleanFieldProps {\n    name: string,\n    value?: [op: VirtualTableWhereFilterOp, fieldValue: any];\n    setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: any]) => void;\n    title?: string;\n}\n\nexport function BooleanFilterField({\n                                       name,\n                                       title,\n                                       value,\n                                       setValue\n                                   }: BooleanFieldProps) {\n\n    function updateFilter(val?: boolean) {\n        if (val !== undefined) {\n            setValue(\n                [\"==\", val]\n            );\n        } else {\n            setValue(\n                undefined\n            );\n        }\n    }\n\n    const valueSetToTrue = value && value[1];\n    const valueSet = !!value;\n\n    return (\n        <div className=\"w-[300px]\">\n            <BooleanSwitchWithLabel\n                value={valueSetToTrue}\n                allowIndeterminate={true}\n                onValueChange={(v: boolean | null) => updateFilter(v === null ? undefined : v)}\n                label={!valueSet\n                    ? \"No filter\"\n                    : valueSetToTrue\n                        ? `${title} is true`\n                        : `${title} is false`}\n            />\n        </div>\n    );\n}\n","import React, { useState } from \"react\";\nimport { VirtualTableWhereFilterOp } from \"../../VirtualTable\";\nimport { Checkbox, DateTimeField, Label, Select, SelectItem } from \"@firecms/ui\";\nimport { useCustomizationController } from \"../../../hooks\";\n\ninterface DateTimeFilterFieldProps {\n    name: string,\n    mode?: \"date\" | \"date_time\",\n    value?: [op: VirtualTableWhereFilterOp, fieldValue: any];\n    setValue: (value?: [op: VirtualTableWhereFilterOp, newValue: any]) => void;\n    isArray?: boolean;\n    title?: string;\n}\n\nconst operationLabels: Record<VirtualTableWhereFilterOp, string> = {\n    \"==\": \"==\",\n    \"!=\": \"!=\",\n    \">\": \">\",\n    \"<\": \"<\",\n    \">=\": \">=\",\n    \"<=\": \"<=\",\n    \"not-in\": \"not in\",\n    in: \"in\",\n    \"array-contains\": \"Contains\",\n    \"array-contains-any\": \"Any\"\n};\n\nconst multipleSelectOperations = [\"array-contains-any\", \"in\"];\n\nexport function DateTimeFilterField({\n                                        name,\n                                        isArray,\n                                        mode,\n                                        value,\n                                        setValue,\n                                        title\n                                    }: DateTimeFilterFieldProps) {\n\n    const { locale } = useCustomizationController();\n    const possibleOperations: (keyof typeof operationLabels) [] = isArray\n        ? [\"array-contains\"]\n        : [\"==\", \"!=\", \">\", \"<\", \">=\", \"<=\"];\n\n    const [fieldOperation, fieldValue] = value || [possibleOperations[0], undefined];\n    const [operation, setOperation] = useState<VirtualTableWhereFilterOp>(fieldOperation);\n    const [internalValue, setInternalValue] = useState<Date | null | undefined>(fieldValue);\n\n    function updateFilter(op: VirtualTableWhereFilterOp, val: Date | undefined | null) {\n        let newValue: Date | null | undefined = val;\n        const prevOpIsArray = multipleSelectOperations.includes(operation);\n        const newOpIsArray = multipleSelectOperations.includes(op);\n        if (prevOpIsArray !== newOpIsArray) {\n            // @ts-ignore\n            newValue = newOpIsArray ? (val ? [val] : []) : \"\";\n        }\n\n        setOperation(op);\n        setInternalValue(newValue === null ? undefined : newValue);\n\n        const hasNewValue = newValue !== null && Array.isArray(newValue)\n            ? newValue.length > 0\n            : newValue !== undefined;\n        if (op && hasNewValue) {\n            setValue(\n                [op, newValue]\n            );\n        } else {\n            setValue(\n                undefined\n            );\n        }\n    }\n\n    return (\n\n        <div className=\"flex w-[440px]\">\n            <div className=\"w-[80px]\">\n                <Select value={operation}\n                        onValueChange={(value) => {\n                            updateFilter(value as VirtualTableWhereFilterOp, internalValue);\n                        }}\n                        renderValue={(op) => operationLabels[op as VirtualTableWhereFilterOp]}>\n                    {possibleOperations.map((op) => (\n                        <SelectItem key={op} value={op}>\n                            {operationLabels[op]}\n                        </SelectItem>\n                    ))}\n                </Select>\n            </div>\n\n            <div className=\"flex-grow ml-2 flex flex-col gap-2\">\n\n                <DateTimeField\n                    mode={mode}\n                    size={\"medium\"}\n                    locale={locale}\n                    value={internalValue ?? undefined}\n                    onChange={(dateValue: Date | undefined) => {\n                        updateFilter(operation, dateValue === null ? undefined : dateValue);\n                    }}\n                    clearable={true}\n                />\n\n                <Label\n                    className=\"border cursor-pointer rounded-md p-2 flex items-center gap-2 [&:has(:checked)]:bg-gray-100 dark:[&:has(:checked)]:bg-gray-800\"\n                    htmlFor=\"null-filter\"\n                >\n                    <Checkbox id=\"null-filter\"\n                              checked={internalValue === null}\n                              size={\"small\"}\n                              onCheckedChange={(checked) => {\n                                  if (internalValue !== null)\n                                      updateFilter(operation, null);\n                                  else updateFilter(operation, undefined);\n                              }}/>\n                    Filter for null values\n                </Label>\n\n            </div>\n\n        </div>\n    );\n\n}\n","import React, { useCallback, useEffect, useRef } from \"react\";\nimport equal from \"react-fast-compare\";\nimport {\n    CollectionSize,\n    Entity,\n    EntityTableController,\n    FilterValues,\n    ResolvedProperty,\n    SelectedCellProps\n} from \"../../types\";\nimport { CellRendererParams, VirtualTable, VirtualTableColumn } from \"../VirtualTable\";\nimport { enumToObjectEntries } from \"../../util\";\nimport { OnCellValueChange, OnColumnResizeParams } from \"../common\";\nimport { FilterFormFieldProps } from \"../VirtualTable/VirtualTableHeader\";\nimport { ReferenceFilterField } from \"./filters/ReferenceFilterField\";\nimport { StringNumberFilterField } from \"./filters/StringNumberFilterField\";\nimport { BooleanFilterField } from \"./filters/BooleanFilterField\";\nimport { DateTimeFilterField } from \"./filters/DateTimeFilterField\";\nimport { useOutsideAlerter } from \"@firecms/ui\";\nimport { SelectableTableContext } from \"./SelectableTableContext\";\n\nexport type SelectableTableProps<M extends Record<string, any>> = {\n\n    /**\n     * Callback when a cell value changes.\n     */\n    onValueChange?: OnCellValueChange<any, M>;\n\n    columns: VirtualTableColumn[];\n\n    cellRenderer: React.ComponentType<CellRendererParams<Entity<M>>>;\n\n    /**\n     * Builder for creating the buttons in each row\n     * @param entity\n     * @param size\n     */\n    tableRowActionsBuilder?: (params: {\n        entity: Entity<M>,\n        size: CollectionSize,\n        width: number,\n        frozen?: boolean\n    }) => React.ReactNode;\n\n    /**\n     * Callback when anywhere on the table is clicked\n     */\n    onEntityClick?(entity: Entity<M>): void;\n\n    /**\n     * Callback when a column is resized\n     */\n    onColumnResize?(params: OnColumnResizeParams): void;\n\n    /**\n     * Should apply a different style to a row when hovering\n     */\n    hoverRow?: boolean;\n\n    /**\n     * Controller holding the logic for the table\n     * {@link useDataSourceEntityCollectionTableController}\n     * {@link EntityTableController}\n     */\n    tableController: EntityTableController<M>;\n\n    filterable?: boolean;\n\n    sortable?: boolean;\n\n    inlineEditing?: boolean;\n\n    forceFilter?: FilterValues<keyof M extends string ? keyof M : never>;\n\n    highlightedRow?: (data: Entity<M>) => boolean;\n\n    size?: CollectionSize;\n\n    emptyComponent?: React.ReactNode;\n\n    endAdornment?: React.ReactNode;\n\n    AddColumnComponent?: React.ComponentType;\n}\n\n/**\n * This component is in charge of rendering a collection table with a high\n * degree of customization.\n *\n * This component is used internally by {@link EntityCollectionView} and\n * {@link useReferenceDialog}\n *\n * Please note that you only need to use this component if you are building\n * a custom view. If you just need to create a default view you can do it\n * exclusively with config options.\n *\n * If you want to bind a {@link EntityCollection} to a table with the default\n * options you see in collections in the top level navigation, you can\n * check {@link EntityCollectionView}.\n *\n * The data displayed in the table is managed by a {@link EntityTableController}.\n * You can build the default, bound to a path in the datasource, by using the hook\n * {@link useDataSourceEntityCollectionTableController}\n *\n * @see EntityCollectionTableProps\n * @see EntityCollectionView\n * @see VirtualTable\n * @group Components\n */\nexport const SelectableTable = React.memo<SelectableTableProps<any>>(\n    function SelectableTable<M extends Record<string, any>>\n    ({\n         onValueChange,\n         cellRenderer,\n         onEntityClick,\n         onColumnResize,\n         hoverRow = true,\n         size,\n         inlineEditing = false,\n         tableController:\n             {\n                 data,\n                 dataLoading,\n                 noMoreToLoad,\n                 dataLoadingError,\n                 filterValues,\n                 setFilterValues,\n                 sortBy,\n                 setSortBy,\n                 setSearchString,\n                 clearFilter,\n                 itemCount,\n                 setItemCount,\n                 pageSize = 50,\n                 paginationEnabled,\n                 checkFilterCombination,\n                 setPopupCell\n             },\n         filterable = true,\n         emptyComponent,\n         columns,\n         forceFilter,\n         highlightedRow,\n         endAdornment,\n         AddColumnComponent\n     }: SelectableTableProps<M>) {\n\n        const ref = useRef<HTMLDivElement>(null);\n\n        const [selectedCell, setSelectedCell] = React.useState<SelectedCellProps<M> | undefined>(undefined);\n\n        const loadNextPage = () => {\n            if (!paginationEnabled || dataLoading || noMoreToLoad)\n                return;\n            if (itemCount !== undefined)\n                setItemCount?.(itemCount + pageSize);\n        };\n\n        const resetPagination = useCallback(() => {\n            setItemCount?.(pageSize);\n        }, [pageSize]);\n\n        const onRowClick = useCallback(({ rowData }: {\n            rowData: Entity<M>\n        }) => {\n            if (inlineEditing)\n                return;\n            return onEntityClick && onEntityClick(rowData);\n        }, [onEntityClick, inlineEditing]);\n\n        useOutsideAlerter(ref,\n            () => {\n                if (selectedCell) {\n                    unselect();\n                }\n            },\n            Boolean(selectedCell));\n\n        // on ESC key press\n        useEffect(() => {\n            const escFunction = (event: any) => {\n                if (event.keyCode === 27) {\n                    unselect();\n                }\n            };\n            document.addEventListener(\"keydown\", escFunction, false);\n            return () => {\n                document.removeEventListener(\"keydown\", escFunction, false);\n            };\n        });\n\n        const select = useCallback((cell?: SelectedCellProps<M>) => {\n            setSelectedCell(cell);\n        }, []);\n\n        const unselect = useCallback(() => {\n            setSelectedCell(undefined);\n        }, []);\n\n        const onFilterUpdate = useCallback((updatedFilterValues?: FilterValues<any>) => {\n            setFilterValues?.({ ...updatedFilterValues, ...forceFilter } as FilterValues<any>);\n        }, [forceFilter]);\n\n        return (\n            <SelectableTableContext.Provider\n                value={{\n                    setPopupCell: setPopupCell as ((cell?: SelectedCellProps<M>) => void),\n                    select,\n                    onValueChange,\n                    size: size ?? \"m\",\n                    selectedCell,\n                }}\n            >\n                <div className=\"h-full w-full flex flex-col bg-white dark:bg-gray-950\"\n                     ref={ref}>\n\n                    <VirtualTable\n                        data={data}\n                        columns={columns}\n                        cellRenderer={cellRenderer}\n                        onRowClick={inlineEditing ? undefined : (onEntityClick ? onRowClick : undefined)}\n                        onEndReached={loadNextPage}\n                        onResetPagination={resetPagination}\n                        error={dataLoadingError}\n                        paginationEnabled={paginationEnabled}\n                        onColumnResize={onColumnResize}\n                        size={size}\n                        loading={dataLoading}\n                        filter={filterValues}\n                        onFilterUpdate={setFilterValues ? onFilterUpdate : undefined}\n                        sortBy={sortBy}\n                        onSortByUpdate={setSortBy as ((sortBy?: [string, \"asc\" | \"desc\"]) => void)}\n                        hoverRow={hoverRow}\n                        checkFilterCombination={checkFilterCombination}\n                        createFilterField={filterable ? createFilterField : undefined}\n                        rowClassName={useCallback((entity: Entity<M>) => {\n                            return highlightedRow?.(entity) ? \"bg-gray-100 bg-opacity-75 dark:bg-gray-800 dark:bg-opacity-75\" : \"\";\n                        }, [highlightedRow])}\n                        className=\"flex-grow\"\n                        emptyComponent={emptyComponent}\n                        endAdornment={endAdornment}\n                        AddColumnComponent={AddColumnComponent}\n                    />\n\n                </div>\n            </SelectableTableContext.Provider>\n        );\n\n    },\n    equal\n);\n\nfunction createFilterField({\n                               id,\n                               filterValue,\n                               setFilterValue,\n                               column,\n                               hidden,\n                               setHidden\n                           }: FilterFormFieldProps<{\n    resolvedProperty: ResolvedProperty,\n    disabled: boolean,\n}>): React.ReactNode {\n\n    if (!column.custom) {\n        return null;\n    }\n\n    const { resolvedProperty } = column.custom;\n\n    const isArray = resolvedProperty?.dataType === \"array\";\n    const baseProperty: ResolvedProperty = isArray ? resolvedProperty.of : resolvedProperty;\n    if (!baseProperty) {\n        return null;\n    }\n    if (baseProperty.dataType === \"reference\") {\n        return <ReferenceFilterField value={filterValue}\n                                     setValue={setFilterValue}\n                                     name={id as string}\n                                     isArray={isArray}\n                                     path={baseProperty.path}\n                                     title={resolvedProperty?.name}\n                                     previewProperties={baseProperty?.previewProperties}\n                                     hidden={hidden}\n                                     setHidden={setHidden}/>;\n    } else if (baseProperty.dataType === \"number\" || baseProperty.dataType === \"string\") {\n        const name = baseProperty.name;\n        const enumValues = baseProperty.enumValues ? enumToObjectEntries(baseProperty.enumValues) : undefined;\n        return <StringNumberFilterField value={filterValue}\n                                        setValue={setFilterValue}\n                                        name={id as string}\n                                        dataType={baseProperty.dataType}\n                                        isArray={isArray}\n                                        enumValues={enumValues}\n                                        title={name}/>;\n    } else if (baseProperty.dataType === \"boolean\") {\n        const name = baseProperty.name;\n        return <BooleanFilterField value={filterValue}\n                                   setValue={setFilterValue}\n                                   name={id as string}\n                                   title={name}/>;\n\n    } else if (baseProperty.dataType === \"date\") {\n        const title = baseProperty.name;\n        return <DateTimeFilterField value={filterValue}\n                                    setValue={setFilterValue}\n                                    name={id as string}\n                                    mode={baseProperty.mode}\n                                    isArray={isArray}\n                                    title={title}/>;\n    }\n\n    return (\n        <div>{`Currently the filter field ${resolvedProperty.dataType} is not supported`}</div>\n    );\n}\n\nfunction filterableProperty(property: ResolvedProperty, partOfArray = false): boolean {\n    if (partOfArray) {\n        return [\"string\", \"number\", \"date\", \"reference\"].includes(property.dataType);\n    }\n    if (property.dataType === \"array\") {\n        if (property.of)\n            return filterableProperty(property.of, true);\n        else\n            return false;\n    }\n    return [\"string\", \"number\", \"boolean\", \"date\", \"reference\", \"array\"].includes(property.dataType);\n}\n","import React, { useCallback, useMemo, useRef } from \"react\";\nimport { AdditionalFieldDelegate, CollectionSize, Entity, FireCMSContext, User } from \"../../types\";\nimport { PropertyTableCell } from \"./PropertyTableCell\";\nimport { ErrorBoundary } from \"../ErrorBoundary\";\nimport { useFireCMSContext, useLargeLayout } from \"../../hooks\";\nimport { CellRendererParams, VirtualTableColumn } from \"../VirtualTable\";\nimport { getValueInPath } from \"../../util\";\nimport { getRowHeight } from \"../VirtualTable/common\";\nimport { EntityCollectionRowActions } from \"./EntityCollectionRowActions\";\nimport { CollectionTableToolbar } from \"./internal/CollectionTableToolbar\";\nimport { EntityCollectionTableProps } from \"./EntityCollectionTableProps\";\nimport { EntityTableCell } from \"./internal/EntityTableCell\";\nimport { CustomFieldValidator } from \"../../form/validation\";\nimport { renderSkeletonText } from \"../../preview\";\nimport { propertiesToColumns } from \"./column_utils\";\nimport { ErrorView } from \"../ErrorView\";\nimport { SelectableTable } from \"../SelectableTable/SelectableTable\";\nimport { cn } from \"@firecms/ui\";\n\n/**\n * This component is in charge of rendering a collection table with a high\n * degree of customization.\n *\n * This component is used internally by {@link EntityCollectionView} and\n * {@link useReferenceDialog}\n *\n * Please note that you only need to use this component if you are building\n * a custom view. If you just need to create a default view you can do it\n * exclusively with config options.\n *\n * If you want to bind a {@link EntityCollection} to a table with the default\n * options you see in collections in the top level navigation, you can\n * check {@link EntityCollectionView}.\n *\n * The data displayed in the table is managed by a {@link EntityTableController}.\n * You can build the default, bound to a path in the datasource, by using the hook\n * {@link useDataSourceEntityCollectionTableController}\n *\n * @see EntityCollectionTableProps\n * @see EntityCollectionView\n * @see VirtualTable\n * @group Components\n */\nexport const EntityCollectionTable = function EntityCollectionTable<M extends Record<string, any>, UserType extends User>\n({\n     className,\n     style,\n     forceFilter,\n     actionsStart,\n     actions,\n     title,\n     tableRowActionsBuilder,\n     uniqueFieldValidator,\n     getPropertyFor,\n     onValueChange,\n     selectionController,\n     highlightedEntities,\n     onEntityClick,\n     onColumnResize,\n     onSizeChanged,\n     textSearchEnabled = false,\n     hoverRow = true,\n     inlineEditing = false,\n     additionalFields,\n     displayedColumnIds,\n     defaultSize,\n     properties,\n     tableController,\n     filterable = true,\n     sortable = true,\n     endAdornment,\n     AddColumnComponent,\n     AdditionalHeaderWidget,\n     additionalIDHeaderWidget,\n     emptyComponent,\n     getIdColumnWidth,\n     onTextSearchClick,\n     textSearchLoading,\n     enablePopupIcon\n }: EntityCollectionTableProps<M>) {\n\n    const ref = useRef<HTMLDivElement>(null);\n\n    const largeLayout = useLargeLayout();\n    const selectedEntities = (selectionController?.selectedEntities?.length > 0 ? selectionController?.selectedEntities : highlightedEntities)?.filter(Boolean);\n\n    const context: FireCMSContext<UserType> = useFireCMSContext();\n\n    const [size, setSize] = React.useState<CollectionSize>(defaultSize ?? \"m\");\n\n    const selectedEntityIds = selectedEntities?.map(e => e.id);\n\n    const updateSize = useCallback((size: CollectionSize) => {\n        if (onSizeChanged)\n            onSizeChanged(size);\n        setSize(size);\n    }, []);\n\n    const onTextSearch = useCallback((newSearchString?: string) => tableController.setSearchString?.(newSearchString), []);\n\n    const additionalFieldsMap: Record<string, AdditionalFieldDelegate<M, UserType>> = useMemo(() => {\n        return (additionalFields\n            ? additionalFields\n                .map((aC) => ({ [aC.key]: aC as AdditionalFieldDelegate<M, any> }))\n                .reduce((a, b) => ({ ...a, ...b }), {})\n            : {}) as Record<string, AdditionalFieldDelegate<M, UserType>>;\n    }, [additionalFields]);\n\n    const customFieldValidator: CustomFieldValidator | undefined = uniqueFieldValidator;\n\n    const propertyCellRenderer = ({\n                                      column,\n                                      columnIndex,\n                                      rowData,\n                                      rowIndex\n                                  }: CellRendererParams<any>) => {\n\n        const entity: Entity<M> = rowData;\n\n        const propertyKey = column.key;\n\n        let disabled = column.custom?.disabled;\n        const property = getPropertyFor?.({\n            propertyKey,\n            entity\n        }) ?? column.custom.resolvedProperty;\n        if (!property?.disabled) {\n            disabled = false;\n        }\n\n        if (!property) {\n            return null;\n        }\n\n        return (\n            <ErrorBoundary>\n                {entity\n                    ? <PropertyTableCell\n                        key={`property_table_cell_${entity.id}_${propertyKey}`}\n                        readonly={!inlineEditing}\n                        align={column.align ?? \"left\"}\n                        propertyKey={propertyKey as string}\n                        property={property}\n                        value={entity?.values ? getValueInPath(entity.values, propertyKey) : undefined}\n                        customFieldValidator={customFieldValidator}\n                        columnIndex={columnIndex}\n                        width={column.width}\n                        height={getRowHeight(size)}\n                        entity={entity}\n                        disabled={disabled}\n                        enablePopupIcon={enablePopupIcon}\n                        path={entity.path}/>\n                    : renderSkeletonText()\n                }\n            </ErrorBoundary>);\n\n    };\n\n    const additionalCellRenderer = useCallback(({\n                                                    column,\n                                                    rowData,\n                                                    width\n                                                }: CellRendererParams<any>) => {\n\n        const entity: Entity<M> = rowData;\n\n        const additionalField = additionalFieldsMap[column.key as string];\n        const value = additionalField.dependencies\n            ? Object.entries(entity.values)\n                .filter(([key, value]) => additionalField.dependencies!.includes(key as Extract<keyof M, string>))\n                .reduce((a, b) => ({ ...a, ...b }), {})\n            : entity;\n\n        const Builder = additionalField.Builder;\n        if (!Builder && !additionalField.value) {\n            throw new Error(\"When using additional fields you need to provide a Builder or a value\");\n        }\n\n        const child = Builder\n            ? <Builder entity={entity} context={context}/>\n            : <>{additionalField.value?.({\n                entity,\n                context\n            })}</>;\n\n        return (\n            <EntityTableCell\n                key={`additional_table_cell_${entity.id}_${column.key}`}\n                width={width}\n                size={size}\n                value={value}\n                selected={false}\n                disabled={true}\n                align={\"left\"}\n                allowScroll={false}\n                showExpandIcon={false}\n                disabledTooltip={\"This column can't be edited directly\"}\n            >\n                <ErrorBoundary>\n                    {child}\n                </ErrorBoundary>\n            </EntityTableCell>\n        );\n\n    }, [size, selectedEntityIds]);\n\n    const collectionColumns: VirtualTableColumn[] = (() => {\n        const columnsResult: VirtualTableColumn[] = propertiesToColumns({\n            properties,\n            sortable,\n            forceFilter,\n            AdditionalHeaderWidget\n        });\n\n        const additionalTableColumns: VirtualTableColumn[] = additionalFields\n            ? additionalFields.map((additionalField) =>\n                ({\n                    key: additionalField.key,\n                    align: \"left\",\n                    sortable: false,\n                    title: additionalField.name,\n                    width: additionalField.width ?? 200\n                }))\n            : [];\n        return [...columnsResult, ...additionalTableColumns];\n    })();\n\n    const idColumn: VirtualTableColumn = {\n        key: \"id_ewcfedcswdf3\",\n        width: getIdColumnWidth?.() ?? (largeLayout ? 160 : 130),\n        title: \"ID\",\n        resizable: false,\n        frozen: largeLayout,\n        headerAlign: \"center\",\n        align: \"center\",\n        AdditionalHeaderWidget: () => additionalIDHeaderWidget\n    }\n\n    const columns: VirtualTableColumn[] = [\n        idColumn,\n        ...(displayedColumnIds\n            ? displayedColumnIds\n                .map((p) => {\n                    return collectionColumns.find(c => c.key === p.key);\n                }).filter(Boolean)\n            : collectionColumns) as VirtualTableColumn[]\n    ];\n\n    const cellRenderer = (props: CellRendererParams<any>) => {\n        const column = props.column;\n        const columns = props.columns;\n        const columnKey = column.key;\n\n        try {\n            if (props.columnIndex === 0) {\n                if (tableRowActionsBuilder)\n                    return tableRowActionsBuilder({\n                        entity: props.rowData,\n                        size,\n                        width: column.width,\n                        frozen: column.frozen\n                    });\n                else\n                    return <EntityCollectionRowActions entity={props.rowData}\n                                                       width={column.width}\n                                                       frozen={column.frozen}\n                                                       isSelected={false}\n                                                       size={size}/>;\n            } else if (additionalFieldsMap[columnKey]) {\n                return additionalCellRenderer(props);\n            } else if (props.columnIndex < columns.length + 1) {\n                return propertyCellRenderer(props);\n            } else {\n                throw Error(\"Internal: columns not mapped properly\");\n            }\n        } catch (e: any) {\n            console.error(\"Error rendering cell\", e);\n            return <EntityTableCell\n                size={size}\n                width={column.width}\n                saved={false}\n                value={null}\n                align={\"left\"}\n                fullHeight={false}\n                disabled={true}>\n                <ErrorView error={e}/>\n            </EntityTableCell>;\n        }\n    }\n\n    return (\n\n        <div ref={ref}\n             style={style}\n             className={cn(\"h-full w-full flex flex-col bg-white dark:bg-gray-950\", className)}>\n\n            <CollectionTableToolbar\n                onTextSearch={textSearchEnabled ? onTextSearch : undefined}\n                textSearchLoading={textSearchLoading}\n                onTextSearchClick={textSearchEnabled ? onTextSearchClick : undefined}\n                size={size}\n                onSizeChanged={updateSize}\n                title={title}\n                actionsStart={actionsStart}\n                actions={actions}\n                loading={tableController.dataLoading}/>\n\n            <SelectableTable columns={columns}\n                             size={size}\n                             inlineEditing={inlineEditing}\n                             cellRenderer={cellRenderer}\n                             onEntityClick={onEntityClick}\n                             highlightedRow={useCallback((entity: Entity<M>) => selectedEntityIds?.includes(entity.id) ?? false, [selectedEntityIds])}\n                             tableController={tableController}\n                             onValueChange={onValueChange}\n                             onColumnResize={onColumnResize}\n                             hoverRow={hoverRow}\n                             filterable={filterable}\n                             emptyComponent={emptyComponent}\n                             endAdornment={endAdornment}\n                             AddColumnComponent={AddColumnComponent}/>\n\n        </div>\n    );\n\n};\n","import React from \"react\";\nimport equal from \"react-fast-compare\";\n\n/**\n * Hack to prevent data updates for incomplete callbacks from Firestore\n * triggers.\n * If any deps change, the update is immediate\n * @param data\n * @param deps\n * @param timeoutMs\n */\nexport function useDebouncedData<T>(data: T[], deps: any, timeoutMs = 5000) {\n\n    const [deferredData, setDeferredData] = React.useState(data);\n    const dataLength = React.useRef(deferredData.length ?? 0);\n    const pendingUpdate = React.useRef(false);\n    const currentDeps = React.useRef(deps);\n\n    const haveDepsChanged = !equal(currentDeps.current, deps);\n    const immediateUpdate = data.length >= dataLength.current || haveDepsChanged;\n\n    React.useEffect(() => {\n\n        const performUpdate = () => {\n            if (!equal(deferredData, data)) {\n                currentDeps.current = deps;\n                dataLength.current = data.length;\n                setDeferredData(data);\n            }\n            pendingUpdate.current = false;\n        };\n\n        pendingUpdate.current = true;\n\n        let handler: any;\n        if (immediateUpdate)\n            performUpdate()\n        else\n            handler = setTimeout(performUpdate, timeoutMs);\n\n        return () => {\n            clearTimeout(handler);\n            if (pendingUpdate.current && immediateUpdate)\n                performUpdate();\n        };\n    }, [data, timeoutMs, deps, immediateUpdate]);\n\n    return immediateUpdate ? data : deferredData;\n}\n","import React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { useDataSource, useFireCMSContext, useNavigationController } from \"../../hooks\";\nimport { useDataOrder } from \"../../hooks/data/useDataOrder\";\nimport {\n    Entity,\n    EntityCollection,\n    EntityTableController,\n    FilterValues,\n    FireCMSContext,\n    SelectedCellProps,\n    User\n} from \"../../types\";\nimport { useDebouncedData } from \"./useDebouncedData\";\nimport equal from \"react-fast-compare\"\n\nconst DEFAULT_PAGE_SIZE = 50;\n\nexport type DataSourceEntityCollectionTableControllerProps<M extends Record<string, any> = any> = {\n    /**\n     * Full path where the data of this table is located\n     */\n    fullPath: string;\n    /**\n     * The collection that is represented by this config.\n     */\n    collection: EntityCollection<M>;\n    /**\n     * List of entities that will be displayed on top, no matter the ordering.\n     * This is used for reference fields selection\n     */\n    entitiesDisplayedFirst?: Entity<M>[];\n\n    lastDeleteTimestamp?: number;\n\n    /**\n     * Force filter to be applied to the table.\n     */\n    forceFilter?: FilterValues<string>;\n}\n\n/**\n * Use this hook to build a controller for the {@link EntityCollectionTable}.\n * This controller is bound to data in a path in your specified datasource.\n *\n * Note that you can build your own hook returning a {@link EntityTableController}\n * if you would like to display different data.\n *\n * @param fullPath\n * @param collection\n * @param entitiesDisplayedFirst\n * @param lastDeleteTimestamp\n * @param forceFilterFromProps\n */\nexport function useDataSourceEntityCollectionTableController<M extends Record<string, any> = any, UserType extends User = User>(\n    {\n        fullPath,\n        collection,\n        entitiesDisplayedFirst,\n        lastDeleteTimestamp,\n        forceFilter: forceFilterFromProps,\n    }: DataSourceEntityCollectionTableControllerProps<M>)\n    : EntityTableController<M> {\n\n    const {\n        initialFilter,\n        initialSort,\n        forceFilter: forceFilterFromCollection\n    } = collection;\n\n    const [popupCell, setPopupCell] = React.useState<SelectedCellProps<M> | undefined>(undefined);\n    const navigation = useNavigationController();\n    const dataSource = useDataSource(collection);\n    const resolvedPath = useMemo(() => navigation.resolveAliasesFrom(fullPath), [fullPath, navigation.resolveAliasesFrom]);\n\n    const forceFilter = forceFilterFromProps ?? forceFilterFromCollection;\n    const paginationEnabled = collection.pagination === undefined || Boolean(collection.pagination);\n    const pageSize = typeof collection.pagination === \"number\" ? collection.pagination : DEFAULT_PAGE_SIZE;\n\n    const [searchString, setSearchString] = React.useState<string | undefined>();\n    const [itemCount, setItemCount] = React.useState<number | undefined>(paginationEnabled ? pageSize : undefined);\n\n    const initialSortInternal = useMemo(() => {\n        if (initialSort && forceFilter && !checkFilterCombination(forceFilter, initialSort)) {\n            console.warn(\"Initial sort is not compatible with the force filter. Ignoring initial sort\");\n            return undefined;\n        }\n        return initialSort;\n    }, [initialSort, forceFilter]);\n\n    useEffect(() => {\n        if (!equal(forceFilter, filterValues)) {\n            setFilterValues(forceFilter)\n        }\n    }, [forceFilter]);\n\n    const [filterValues, setFilterValues] = React.useState<FilterValues<Extract<keyof M, string>> | undefined>(forceFilter ?? initialFilter ?? undefined);\n    const [sortBy, setSortBy] = React.useState<[Extract<keyof M, string>, \"asc\" | \"desc\"] | undefined>(initialSortInternal);\n\n    const sortByProperty = sortBy ? sortBy[0] : undefined;\n    const currentSort = sortBy ? sortBy[1] : undefined;\n\n    const context: FireCMSContext<UserType> = useFireCMSContext();\n\n    const [rawData, setRawData] = useState<Entity<M>[]>([]);\n\n    const [dataLoading, setDataLoading] = useState<boolean>(false);\n    const [dataLoadingError, setDataLoadingError] = useState<Error | undefined>();\n    const [noMoreToLoad, setNoMoreToLoad] = useState<boolean>(false);\n\n    const checkFilterCombination = useCallback((filterValues: FilterValues<any>,\n                                                sortBy?: [string, \"asc\" | \"desc\"]) => {\n        if (!dataSource.isFilterCombinationValid)\n            return true;\n        return dataSource.isFilterCombinationValid({\n            path: resolvedPath,\n            collection,\n            filterValues,\n            sortBy\n        })\n    }, []);\n\n    const clearFilter = useCallback(() => setFilterValues(forceFilter ?? undefined), [forceFilter]);\n\n    const updateFilterValues = useCallback((updatedFilter: FilterValues<Extract<keyof M, string>> | undefined) => {\n        if (forceFilter) {\n            console.warn(\"Filter is not compatible with the force filter. Ignoring filter\");\n            return;\n        }\n        if (updatedFilter && Object.keys(updatedFilter).length === 0) {\n            setFilterValues(undefined);\n        } else {\n            setFilterValues(updatedFilter);\n        }\n    }, [forceFilter]);\n\n    useEffect(() => {\n\n        setDataLoading(true);\n\n        const onEntitiesUpdate = async (entities: Entity<M>[]) => {\n            if (collection.callbacks?.onFetch) {\n                try {\n                    entities = await Promise.all(\n                        entities.map((entity) =>\n                            collection.callbacks!.onFetch!({\n                                collection,\n                                path: resolvedPath,\n                                entity,\n                                context\n                            })));\n                } catch (e: any) {\n                    console.error(e);\n                }\n            }\n            setDataLoading(false);\n            setDataLoadingError(undefined);\n            setRawData(entities.map(e => ({\n                ...e,\n                // values: sanitizeData(e.values, resolvedCollection.properties)\n            })));\n            setNoMoreToLoad(!itemCount || entities.length < itemCount);\n        };\n\n        const onError = (error: Error) => {\n            console.error(\"ERROR\", error);\n            setDataLoading(false);\n            setRawData([]);\n            setDataLoadingError(error);\n        };\n\n        if (dataSource.listenCollection) {\n            return dataSource.listenCollection<M>({\n                path: resolvedPath,\n                collection,\n                onUpdate: onEntitiesUpdate,\n                onError,\n                searchString,\n                filter: filterValues,\n                limit: itemCount,\n                startAfter: undefined,\n                orderBy: sortByProperty,\n                order: currentSort\n            });\n        } else {\n            dataSource.fetchCollection<M>({\n                path: resolvedPath,\n                collection,\n                searchString,\n                filter: filterValues,\n                limit: itemCount,\n                startAfter: undefined,\n                orderBy: sortByProperty,\n                order: currentSort\n            })\n                .then(onEntitiesUpdate)\n                .catch(onError);\n            return () => {\n            };\n        }\n    }, [resolvedPath, itemCount, currentSort, sortByProperty, filterValues, searchString]);\n\n    const orderedData = useDataOrder({\n        data: rawData,\n        entitiesDisplayedFirst\n    });\n\n    // hack to fix Firestore listeners firing with incomplete data\n    const data = useDebouncedData(orderedData, {\n        filterValues,\n        sortBy,\n        searchString,\n        lastDeleteTimestamp\n    });\n\n    return {\n        data,\n        dataLoading,\n        noMoreToLoad,\n        dataLoadingError,\n        filterValues,\n        setFilterValues: updateFilterValues,\n        sortBy,\n        setSortBy,\n        searchString,\n        setSearchString,\n        clearFilter,\n        itemCount,\n        setItemCount,\n        paginationEnabled,\n        pageSize,\n        checkFilterCombination,\n        popupCell,\n        setPopupCell\n    }\n}\n","import { Entity } from \"../../types\";\n\nexport interface DataOrderProps<M extends Record<string, any>> {\n    data: Entity<M>[];\n    entitiesDisplayedFirst?: Entity<M>[];\n}\n\n/**\n * This hook is used to have some entities at the beginning of data.\n * @param path\n * @param entitiesDisplayedFirst\n * @group Hooks and utilities\n */\nexport function useDataOrder<M extends Record<string, any>>(\n    {\n        data,\n        entitiesDisplayedFirst\n    }: DataOrderProps<M>): Entity<M>[] {\n\n    if (!entitiesDisplayedFirst)\n        return data;\n\n    const displayedFirstId = new Set(entitiesDisplayedFirst.map((e) => e.id));\n    return [...entitiesDisplayedFirst, ...data.filter((e) => !displayedFirstId.has(e.id))];\n\n}\n","import { useCallback, useState } from \"react\";\nimport { Entity, SelectionController } from \"../../types\";\n\nexport function useSelectionController<M extends Record<string, any> = any>(\n    onSelectionChange?: (entity: Entity<M>, selected: boolean) => void\n): SelectionController<M> {\n\n    const [selectedEntities, setSelectedEntities] = useState<Entity<M>[]>([]);\n\n    const toggleEntitySelection = useCallback((entity: Entity<M>) => {\n        let newValue;\n        if (selectedEntities.map(e => e.id).includes(entity.id)) {\n            onSelectionChange?.(entity, false);\n            newValue = selectedEntities.filter((item: Entity<M>) => item.id !== entity.id);\n        } else {\n            onSelectionChange?.(entity, true);\n            newValue = [...selectedEntities, entity];\n        }\n        setSelectedEntities(newValue);\n    }, [selectedEntities]);\n\n    const isEntitySelected = useCallback((entity: Entity<M>) => selectedEntities.map(e => e.id).includes(entity.id), [selectedEntities]);\n\n    return {\n        selectedEntities,\n        setSelectedEntities,\n        isEntitySelected,\n        toggleEntitySelection\n    };\n}\n","import { useState } from \"react\";\n\nimport { EntityCollection } from \"../../types\";\nimport { useCustomizationController, useFireCMSContext } from \"../../hooks\";\n\nexport interface UseTableSearchHelperParams<M extends Record<string, any>> {\n    collection: EntityCollection<M>;\n    fullPath: string;\n    parentCollectionIds?: string[];\n}\n\nexport function useTableSearchHelper<M extends Record<string, any>>({ collection, fullPath, parentCollectionIds }: UseTableSearchHelperParams<M>) {\n\n    const context = useFireCMSContext();\n    const customizationController = useCustomizationController();\n\n    const [textSearchLoading, setTextSearchLoading] = useState<boolean>(false);\n    const [textSearchInitialised, setTextSearchInitialised] = useState<boolean>(false);\n    let onTextSearchClick: (() => void) | undefined;\n    let textSearchEnabled = Boolean(collection.textSearchEnabled);\n    if (customizationController?.plugins) {\n        const addTextSearchClickListener = customizationController.plugins?.find(p => Boolean(p.collectionView?.onTextSearchClick));\n\n        onTextSearchClick = addTextSearchClickListener\n            ? () => {\n                setTextSearchLoading(true);\n                Promise.all(customizationController.plugins?.map(p => {\n                    if (p.collectionView?.onTextSearchClick)\n                        return p.collectionView.onTextSearchClick({ context, path: fullPath, collection, parentCollectionIds });\n                    return Promise.resolve(true);\n                }) as Promise<boolean>[])\n                    .then((res) => {\n                        if (res.every(Boolean)) setTextSearchInitialised(true);\n                    })\n                    .finally(() => setTextSearchLoading(false));\n            }\n            : undefined;\n\n        customizationController.plugins?.forEach(p => {\n            if (!textSearchEnabled)\n                if (p.collectionView?.showTextSearchBar) {\n                    textSearchEnabled = p.collectionView.showTextSearchBar({ context, path: fullPath, collection, parentCollectionIds });\n                }\n        })\n    }\n    return { textSearchLoading, textSearchInitialised, onTextSearchClick, textSearchEnabled };\n}\n","import { Entity, EntityCallbacks, EntityCollection } from \"../types\";\nimport React, { useCallback, useMemo, useState } from \"react\";\nimport { Button, CircularProgress, Dialog, DialogActions, DialogContent, Typography } from \"@firecms/ui\";\nimport {\n    deleteEntityWithCallbacks,\n    useCustomizationController,\n    useDataSource,\n    useFireCMSContext,\n    useSnackbarController\n} from \"../hooks\";\nimport { resolveCollection } from \"../util\";\nimport { EntityView } from \"./EntityView\";\n\nexport interface DeleteEntityDialogProps<M extends Record<string, any>> {\n    entityOrEntitiesToDelete?: Entity<M> | Entity<M>[],\n    path: string,\n    collection: EntityCollection<M>\n    open: boolean;\n    onClose: () => void;\n    callbacks?: EntityCallbacks<M>,\n\n    onEntityDelete?(path: string, entity: Entity<M>): void;\n\n    onMultipleEntitiesDelete?(path: string, entities: Entity<M>[]): void;\n}\n\nexport function DeleteEntityDialog<M extends Record<string, any>>({\n                                                                      entityOrEntitiesToDelete,\n                                                                      collection,\n                                                                      onClose,\n                                                                      open,\n                                                                      callbacks,\n                                                                      onEntityDelete,\n                                                                      onMultipleEntitiesDelete,\n                                                                      path\n                                                                  }: DeleteEntityDialogProps<M>) {\n\n    const dataSource = useDataSource(collection);\n    const customizationController = useCustomizationController();\n    const snackbarController = useSnackbarController();\n    const [loading, setLoading] = useState(false);\n\n    const [entityOrEntities, setUsedEntityOrEntities] = React.useState<Entity<M> | Entity<M>[]>();\n\n    const [multipleEntities, setMultipleEntities] = React.useState<boolean>();\n    const context = useFireCMSContext();\n\n    React.useEffect(() => {\n        if (entityOrEntitiesToDelete) {\n            const revisedEntityOrEntities = Array.isArray(entityOrEntitiesToDelete) && entityOrEntitiesToDelete.length === 1\n                ? entityOrEntitiesToDelete[0]\n                : entityOrEntitiesToDelete;\n            setUsedEntityOrEntities(revisedEntityOrEntities);\n            setMultipleEntities(Array.isArray(revisedEntityOrEntities));\n        }\n    }, [entityOrEntitiesToDelete]);\n\n    const resolvedCollection = useMemo(() => resolveCollection<M>({\n        collection,\n        path,\n        fields: customizationController.propertyConfigs\n    }), [collection, path]);\n\n    const handleCancel = useCallback(() => {\n        onClose();\n    }, [onClose]);\n\n    const onDeleteSuccess = useCallback((entity: Entity<any>) => {\n        console.debug(\"Deleted\", entity);\n    }, []);\n\n    const onDeleteFailure = useCallback((entity: Entity<any>, e: Error) => {\n        snackbarController.open({\n            type: \"error\",\n            message: \"Error deleting: \" + e?.message\n        });\n\n        console.error(\"Error deleting entity\");\n        console.error(e);\n    }, [resolvedCollection.name]);\n\n    const onPreDeleteHookError = useCallback((entity: Entity<any>, e: Error) => {\n        snackbarController.open({\n            type: \"error\",\n            message: \"Error before deleting: \" + e?.message\n        });\n        console.error(e);\n    }, [resolvedCollection.name]);\n\n    const onDeleteSuccessHookError = useCallback((entity: Entity<any>, e: Error) => {\n        snackbarController.open({\n            type: \"error\",\n            message: \"Error after deleting: \" + e?.message\n        });\n        console.error(e);\n    }, [resolvedCollection.name]);\n\n    const performDelete = useCallback((entity: Entity<M>): Promise<boolean> =>\n        deleteEntityWithCallbacks({\n            dataSource,\n            entity,\n            collection: resolvedCollection,\n            callbacks,\n            onDeleteSuccess,\n            onDeleteFailure,\n            onPreDeleteHookError,\n            onDeleteSuccessHookError,\n            context\n        }), [dataSource, resolvedCollection, callbacks, onDeleteSuccess, onDeleteFailure, onPreDeleteHookError, onDeleteSuccessHookError, context]);\n\n    const handleOk = useCallback(async () => {\n        if (entityOrEntities) {\n\n            setLoading(true);\n\n            if (multipleEntities) {\n                Promise.all((entityOrEntities as Entity<M>[]).map(performDelete)).then((results) => {\n\n                    setLoading(false);\n\n                    if (onMultipleEntitiesDelete && entityOrEntities)\n                        onMultipleEntitiesDelete(path, entityOrEntities as Entity<M>[]);\n\n                    if (results.every(Boolean)) {\n                        snackbarController.open({\n                            type: \"success\",\n                            message: `${resolvedCollection.name}: multiple deleted`\n                        });\n                    } else if (results.some(Boolean)) {\n                        snackbarController.open({\n                            type: \"warning\",\n                            message: `${resolvedCollection.name}: Some of the entities have been deleted, but not all`\n                        });\n                    } else {\n                        snackbarController.open({\n                            type: \"error\",\n                            message: `${resolvedCollection.name}: Error deleting entities`\n                        });\n                    }\n                    onClose();\n                });\n\n            } else {\n                performDelete(entityOrEntities as Entity<M>).then((success) => {\n                    setLoading(false);\n                    if (success) {\n                        if (onEntityDelete && entityOrEntities)\n                            onEntityDelete(path, entityOrEntities as Entity<M>);\n                        snackbarController.open({\n                            type: \"success\",\n                            message: `${resolvedCollection.singularName ?? resolvedCollection.name} deleted`\n                        });\n                        onClose();\n                    }\n                });\n            }\n        }\n    }, [entityOrEntities, multipleEntities, performDelete, onMultipleEntitiesDelete, path, onClose, snackbarController, resolvedCollection.name, onEntityDelete]);\n\n    let content: React.ReactNode;\n    if (entityOrEntities && multipleEntities) {\n        content = <>Multiple entities</>;\n    } else {\n        const entity = entityOrEntities as Entity<M> | undefined;\n        content = entity\n            ? <EntityView\n                entity={entity}\n                collection={collection}\n                path={path}/>\n            : <></>;\n    }\n\n    const dialogTitle = multipleEntities\n        ? <><b>{resolvedCollection.name}</b>: Confirm multiple delete?</>\n        : `Would you like to delete this ${resolvedCollection.singularName ?? resolvedCollection.name}?`;\n\n    return (\n        <Dialog\n            maxWidth={multipleEntities ? \"lg\" : \"2xl\"}\n            aria-labelledby=\"delete-dialog\"\n            open={open}\n            onOpenChange={(open) => !open ? onClose() : undefined}\n        >\n            <DialogContent fullHeight={true}>\n                <Typography variant={\"subtitle2\"} className={\"p-4\"}>\n                    {dialogTitle}\n                </Typography>\n\n                {!multipleEntities && <div className={\"p-4\"}>{content}</div>}\n            </DialogContent>\n            <DialogActions>\n\n                {loading && <CircularProgress size={\"small\"}/>}\n\n                <Button onClick={handleCancel}\n                        disabled={loading}\n                        variant=\"text\"\n                        color=\"primary\">\n                    Cancel\n                </Button>\n                <Button\n                    autoFocus\n                    disabled={loading}\n                    onClick={handleOk}\n                    variant=\"filled\"\n                    color=\"primary\">\n                    Ok\n                </Button>\n            </DialogActions>\n\n        </Dialog>\n    );\n}\n","import { ArchiveIcon, DeleteIcon, FileCopyIcon, KeyboardTabIcon, OpenInNewIcon } from \"@firecms/ui\";\nimport { EntityAction } from \"../../types\";\nimport { DeleteEntityDialog } from \"../DeleteEntityDialog\";\n\nexport const editEntityAction: EntityAction = {\n    icon: <KeyboardTabIcon/>,\n    name: \"Edit\",\n    collapsed: false,\n    onClick({\n                entity,\n                collection,\n                fullPath,\n                context,\n                highlightEntity,\n                unhighlightEntity,\n            }): Promise<void> {\n        highlightEntity?.(entity);\n        context.analyticsController?.onAnalyticsEvent?.(\"entity_click\", {\n            path: entity.path,\n            entityId: entity.id\n        });\n        const path = collection?.collectionGroup ? entity.path : (fullPath ?? entity.path);\n        context.sideEntityController.open({\n            entityId: entity.id,\n            path,\n            collection,\n            updateUrl: true,\n            onClose: () => unhighlightEntity?.(entity),\n        });\n        return Promise.resolve(undefined);\n    }\n}\n\nexport const copyEntityAction: EntityAction = {\n    icon: <FileCopyIcon/>,\n    name: \"Copy\",\n    onClick({\n                entity,\n                collection,\n                context,\n                highlightEntity,\n                unhighlightEntity,\n            }): Promise<void> {\n        highlightEntity?.(entity);\n        context.analyticsController?.onAnalyticsEvent?.(\"copy_entity_click\", {\n            path: entity.path,\n            entityId: entity.id\n        });\n        context.sideEntityController.open({\n            entityId: entity.id,\n            path: entity.path,\n            copy: true,\n            collection,\n            updateUrl: true,\n            onClose: () => unhighlightEntity?.(entity),\n        });\n        return Promise.resolve(undefined);\n    }\n}\n\nexport const archiveEntityAction: EntityAction = {\n    icon: <ArchiveIcon/>,\n    name: \"Archive\",\n    onClick({\n                entity,\n                collection,\n                context: {\n                    dataSource,\n                }\n            }): Promise<void> {\n        // Add your code here\n        return Promise.resolve(undefined);\n    }\n}\n\nexport const openWebsiteAction: EntityAction = {\n    icon: <OpenInNewIcon/>,\n    name: \"See in website\",\n    onClick({\n                entity,\n                collection,\n                context,\n            }): Promise<void> {\n        // open a new tab\n        window.open(`https://example.com/${entity.id}`, \"_blank\");\n        return Promise.resolve(undefined);\n    }\n}\n\nexport const deleteEntityAction: EntityAction = {\n    icon: <DeleteIcon/>,\n    name: \"Delete\",\n    onClick({\n                entity,\n                fullPath,\n                collection,\n                context,\n                selectionController,\n                onCollectionChange,\n                sideEntityController\n            }): Promise<void> {\n        const { closeDialog } = context.dialogsController.open({\n            key: \"delete_entity_dialog_\" + entity.id,\n            Component: ({ open }) => {\n                if (!collection || !fullPath)\n                    throw new Error(\"deleteEntityAction: Collection is undefined\");\n                return <DeleteEntityDialog\n                    entityOrEntitiesToDelete={entity}\n                    path={fullPath}\n                    collection={collection}\n                    callbacks={collection.callbacks}\n                    open={open}\n                    onEntityDelete={() => {\n                        context.analyticsController?.onAnalyticsEvent?.(\"single_entity_deleted\", {\n                            path: fullPath\n                        });\n                        selectionController?.setSelectedEntities(selectionController.selectedEntities.filter(e => e.id !== entity.id));\n                        onCollectionChange?.();\n                        sideEntityController?.close();\n                    }}\n                    onClose={closeDialog}/>;\n            }\n        })\n        return Promise.resolve(undefined);\n    }\n}\n","import React, { MouseEventHandler, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { CollectionSize, Entity, EntityCollection, FilterValues } from \"../../types\";\n\nimport {\n    EntityCollectionRowActions,\n    EntityCollectionTable,\n    useDataSourceEntityCollectionTableController\n} from \"../EntityCollectionTable\";\nimport {\n    useAuthController,\n    useCustomizationController,\n    useDataSource,\n    useLargeLayout,\n    useNavigationController,\n    useSideEntityController\n} from \"../../hooks\";\nimport { ErrorView } from \"../ErrorView\";\nimport { AddIcon, Button, DialogActions, Typography } from \"@firecms/ui\";\nimport { canCreateEntity, fullPathToCollectionSegments, resolveCollection } from \"../../util\";\nimport { useSelectionController } from \"../EntityCollectionView/useSelectionController\";\nimport { useColumnIds, useTableSearchHelper } from \"../common\";\nimport { useSideDialogContext } from \"../../core\";\nimport { useAnalyticsController } from \"../../hooks/useAnalyticsController\";\n\n/**\n * @group Components\n */\nexport interface ReferenceSelectionInnerProps<M extends Record<string, any>> {\n\n    /**\n     * Allow multiple selection of values\n     */\n    multiselect?: boolean;\n\n    /**\n     * Entity collection config\n     */\n    collection?: EntityCollection<M>;\n\n    /**\n     * Absolute path of the collection.\n     * May be not set if this hook is being used in a component and the path is\n     * dynamic. If not set, the dialog won't open.\n     */\n    path: string;\n\n    /**\n     * If you are opening the dialog for the first time, you can select some\n     * entity ids to be displayed first.\n     */\n    selectedEntityIds?: string[];\n\n    /**\n     * If `multiselect` is set to `false`, you will get the selected entity\n     * in this callback.\n     * @param entity\n     * @callback\n     */\n    onSingleEntitySelected?(entity: Entity<any> | null): void;\n\n    /**\n     * If `multiselect` is set to `true`, you will get the selected entities\n     * in this callback.\n     * @param entities\n     * @callback\n     */\n    onMultipleEntitiesSelected?(entities: Entity<any>[]): void;\n\n    /**\n     * Allow selection of entities that pass the given filter only.\n     */\n    forceFilter?: FilterValues<string>;\n\n    /**\n     * Use this description to indicate the user what to do in this dialog.\n     */\n    description?: React.ReactNode;\n\n    /**\n     * Maximum number of entities that can be selected.\n     */\n    maxSelection?: number;\n\n}\n\n/**\n * This component allows to select entities from a given collection.\n * You probably want to open this dialog as a side view using {@link useReferenceDialog}\n * @group Components\n */\nexport function ReferenceSelectionTable<M extends Record<string, any>>(\n    {\n        onSingleEntitySelected,\n        onMultipleEntitiesSelected,\n        multiselect,\n        collection,\n        path: pathInput,\n        selectedEntityIds: selectedEntityIdsProp,\n        description,\n        forceFilter,\n        maxSelection,\n    }: ReferenceSelectionInnerProps<M>) {\n\n    const sideDialogContext = useSideDialogContext();\n    const sideEntityController = useSideEntityController();\n    const navigation = useNavigationController();\n    const analyticsController = useAnalyticsController();\n    const customizationController = useCustomizationController();\n\n    const fullPath = navigation.resolveAliasesFrom(pathInput);\n\n    const dataSource = useDataSource(collection);\n\n    const [entitiesDisplayedFirst, setEntitiesDisplayedFirst] = useState<Entity<any>[]>([]);\n\n    const toggleEntitySelection = (entity: Entity<any>) => {\n        let newValue;\n        const selectedEntities = selectionController.selectedEntities;\n\n        analyticsController.onAnalyticsEvent?.(\"reference_selection_toggle\", {\n            path: fullPath,\n            entityId: entity.id\n        });\n        if (selectedEntities) {\n\n            if (selectedEntities.map((e) => e.id).indexOf(entity.id) > -1) {\n                newValue = selectedEntities.filter((item: Entity<any>) => item.id !== entity.id);\n            } else {\n                if (maxSelection && selectedEntities.length >= maxSelection)\n                    return;\n                newValue = [...selectedEntities, entity];\n            }\n            selectionController.setSelectedEntities(newValue);\n\n            if (onMultipleEntitiesSelected)\n                onMultipleEntitiesSelected(newValue);\n        }\n    };\n\n    const selectionController = useSelectionController(toggleEntitySelection);\n\n    /**\n     * Fetch initially selected ids\n     */\n    useEffect(() => {\n        let unmounted = false;\n        const selectedEntityIds = selectedEntityIdsProp?.map(id => id?.toString()).filter(Boolean);\n        if (selectedEntityIds && collection) {\n            Promise.all(\n                selectedEntityIds.map((entityId) =>\n                    dataSource.fetchEntity({\n                        path: fullPath,\n                        entityId,\n                        collection\n                    })))\n                .then((entities) => {\n                    if (!unmounted) {\n                        const result = entities.filter(e => e !== undefined) as Entity<any>[];\n                        selectionController.setSelectedEntities(result);\n                        setEntitiesDisplayedFirst(result);\n                    }\n                });\n        } else {\n            selectionController.setSelectedEntities([]);\n            setEntitiesDisplayedFirst([]);\n        }\n        return () => {\n            unmounted = true;\n        };\n    }, [dataSource, fullPath, selectedEntityIdsProp, collection, selectionController.setSelectedEntities]);\n\n    const onClear = () => {\n        analyticsController.onAnalyticsEvent?.(\"reference_selection_clear\", {\n            path: fullPath\n        });\n        selectionController.setSelectedEntities([]);\n        if (!multiselect && onSingleEntitySelected) {\n            onSingleEntitySelected(null);\n        } else if (onMultipleEntitiesSelected) {\n            onMultipleEntitiesSelected([]);\n        }\n    };\n\n    const onEntityClick = (entity: Entity<any>) => {\n        if (!multiselect && onSingleEntitySelected) {\n            analyticsController.onAnalyticsEvent?.(\"reference_selected_single\", {\n                path: fullPath,\n                entityId: entity.id\n            });\n            onSingleEntitySelected(entity);\n            sideDialogContext.close(false);\n        } else {\n            toggleEntitySelection(entity);\n        }\n    };\n\n    // create a new entity from within the reference dialog\n    const onNewClick = () => {\n        analyticsController.onAnalyticsEvent?.(\"reference_selection_new_entity\", {\n            path: fullPath\n        });\n        sideEntityController.open({\n            path: fullPath,\n            collection,\n            updateUrl: true,\n            onUpdate: ({ entity }) => {\n                setEntitiesDisplayedFirst([entity, ...entitiesDisplayedFirst]);\n                onEntityClick(entity);\n            },\n            closeOnSave: true\n        });\n    };\n\n    const tableRowActionsBuilder = ({\n                                        entity,\n                                        size,\n                                        width,\n                                        frozen\n                                    }: {\n        entity: Entity<any>,\n        size: CollectionSize,\n        width: number,\n        frozen?: boolean\n    }) => {\n        const selectedEntities = selectionController.selectedEntities;\n        const isSelected = selectedEntities && selectedEntities.map(e => e.id).indexOf(entity.id) > -1;\n        return <EntityCollectionRowActions\n            width={width}\n            frozen={frozen}\n            entity={entity}\n            size={size}\n            isSelected={isSelected}\n            selectionEnabled={multiselect}\n            hideId={collection?.hideIdFromCollection}\n            fullPath={fullPath}\n            selectionController={selectionController}/>;\n\n    };\n\n    const onDone = useCallback((event: React.SyntheticEvent) => {\n        event.stopPropagation();\n        sideDialogContext.close(false);\n    }, [sideDialogContext]);\n\n    if (!collection) {\n        return <ErrorView\n            error={\"Could not find collection with id \" + collection}/>\n    }\n\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    const resolvedCollection = useMemo(() => resolveCollection({\n        collection: collection,\n        path: fullPath,\n        values: {},\n        fields: customizationController.propertyConfigs\n    }), [collection, customizationController.propertyConfigs, fullPath]);\n\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    const displayedColumnIds = useColumnIds(resolvedCollection, false);\n\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    const tableController = useDataSourceEntityCollectionTableController<M>({\n        fullPath,\n        collection,\n        entitiesDisplayedFirst,\n        forceFilter\n    });\n\n    const {\n        textSearchLoading,\n        textSearchInitialised,\n        onTextSearchClick,\n        textSearchEnabled\n    } =\n        // eslint-disable-next-line react-hooks/rules-of-hooks\n        useTableSearchHelper({\n            collection,\n            fullPath,\n        });\n\n    return (\n\n        <div className=\"flex flex-col h-full\">\n\n            <div className=\"flex-grow\">\n                {entitiesDisplayedFirst &&\n                    <EntityCollectionTable\n                        textSearchLoading={textSearchLoading}\n                        onTextSearchClick={textSearchInitialised ? undefined : onTextSearchClick}\n                        textSearchEnabled={textSearchEnabled}\n                        displayedColumnIds={displayedColumnIds}\n                        onEntityClick={onEntityClick}\n                        tableController={tableController}\n                        enablePopupIcon={false}\n                        tableRowActionsBuilder={tableRowActionsBuilder}\n                        title={<Typography variant={\"subtitle2\"}>\n                            {collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}`}\n                        </Typography>}\n                        defaultSize={collection.defaultSize}\n                        properties={resolvedCollection.properties}\n                        forceFilter={forceFilter}\n                        inlineEditing={false}\n                        selectionController={selectionController}\n                        actions={<ReferenceDialogActions\n                            collection={collection}\n                            path={fullPath}\n                            onNewClick={onNewClick}\n                            onClear={onClear}/>\n                        }\n                    />}\n            </div>\n            <DialogActions translucent={false}>\n                {description &&\n                    <Typography variant={\"body2\"}\n                                className=\"flex-grow text-left\">\n                        {description}\n                    </Typography>}\n                <Button\n                    onClick={onDone}\n                    color=\"primary\"\n                    variant=\"filled\">\n                    Done\n                </Button>\n            </DialogActions>\n        </div>\n\n    );\n\n}\n\nfunction ReferenceDialogActions({\n                                    collection,\n                                    path,\n                                    onClear,\n                                    onNewClick\n                                }: {\n    collection: EntityCollection<any>,\n    path: string,\n    onClear: () => void,\n    onNewClick: () => void\n}) {\n\n    const authController = useAuthController();\n\n    const largeLayout = useLargeLayout();\n\n    const onClick: MouseEventHandler<HTMLButtonElement> | undefined = onNewClick\n        ? (e) => {\n            e.preventDefault();\n            onNewClick();\n        }\n        : undefined;\n    const addButton = canCreateEntity(collection, authController, path, null) &&\n        onClick && (largeLayout\n            ? <Button\n                onClick={onClick}\n                startIcon={<AddIcon/>}\n                variant=\"outlined\"\n                color=\"primary\">\n                Add {collection.singularName ?? collection.name}\n            </Button>\n            : <Button\n                onClick={onClick}\n                variant=\"outlined\"\n                color=\"primary\"\n            >\n                <AddIcon/>\n            </Button>);\n\n    return (\n        <>\n            <Button onClick={onClear}\n                    variant={\"text\"}\n                    color=\"primary\">\n                Clear\n            </Button>\n            {addButton}\n        </>\n    );\n}\n","export function toArray<T>(input?: T | T[]): T[] {\n    return Array.isArray(input) ? input : (input ? [input] : []);\n}\n","import { PropsWithChildren } from \"react\";\nimport { useUserConfigurationPersistence } from \"../../hooks/useUserConfigurationPersistence\";\nimport { ExpandablePanel, Typography } from \"@firecms/ui\";\n\nexport function NavigationGroup({\n                                    children,\n                                    group\n                                }: PropsWithChildren<{\n    group: string | undefined\n}>) {\n    const userConfigurationPersistence = useUserConfigurationPersistence();\n    return (\n        <ExpandablePanel\n            invisible={true}\n            titleClassName={\"font-medium text-sm text-gray-600 dark:text-gray-400\"}\n            className={\"py-4\"}\n            initiallyExpanded={!(userConfigurationPersistence?.collapsedGroups ?? []).includes(group ?? \"ungrouped\")}\n            onExpandedChange={expanded => {\n                if (userConfigurationPersistence) {\n\n                    if (!expanded) {\n                        const paths = (userConfigurationPersistence.collapsedGroups ?? []).concat(group ?? \"ungrouped\");\n                        userConfigurationPersistence.setCollapsedGroups(paths);\n                    } else {\n                        userConfigurationPersistence.setCollapsedGroups((userConfigurationPersistence.collapsedGroups ?? []).filter(g => g !== (group ?? \"ungrouped\")));\n                    }\n                }\n            }}\n            title={<Typography color={\"secondary\"}\n                               className=\"font-medium ml-1\">\n                {group?.toUpperCase() ?? \"Views\".toUpperCase()}\n            </Typography>}>\n\n            <div className=\"mb-8\">\n                {children}\n            </div>\n        </ExpandablePanel>\n    );\n}\n","import { ArrowForwardIcon, Card, cn, Markdown, Typography, } from \"@firecms/ui\";\n\nexport type NavigationCardProps = {\n    name: string,\n    description?: string;\n    actions: React.ReactNode;\n    icon: React.ReactNode;\n    onClick?: () => void,\n};\n\nexport function NavigationCard({\n                                   name,\n                                   description,\n                                   icon,\n                                   actions,\n                                   onClick,\n                               }: NavigationCardProps) {\n\n    return (<Card\n        className={cn(\"h-full p-4 cursor-pointer min-h-[230px]\")}\n        onClick={() => {\n            onClick?.();\n        }}>\n\n        <div className=\"flex flex-col items-start h-full\">\n            <div\n                className=\"flex-grow w-full\">\n\n                <div\n                    className=\"h-10 flex items-center w-full justify-between text-gray-300 dark:text-gray-600\">\n\n                    {icon}\n\n                    <div\n                        className=\"flex items-center gap-1\"\n                        onClick={(event: React.MouseEvent) => {\n                            event.preventDefault();\n                            event.stopPropagation();\n                        }}>\n\n                        {actions}\n\n                    </div>\n\n                </div>\n\n                <Typography gutterBottom variant=\"h5\"\n                            component=\"h2\">\n                    {name}\n                </Typography>\n\n                {description && <Typography variant=\"body2\"\n                                            color=\"secondary\"\n                                            component=\"div\">\n                    <Markdown source={description} size={\"small\"}/>\n                </Typography>}\n            </div>\n\n            <div style={{ alignSelf: \"flex-end\" }}>\n\n                <div className={\"p-4\"}>\n                    <ArrowForwardIcon className=\"text-primary\"/>\n                </div>\n            </div>\n\n        </div>\n\n    </Card>)\n}\n","import { ArrowForwardIcon, cardClickableMixin, cardMixin, cn, focusedMixin, Typography, } from \"@firecms/ui\";\n\nimport { Link } from \"react-router-dom\";\n\nexport type SmallNavigationCardProps = {\n    name: string,\n    url: string;\n    icon: React.ReactElement;\n};\n\nexport function SmallNavigationCard({\n                                 name,\n                                 url,\n                                 icon,\n                             }: SmallNavigationCardProps) {\n\n    return (\n        <>\n\n            <Link\n                tabIndex={0}\n                className={cn(cardMixin,\n                    cardClickableMixin,\n                    focusedMixin,\n                    \"cursor-pointer flex flex-row items-center px-4 py-2 text-inherit dark:text-inherit visited:text-inherit visited:dark:text-inherit hover:text-inherit hover:dark:text-inherit \")}\n                to={url}\n            >\n\n                <div className=\"flex flex-row items-center flex-grow gap-2 \">\n                    {icon}\n\n                    <Typography gutterBottom variant=\"h5\"\n                                component=\"h2\"\n                                className=\"mb-0 ml-4\">\n                        {name}\n                    </Typography>\n                </div>\n\n                <div className={\"p-4\"}>\n                    <ArrowForwardIcon color=\"primary\"/>\n                </div>\n            </Link>\n\n        </>);\n}\n","import { useNavigate } from \"react-router-dom\";\n\nimport { useCustomizationController, useFireCMSContext } from \"../../hooks\";\nimport { PluginHomePageActionsProps, TopNavigationEntry } from \"../../types\";\nimport { IconForView } from \"../../util\";\nimport { useUserConfigurationPersistence } from \"../../hooks/useUserConfigurationPersistence\";\nimport { IconButton, StarBorderIcon, StarIcon } from \"@firecms/ui\";\nimport { NavigationCard } from \"./NavigationCard\";\nimport { SmallNavigationCard } from \"./SmallNavigationCard\";\n\n/**\n * This is the component used in the home page to render a card for each\n * collection or view.\n * @group Components\n * @param view\n * @param path\n * @param collection\n * @param url\n * @param name\n * @param description\n * @param onClick\n * @constructor\n */\nexport function NavigationCardBinding({\n                                          path,\n                                          collection,\n                                          view,\n                                          url,\n                                          name,\n                                          description,\n                                          onClick,\n                                          type\n                                      }: TopNavigationEntry & {\n    onClick?: () => void\n}) {\n\n    const userConfigurationPersistence = useUserConfigurationPersistence();\n    const collectionIcon = <IconForView collectionOrView={collection ?? view}/>;\n\n    const navigate = useNavigate();\n    const context = useFireCMSContext();\n    const customizationController = useCustomizationController();\n\n    const favourite = (userConfigurationPersistence?.favouritePaths ?? []).includes(path);\n\n    const actionsArray: React.ReactNode[] = userConfigurationPersistence\n        ? [\n            <IconButton\n                key={\"favourite\"}\n                onClick={(e) => {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    if (favourite) {\n                        userConfigurationPersistence.setFavouritePaths(\n                            userConfigurationPersistence.favouritePaths.filter(p => p !== path)\n                        );\n                    } else {\n                        userConfigurationPersistence.setFavouritePaths(\n                            [...userConfigurationPersistence.favouritePaths, path]\n                        );\n                    }\n                }}>\n                {\n                    favourite\n                        ? <StarIcon\n                            size={18}\n                            className={\"text-secondary\"}/>\n                        : <StarBorderIcon\n                            size={18}\n                            className={\"text-gray-400 dark:text-gray-500\"}/>}\n            </IconButton>\n        ]\n        : [];\n\n    if (customizationController.plugins && collection) {\n        const actionProps: PluginHomePageActionsProps = {\n            path,\n            collection,\n            context\n        };\n        customizationController.plugins.forEach((plugin, i) => (\n            actionsArray.push(plugin.homePage?.CollectionActions\n                ? <plugin.homePage.CollectionActions\n                    key={`actions_${i}`}\n                    {...actionProps}\n                    extraProps={plugin.homePage.extraProps}\n                />\n                : null\n            )))\n    }\n\n    const actions: React.ReactNode | undefined = <>\n        {actionsArray}\n    </>\n\n    if (type === \"admin\") {\n        return <SmallNavigationCard icon={collectionIcon}\n                                    name={name}\n                                    url={url}/>\n    }\n\n    return <NavigationCard\n        icon={collectionIcon}\n        name={name}\n        description={description}\n        actions={actions}\n        onClick={() => {\n            onClick?.();\n            navigate(url);\n            if (userConfigurationPersistence) {\n                userConfigurationPersistence.setRecentlyVisitedPaths(\n                    [path, ...(userConfigurationPersistence.recentlyVisitedPaths ?? []).filter(p => p !== path)]\n                );\n            }\n        }}/>;\n}\n","import { useNavigate } from \"react-router-dom\";\nimport { useNavigationController } from \"../../hooks\";\nimport { useUserConfigurationPersistence } from \"../../hooks/useUserConfigurationPersistence\";\nimport { TopNavigationEntry } from \"../../types\";\nimport { Chip, Collapse, StarBorderIcon, StarIcon } from \"@firecms/ui\";\n\nfunction NavigationChip({ entry }: { entry: TopNavigationEntry }) {\n\n    const navigate = useNavigate();\n    const userConfigurationPersistence = useUserConfigurationPersistence();\n\n    if (!userConfigurationPersistence)\n        return null;\n\n    const favourite = userConfigurationPersistence.favouritePaths.includes(entry.path);\n    const onIconClick = (e: React.SyntheticEvent) => {\n        e.preventDefault();\n        e.stopPropagation();\n        if (favourite) {\n            userConfigurationPersistence.setFavouritePaths(\n                userConfigurationPersistence.favouritePaths.filter(p => p !== entry.path)\n            );\n        } else {\n            userConfigurationPersistence.setFavouritePaths(\n                [...userConfigurationPersistence.favouritePaths, entry.path]\n            );\n        }\n    };\n    return <Chip\n        key={entry.path}\n        onClick={() => navigate(entry.url)}\n        icon={\n            favourite\n                ? <StarIcon\n                    onClick={onIconClick}\n                    size={18}\n                    className={\"text-secondary\"}/>\n                : <StarBorderIcon\n                    onClick={onIconClick}\n                    size={18}\n                    className={\"text-gray-400 dark:text-gray-500\"}/>}>\n        {entry.name}\n    </Chip>;\n}\n\nexport function FavouritesView({ hidden }: { hidden: boolean }) {\n\n    const navigationController = useNavigationController();\n    const userConfigurationPersistence = useUserConfigurationPersistence();\n\n    if (!userConfigurationPersistence)\n        return null;\n\n    const favouriteCollections = (userConfigurationPersistence?.favouritePaths ?? [])\n        .map((path) => navigationController.topLevelNavigation?.navigationEntries.find((entry) => entry.path === path))\n        .filter(Boolean) as TopNavigationEntry[];\n\n    return <Collapse in={favouriteCollections.length > 0}>\n        <div className=\"flex flex-row flex-wrap gap-2 pb-2 min-h-[32px]\">\n            {favouriteCollections.map((entry) => <NavigationChip key={entry.path}\n                                                                 entry={entry}/>)}\n        </div>\n    </Collapse>;\n}\n","import React, { useCallback, useEffect } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\nconst scrollsMap: Record<string, number> = {};\n\nexport function useRestoreScroll() {\n\n    // const scrollsMap = React.useRef<Record<string, number>>({});\n\n    const location = useLocation();\n\n    const containerRef = React.useRef<HTMLDivElement>(null);\n    const [scroll, setScroll] = React.useState(0);\n    const [direction, setDirection] = React.useState<\"up\" | \"down\">(\"down\");\n\n    const handleScroll = useCallback(() => {\n        if (!containerRef.current || !location.key) return;\n        scrollsMap[location.key] = containerRef.current.scrollTop;\n        setScroll(containerRef.current.scrollTop);\n        setDirection(containerRef.current.scrollTop > scroll ? \"down\" : \"up\");\n    }, [containerRef, location.key, scroll]);\n\n    useEffect(() => {\n        const container = containerRef.current;\n        if (!container) return;\n        container.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n        return () => {\n            if (container)\n                container.removeEventListener(\"scroll\", handleScroll);\n        };\n    }, [containerRef, handleScroll, location]);\n\n    useEffect(() => {\n        if (!containerRef.current || !scrollsMap[location.key]) return;\n        containerRef.current.scrollTo(\n            {\n                top: scrollsMap[location.key],\n                behavior: \"auto\"\n            });\n    }, [location]);\n\n    return {\n        containerRef,\n        scroll,\n        direction\n    };\n}\n","import React, { useCallback, useEffect, useState } from \"react\";\n\nimport { useCustomizationController, useFireCMSContext, useNavigationController } from \"../../hooks\";\nimport { CMSAnalyticsEvent, PluginGenericProps, PluginHomePageAdditionalCardsProps } from \"../../types\";\n\nimport { toArray } from \"../../util/arrays\";\nimport { NavigationGroup } from \"./NavigationGroup\";\nimport { NavigationCardBinding } from \"./NavigationCardBinding\";\n\n// @ts-ignore\nimport * as JsSearch from \"js-search\";\n\nimport { Container, SearchBar } from \"@firecms/ui\";\nimport { FavouritesView } from \"./FavouritesView\";\nimport { useRestoreScroll } from \"../../internal/useRestoreScroll\";\n\nconst search = new JsSearch.Search(\"url\");\nsearch.addIndex(\"name\");\nsearch.addIndex(\"description\");\nsearch.addIndex(\"group\");\nsearch.addIndex(\"path\");\n\n/**\n * Default entry view for the CMS. This component renders navigation cards\n * for each collection defined in the navigation.\n * @constructor\n * @group Components\n */\nexport function DefaultHomePage({\n                                    additionalActions,\n                                    additionalChildrenStart,\n                                    additionalChildrenEnd\n                                }: {\n    /**\n     * Additional actions to be rendered in the home page, close to the search bar.\n     */\n    additionalActions?: React.ReactNode;\n    /**\n     * Additional children to be rendered in the beginning of the home page.\n     */\n    additionalChildrenStart?: React.ReactNode;\n    /**\n     * Additional children to be rendered at the end of the home page.\n     */\n    additionalChildrenEnd?: React.ReactNode;\n}) {\n\n    const context = useFireCMSContext();\n    const customizationController = useCustomizationController();\n    const navigationController = useNavigationController();\n\n    if (!navigationController.topLevelNavigation)\n        throw Error(\"Navigation not ready in FireCMSHomePage\");\n\n    const {\n        containerRef,\n        scroll,\n        direction\n    } = useRestoreScroll();\n\n    const {\n        navigationEntries,\n        groups\n    } = navigationController.topLevelNavigation;\n\n    const [filteredUrls, setFilteredUrls] = useState<string[] | null>(null);\n\n    const filteredNavigationEntries = filteredUrls\n        ? navigationEntries.filter((entry) => filteredUrls.includes(entry.url))\n        : navigationEntries;\n\n    useEffect(() => {\n        search.addDocuments(navigationEntries);\n    }, [navigationEntries]);\n\n    const updateSearchResults = useCallback(\n        (value?: string) => {\n            if (!value || value === \"\") {\n                setFilteredUrls(null);\n            } else {\n                const searchResult = search.search(value);\n                setFilteredUrls(searchResult.map((e: any) => e.url));\n            }\n        }, []);\n\n    const allGroups: Array<string | undefined> = [...groups];\n    if (filteredNavigationEntries.filter(e => !e.group).length > 0 || filteredNavigationEntries.length === 0) {\n        allGroups.push(undefined);\n    }\n\n    let additionalPluginChildrenStart: React.ReactNode | undefined;\n    let additionalPluginChildrenEnd: React.ReactNode | undefined;\n    let additionalPluginSections: React.ReactNode | undefined;\n    if (customizationController.plugins) {\n        const sectionProps: PluginGenericProps = {\n            context\n        };\n        additionalPluginSections = <>\n            {customizationController.plugins.filter(plugin => plugin.homePage?.includeSection)\n                .map((plugin, i) => {\n                    const section = plugin.homePage!.includeSection!(sectionProps)\n                    return (\n                        <NavigationGroup\n                            group={section.title}\n                            key={`plugin_section_${plugin.key}`}>\n                            {section.children}\n                        </NavigationGroup>\n                    );\n                })}\n        </>;\n        additionalPluginChildrenStart = <div className={\"flex flex-col gap-2\"}>\n            {customizationController.plugins.filter(plugin => plugin.homePage?.additionalChildrenStart)\n                .map((plugin, i) => {\n                    return <div key={`plugin_children_start_${i}`}>{plugin.homePage!.additionalChildrenStart}</div>;\n                })}\n        </div>;\n\n        additionalPluginChildrenEnd = <div className={\"flex flex-col gap-2\"}>\n            {customizationController.plugins.filter(plugin => plugin.homePage?.additionalChildrenEnd)\n                .map((plugin, i) => {\n                    return <div key={`plugin_children_start_${i}`}>{plugin.homePage!.additionalChildrenEnd}</div>;\n                })}\n        </div>;\n    }\n\n    return (\n        <div id=\"home_page\"\n             ref={containerRef}\n             className=\"py-2 overflow-auto h-full w-full\">\n            <Container maxWidth={\"6xl\"}>\n                <div\n                    className=\"w-full sticky py-4 transition-all duration-400 ease-in-out top-0 z-10 flex flex-row gap-4\"\n                    style={{ top: direction === \"down\" ? -84 : 0 }}>\n                    <SearchBar onTextSearch={updateSearchResults}\n                               placeholder={\"Search collections\"}\n                               large={false}\n                               innerClassName={\"w-full\"}\n                               className={\"w-full flex-grow\"}/>\n                    {additionalActions}\n                </div>\n\n                <FavouritesView hidden={Boolean(filteredUrls)}/>\n\n                {additionalChildrenStart}\n\n                {additionalPluginChildrenStart}\n\n                {allGroups.map((group, index) => {\n\n                    const AdditionalCards: React.ComponentType<PluginHomePageAdditionalCardsProps>[] = [];\n                    const actionProps: PluginHomePageAdditionalCardsProps = {\n                        group,\n                        context\n                    };\n\n                    if (customizationController.plugins) {\n                        customizationController.plugins.forEach(plugin => {\n                            if (plugin.homePage?.AdditionalCards) {\n                                AdditionalCards.push(...toArray(plugin.homePage?.AdditionalCards));\n                            }\n                        });\n                    }\n\n                    const thisGroupCollections = filteredNavigationEntries\n                        .filter((entry) => entry.group === group || (!entry.group && group === undefined));\n                    if (thisGroupCollections.length === 0 && AdditionalCards.length === 0)\n                        return null;\n                    return (\n                        <NavigationGroup\n                            group={group}\n                            key={`plugin_section_${group}`}>\n\n                            <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n                                {thisGroupCollections.map((entry) => (\n                                    <div key={`nav_${entry.group}_${entry.name}`} className=\"col-span-1\">\n                                        <NavigationCardBinding\n                                            {...entry}\n                                            onClick={() => {\n                                                let event: CMSAnalyticsEvent;\n                                                if (entry.type === \"collection\") {\n                                                    event = \"home_navigate_to_collection\";\n                                                } else if (entry.type === \"view\") {\n                                                    event = \"home_navigate_to_view\";\n                                                } else if (entry.type === \"admin\") {\n                                                    event = \"home_navigate_to_admin_view\";\n                                                } else {\n                                                    event = \"unmapped_event\";\n                                                }\n                                                context.analyticsController?.onAnalyticsEvent?.(event, { path: entry.path });\n                                            }}\n                                        />\n                                    </div>\n                                ))}\n                                {group?.toLowerCase() !== \"admin\" && AdditionalCards &&\n                                    AdditionalCards.map((AdditionalCard, i) => (\n                                        <div key={`nav_${group}_add_${i}`}>\n                                            <AdditionalCard {...actionProps} />\n                                        </div>\n                                    ))}\n                            </div>\n                        </NavigationGroup>\n                    );\n                })}\n\n                {additionalPluginSections}\n\n                {additionalPluginChildrenEnd}\n\n                {additionalChildrenEnd}\n\n            </Container>\n        </div>\n    );\n}\n","import React from \"react\";\n\nimport { canCreateEntity, canDeleteEntity, fullPathToCollectionSegments } from \"../../util\";\nimport { useAuthController, useCustomizationController, useFireCMSContext, useLargeLayout } from \"../../hooks\";\nimport { CollectionActionsProps, EntityCollection, EntityTableController, SelectionController } from \"../../types\";\nimport { AddIcon, Button, DeleteIcon, IconButton, Tooltip } from \"@firecms/ui\";\nimport { toArray } from \"../../util/arrays\";\nimport { ErrorBoundary } from \"../ErrorBoundary\";\n\nexport type EntityCollectionViewActionsProps<M extends Record<string, any>> = {\n    collection: EntityCollection<M>;\n    path: string;\n    relativePath: string;\n    parentCollectionIds: string[];\n    selectionEnabled: boolean;\n    onNewClick: () => void;\n    onMultipleDeleteClick: () => void;\n    selectionController: SelectionController<M>;\n    tableController: EntityTableController<M>;\n    collectionEntitiesCount: number;\n}\n\nexport function EntityCollectionViewActions<M extends Record<string, any>>({\n                                                                               collection,\n                                                                               relativePath,\n                                                                               parentCollectionIds,\n                                                                               onNewClick,\n                                                                               onMultipleDeleteClick,\n                                                                               selectionEnabled,\n                                                                               path,\n                                                                               selectionController,\n                                                                               tableController,\n                                                                               collectionEntitiesCount\n                                                                           }: EntityCollectionViewActionsProps<M>) {\n\n    const context = useFireCMSContext();\n\n    const customizationController = useCustomizationController();\n    const plugins = customizationController.plugins ?? [];\n\n    const authController = useAuthController();\n\n    const largeLayout = useLargeLayout();\n\n    const selectedEntities = selectionController.selectedEntities;\n\n    const addButton = canCreateEntity(collection, authController, path, null) &&\n        onNewClick && (largeLayout\n            ? <Button\n                id={`add_entity_${path}`}\n                onClick={onNewClick}\n                startIcon={<AddIcon/>}\n                variant=\"filled\"\n                color=\"primary\">\n                Add {collection.singularName ?? collection.name}\n            </Button>\n            : <Button\n                id={`add_entity_${path}`}\n                onClick={onNewClick}\n                variant=\"filled\"\n                color=\"primary\"\n            >\n                <AddIcon/>\n            </Button>);\n\n    const multipleDeleteEnabled = canDeleteEntity(collection, authController, path, null);\n\n    let multipleDeleteButton: React.ReactNode | undefined;\n    if (selectionEnabled) {\n        const button = largeLayout\n            ? <Button\n                variant={\"text\"}\n                disabled={!(selectedEntities?.length) || !multipleDeleteEnabled}\n                startIcon={<DeleteIcon/>}\n                onClick={onMultipleDeleteClick}\n                color={\"primary\"}\n                className=\"lg:w-20\"\n            >\n                ({selectedEntities?.length})\n            </Button>\n            : <IconButton\n                color={\"primary\"}\n                disabled={!(selectedEntities?.length) || !multipleDeleteEnabled}\n                onClick={onMultipleDeleteClick}>\n                <DeleteIcon/>\n            </IconButton>;\n        multipleDeleteButton =\n            <Tooltip\n                title={multipleDeleteEnabled ? \"Delete\" : \"You have selected at least one entity you cannot delete\"}>\n                {button}\n            </Tooltip>\n    }\n\n    const actionProps: CollectionActionsProps = {\n        path,\n        relativePath,\n        parentCollectionIds,\n        collection,\n        selectionController,\n        context,\n        tableController,\n        collectionEntitiesCount\n    };\n\n    const actions = toArray(collection.Actions)\n        .map((Action, i) => (\n            <ErrorBoundary key={`actions_${i}`}>\n                <Action {...actionProps} />\n            </ErrorBoundary>\n        ));\n\n    if (plugins) {\n        plugins.forEach((plugin, i) => {\n            if (plugin.collectionView?.CollectionActions) {\n                actions.push(...toArray(plugin.collectionView?.CollectionActions)\n                    .map((Action, j) => (\n                        <ErrorBoundary key={`plugin_actions_${i}_${j}`}>\n                            <Action {...actionProps} {...plugin.collectionView?.collectionActionsProps}/>\n                        </ErrorBoundary>\n                    )));\n            }\n        });\n    }\n\n    return (\n        <>\n            {actions}\n            {multipleDeleteButton}\n            {addButton}\n        </>\n    );\n}\n","import React, { useEffect } from \"react\";\n\ninterface DraggableProps {\n    containerRef: React.RefObject<HTMLDivElement>,\n    innerRef: React.RefObject<HTMLDivElement>,\n    // ref: React.RefObject<HTMLDivElement>,\n    x?: number;\n    y?: number;\n    onMove: (params: { x: number, y: number }) => void,\n}\n\nexport function useDraggable({\n                                 containerRef,\n                                 innerRef,\n                                 x,\n                                 y,\n                                 onMove\n                             }: DraggableProps) {\n\n    let relX = 0;\n    let relY = 0;\n\n    const listeningRef = React.useRef(false);\n\n    const onMouseDown = (event: any) => {\n        if (event.button !== 0 || !containerRef.current || event.defaultPrevented || event.innerClicked) {\n            return;\n        }\n\n        const {\n            x,\n            y\n        } = containerRef.current.getBoundingClientRect();\n\n        relX = event.screenX - x;\n        relY = event.screenY - y;\n        document.addEventListener(\"mousemove\", onMouseMove);\n        document.addEventListener(\"mouseup\", onMouseUp);\n        document.addEventListener(\"selectstart\", onSelect);\n        listeningRef.current = true;\n        // event.stopPropagation();\n    };\n    const onMouseDownInner = (event: any) => {\n        // @ts-ignore\n        event.innerClicked = true;\n    };\n\n    const onSelect = (event: any) => {\n        event.preventDefault()\n        event.stopPropagation();\n    };\n\n    const onMouseUp = (event: any) => {\n        document.removeEventListener(\"mousemove\", onMouseMove);\n        document.removeEventListener(\"mouseup\", onMouseUp);\n        document.removeEventListener(\"selectstart\", onSelect);\n        event.stopPropagation();\n        listeningRef.current = false;\n    };\n\n    const onMouseMove = (event: any) => {\n        if (event.target.localName === \"input\" || !listeningRef.current)\n            return;\n        onMove({\n                x: event.screenX - relX,\n                y: event.screenY - relY\n            }\n        );\n        event.stopPropagation();\n    };\n\n    const update = () => {\n        if (containerRef.current) {\n            containerRef.current.style.top = `${y}px`;\n            containerRef.current.style.left = `${x}px`;\n        }\n    };\n\n    useEffect(() => {\n        const current = containerRef.current;\n        const innerCurrent = innerRef.current;\n        if (!current || !innerCurrent)\n            return;\n        if (innerCurrent)\n            innerCurrent.addEventListener(\"mousedown\", onMouseDownInner);\n        if (current)\n            current.addEventListener(\"mousedown\", onMouseDown);\n        update();\n        return () => {\n            if (current)\n                current.removeEventListener(\"mousedown\", onMouseDown);\n            if (innerCurrent)\n                innerCurrent.removeEventListener(\"mousedown\", onMouseDownInner);\n        };\n    });\n\n}\n","import { RefObject, useCallback, useEffect, useRef } from \"react\";\n\ninterface Props {\n    onResize: (event: Event) => void;\n}\n\nexport const ElementResizeListener: React.FC<Props> = ({ onResize }) => {\n    const rafRef = useRef(0);\n    const objectRef: RefObject<HTMLObjectElement> = useRef(null);\n    const onResizeRef = useRef(onResize);\n\n    onResizeRef.current = onResize;\n\n    const _onResize = useCallback((e: Event) => {\n        if (rafRef.current) {\n            cancelAnimationFrame(rafRef.current);\n        }\n        rafRef.current = requestAnimationFrame(() => {\n            onResizeRef.current(e);\n        });\n    }, []);\n\n    const onLoad = useCallback(() => {\n        const obj = objectRef.current;\n        if (obj && obj.contentDocument && obj.contentDocument.defaultView) {\n            obj.contentDocument.defaultView.addEventListener(\"resize\", _onResize);\n        }\n    }, [_onResize]);\n\n    useEffect(() => {\n        const obj = objectRef.current;\n        return () => {\n            if (obj && obj.contentDocument && obj.contentDocument.defaultView) {\n                obj.contentDocument.defaultView.removeEventListener(\"resize\", _onResize);\n            }\n        };\n    }, [_onResize]);\n\n    return (\n        <object\n            onLoad={onLoad}\n            ref={objectRef}\n            tabIndex={-1}\n            type={\"text/html\"}\n            data={\"about:blank\"}\n            title={\"\"}\n            style={{\n                position: \"absolute\",\n                top: 0,\n                left: 0,\n                height: \"100%\",\n                width: \"100%\",\n                pointerEvents: \"none\",\n                zIndex: -1,\n                opacity: 0\n            }}\n        />\n    );\n};\n","import React, { useCallback, useEffect, useLayoutEffect, useMemo, useState } from \"react\";\nimport equal from \"react-fast-compare\"\n\nimport * as Portal from \"@radix-ui/react-portal\";\n\nimport {\n    Entity,\n    EntityCollection,\n    EntityValues,\n    FireCMSPlugin,\n    FormContext,\n    PropertyFieldBindingProps,\n    ResolvedEntityCollection,\n    ResolvedProperties,\n    ResolvedProperty\n} from \"../../../../types\";\nimport { Formex, useCreateFormex } from \"@firecms/formex\";\nimport { useDraggable } from \"./useDraggable\";\nimport { CustomFieldValidator, getYupEntitySchema } from \"../../../../form/validation\";\nimport { useWindowSize } from \"./useWindowSize\";\nimport { ElementResizeListener } from \"./ElementResizeListener\";\nimport { ErrorView } from \"../../../ErrorView\";\nimport { getPropertyInPath, isReadOnly, resolveCollection } from \"../../../../util\";\nimport { Button, ClearIcon, DialogActions, IconButton, Typography } from \"@firecms/ui\";\nimport { PropertyFieldBinding } from \"../../../../form\";\nimport { useCustomizationController, useFireCMSContext } from \"../../../../hooks\";\nimport { OnCellValueChangeParams } from \"../../../common\";\n\ninterface PopupFormFieldProps<M extends Record<string, any>> {\n    entity?: Entity<M>;\n    customFieldValidator?: CustomFieldValidator;\n    path: string;\n    tableKey: string;\n    propertyKey?: Extract<keyof M, string>;\n    collection?: EntityCollection<M>;\n    cellRect?: DOMRect;\n    open: boolean;\n    onClose: () => void;\n    container: HTMLElement | null;\n    /**\n     * Callback when the value of a cell has been edited\n     * @param params\n     */\n    onCellValueChange?: (params: OnCellValueChangeParams<any, any>) => Promise<void> | void;\n}\n\nexport function PopupFormField<M extends Record<string, any>>(props: PopupFormFieldProps<M>) {\n    if (!props.open) return null;\n    return <PopupFormFieldInternal {...props} />;\n\n}\n\nexport function PopupFormFieldInternal<M extends Record<string, any>>({\n                                                                          tableKey,\n                                                                          entity: entityProp,\n                                                                          customFieldValidator,\n                                                                          propertyKey,\n                                                                          collection: inputCollection,\n                                                                          path,\n                                                                          cellRect,\n                                                                          open,\n                                                                          onClose,\n                                                                          onCellValueChange,\n                                                                          container\n                                                                      }: PopupFormFieldProps<M>) {\n\n    // const dataSource = useDataSource();\n    const fireCMSContext = useFireCMSContext();\n    const customizationController = useCustomizationController();\n\n    const [savingError, setSavingError] = React.useState<any>();\n    const [popupLocation, setPopupLocation] = useState<{\n        x: number,\n        y: number\n    }>();\n\n    const entityId = entityProp?.id;\n    const [entity, setEntity] = useState<Entity<M> | undefined>(entityProp);\n    // useEffect(() => {\n    //     if (entityId && inputCollection) {\n    //         return dataSource.listenEntity?.({\n    //             path,\n    //             entityId,\n    //             collection: inputCollection,\n    //             onUpdate: (e) => {\n    //                 setEntity(e);\n    //                 setInternalValue(e?.values);\n    //             }\n    //         });\n    //     } else {\n    //         return () => {\n    //         };\n    //     }\n    // }, [dataSource, entityId, inputCollection, path, open]);\n\n    const [internalValue, setInternalValue] = useState<EntityValues<M> | undefined>(entity?.values);\n\n    const collection: ResolvedEntityCollection<M> | undefined = inputCollection\n        ? resolveCollection<M>({\n            collection: inputCollection,\n            path,\n            values: internalValue,\n            entityId,\n            fields: customizationController.propertyConfigs\n        })\n        : undefined;\n\n    const windowSize = useWindowSize();\n\n    const draggableRef = React.useRef<HTMLDivElement>(null);\n    const innerRef = React.useRef<HTMLDivElement>(null);\n\n    const initialPositionSet = React.useRef<boolean>(false);\n\n    const getInitialLocation = useCallback(() => {\n        if (!cellRect) throw Error(\"getInitialLocation error\");\n\n        return {\n            x: cellRect.left < windowSize.width - cellRect.right\n                ? cellRect.x + cellRect.width / 2\n                : cellRect.x - cellRect.width / 2,\n            y: cellRect.top < windowSize.height - cellRect.bottom\n                ? cellRect.y + cellRect.height / 2\n                : cellRect.y - cellRect.height / 2\n        };\n    }, [cellRect, windowSize.height, windowSize.width]);\n\n    const normalizePosition = useCallback(({\n                                               x,\n                                               y\n                                           }: { x: number, y: number }) => {\n\n        const draggableBoundingRect = draggableRef.current?.getBoundingClientRect();\n        if (!draggableBoundingRect)\n            throw Error(\"normalizePosition called before draggableBoundingRect is set\");\n\n        return {\n            x: Math.max(0, Math.min(x, windowSize.width - draggableBoundingRect.width)),\n            y: Math.max(0, Math.min(y, windowSize.height - draggableBoundingRect.height))\n        };\n    }, [windowSize]);\n\n    const updatePopupLocation = useCallback((position?: {\n        x: number,\n        y: number\n    }) => {\n\n        const draggableBoundingRect = draggableRef.current?.getBoundingClientRect();\n        if (!cellRect || !draggableBoundingRect) return;\n        // const newPosition = normalizePosition(position ?? getInitialLocation());\n        const newPosition = position ?? normalizePosition(getInitialLocation());\n        if (!popupLocation || newPosition.x !== popupLocation.x || newPosition.y !== popupLocation.y)\n            setPopupLocation(newPosition);\n    }, [cellRect, getInitialLocation, normalizePosition, popupLocation]);\n\n    useDraggable({\n        containerRef: draggableRef,\n        innerRef,\n        x: popupLocation?.x,\n        y: popupLocation?.y,\n        onMove: updatePopupLocation\n    });\n\n    useEffect(\n        () => {\n            initialPositionSet.current = false;\n        },\n        [propertyKey, entity]\n    );\n\n    useLayoutEffect(\n        () => {\n            const draggableBoundingRect = draggableRef.current?.getBoundingClientRect();\n            if (!cellRect || !draggableBoundingRect || initialPositionSet.current) return;\n            updatePopupLocation();\n            initialPositionSet.current = true;\n        },\n        [cellRect, updatePopupLocation, initialPositionSet.current]\n    );\n\n    useLayoutEffect(\n        () => {\n            updatePopupLocation(popupLocation);\n        },\n        [windowSize, cellRect]\n    );\n\n    const validationSchema = useMemo(() => {\n        if (!collection || !entityId) return;\n        return getYupEntitySchema(\n            entityId,\n            propertyKey && collection.properties[propertyKey as string]\n                ? { [propertyKey]: collection.properties[propertyKey as string] } as ResolvedProperties<any>\n                : {} as ResolvedProperties<any>,\n            customFieldValidator);\n    }, [collection, entityId, propertyKey, customFieldValidator]);\n\n    const adaptResize = useCallback(() => {\n        return updatePopupLocation(popupLocation);\n    }, [popupLocation, updatePopupLocation]);\n\n    const saveValue = async (values: M) => {\n        setSavingError(null);\n        if (inputCollection && entity && onCellValueChange && propertyKey) {\n            return onCellValueChange({\n                value: values[propertyKey as string],\n                propertyKey: propertyKey as string,\n                data: entity,\n                setError: setSavingError,\n                onValueUpdated: () => {\n                },\n            });\n        }\n        return Promise.resolve();\n    };\n\n    if (!entity)\n        return <></>;\n\n    // enableReinitialize={true}\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    const formex = useCreateFormex<M>({\n        initialValues: (entity?.values ?? {}) as EntityValues<M>,\n        validation: (values) => {\n            return validationSchema?.validate(values, { abortEarly: false })\n                .then(() => ({}))\n                .catch((e) => {\n                    const errors: Record<string, string> = {};\n                    e.inner.forEach((error: any) => {\n                        errors[error.path] = error.message;\n                    });\n                    return errors;\n                });\n        },\n        validateOnInitialRender: true,\n        onSubmit: (values, actions) => {\n            saveValue(values)\n                .then(() => onClose())\n                .finally(() => actions.setSubmitting(false));\n        }\n    });\n\n    const { values, isSubmitting, setFieldValue, handleSubmit } = formex;\n\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useEffect(() => {\n        if (!equal(values, internalValue)) {\n            setInternalValue(values);\n        }\n    }, [values]);\n\n    if (!entity)\n        return <ErrorView\n            error={\"PopupFormField misconfiguration\"}/>;\n\n    if (!collection)\n        return <></>;\n\n    const disabled = isSubmitting;\n\n    const formContext: FormContext<M> = {\n        collection,\n        entityId,\n        values,\n        path,\n        setFieldValue,\n        save: saveValue\n    };\n\n    const property: ResolvedProperty<any> | undefined = propertyKey && getPropertyInPath(collection.properties, propertyKey as string);\n    const fieldProps: PropertyFieldBindingProps<any, M> | undefined = propertyKey && property\n        ? {\n            propertyKey: propertyKey as string,\n            disabled: isSubmitting || isReadOnly(property) || !!property.disabled,\n            property,\n            includeDescription: false,\n            underlyingValueHasChanged: false,\n            context: formContext,\n            tableMode: true,\n            partOfArray: false,\n            partOfBlock: false,\n            autoFocus: open\n        }\n        : undefined;\n\n    let internalForm = <>\n        <div\n            key={`popup_form_${tableKey}_${entityId}_${propertyKey}`}\n            className=\"w-[560px] max-w-full max-h-[85vh]\">\n            <form\n                onSubmit={handleSubmit}\n                noValidate>\n\n                <div\n                    className=\"mb-1 p-4 flex flex-col relative\">\n                    <div\n                        ref={innerRef}\n                        className=\"cursor-auto\"\n                        style={{ cursor: \"auto !important\" }}>\n                        {fieldProps &&\n                            <PropertyFieldBinding {...fieldProps}/>}\n                    </div>\n                </div>\n\n                <DialogActions>\n                    <Button\n                        variant=\"filled\"\n                        color=\"primary\"\n                        type=\"submit\"\n                        disabled={disabled}\n                    >\n                        Save\n                    </Button>\n                </DialogActions>\n\n            </form>\n\n        </div>\n\n    </>;\n\n    const plugins = customizationController.plugins;\n    if (plugins) {\n        // const formController: FormContext<M> = {\n        //     values,\n        //     setFieldValue\n        // }\n        plugins.forEach((plugin: FireCMSPlugin) => {\n            if (plugin.form?.provider) {\n                internalForm = (\n                    <plugin.form.provider.Component\n                        status={\"existing\"}\n                        path={path}\n                        collection={collection}\n                        entity={entity}\n                        context={fireCMSContext}\n                        currentEntityId={entityId}\n                        formContext={formContext}\n                        {...plugin.form.provider.props}>\n                        {internalForm}\n                    </plugin.form.provider.Component>\n                );\n            }\n        });\n    }\n    const form = <div\n        className={`text-gray-900 dark:text-white overflow-auto rounded rounded-md bg-white dark:bg-gray-950 ${!open ? \"hidden\" : \"\"} cursor-grab max-w-[100vw]`}>\n\n        {internalForm}\n\n        {savingError &&\n            <Typography color={\"error\"}>\n                {savingError.message}\n            </Typography>\n        }\n    </div>;\n\n    const draggable = (\n        <div\n            key={`draggable_${propertyKey as string}_${entityId}_${open}`}\n            style={{\n                boxShadow: \"0 0 0 2px rgba(128,128,128,0.2)\",\n            }}\n            className={`inline-block fixed z-20 shadow-outline rounded-md bg-white dark:bg-gray-950 ${\n                !open ? \"invisible\" : \"visible\"\n            } cursor-grab overflow-visible`}\n            ref={draggableRef}>\n\n            <ElementResizeListener onResize={adaptResize}/>\n\n            <div\n                className=\"overflow-hidden\">\n\n                {form}\n\n                <div\n                    className=\"absolute -top-3.5 -right-3.5 bg-gray-500 rounded-full\"\n                    style={{\n                        width: \"32px\",\n                        height: \"32px\"\n                    }}>\n                    <IconButton\n                        size={\"small\"}\n                        onClick={(event) => {\n                            event.stopPropagation();\n                            onClose();\n                        }}>\n                        <ClearIcon className=\"text-white\"\n                                   size={\"small\"}/>\n                    </IconButton>\n                </div>\n            </div>\n\n        </div>\n    );\n\n    return (\n        <Portal.Root asChild\n                     container={container}>\n            <Formex value={formex}>\n                {draggable}\n            </Formex>\n        </Portal.Root>\n    );\n\n}\n","import { useLayoutEffect, useState } from \"react\";\n\ninterface WindowSize {\n    width: number,\n    height: number\n}\n\nexport function useWindowSize(): WindowSize {\n    const [size, setSize] = useState<WindowSize>({ width: 0, height: 0 });\n    useLayoutEffect(() => {\n        function updateSize() {\n            setSize({ width: window.innerWidth, height: window.innerHeight });\n        }\n\n        window.addEventListener(\"resize\", updateSize);\n        updateSize();\n        return () => window.removeEventListener(\"resize\", updateSize);\n    }, []);\n    return size;\n}\n","import { Button, FilterListOffIcon } from \"@firecms/ui\";\nimport { EntityTableController } from \"../types\";\n\nexport function ClearFilterSortButton({\n                                          tableController,\n                                          enabled\n                                      }: {\n    enabled: boolean;\n    tableController: EntityTableController\n}) {\n    if (!enabled) {\n        return null;\n    }\n\n    const filterIsSet = !!tableController.filterValues && Object.keys(tableController.filterValues).length > 0;\n    const sortIsSet = !!tableController.sortBy && tableController.sortBy.length > 0;\n\n    if ((filterIsSet || sortIsSet) && (tableController.clearFilter || tableController.setSortBy)) {\n        let label;\n        if (filterIsSet && sortIsSet) {\n            label = \"Clear filter and sort\";\n        } else if (filterIsSet) {\n            label = \"Clear filter\";\n        } else {\n            label = \"Clear sort\";\n        }\n        return <Button\n            variant={\"outlined\"}\n            className=\"h-fit-content\"\n            aria-label=\"filter clear\"\n            onClick={() => {\n                tableController.clearFilter?.();\n                tableController.setSortBy?.(undefined);\n            }}\n            size={\"small\"}>\n            <FilterListOffIcon/>\n            {label}\n        </Button>\n    }\n    return null;\n}\n","import React from \"react\";\nimport { useCustomizationController, useFireCMSContext } from \"../../hooks\";\nimport { CollectionActionsProps, EntityCollection, EntityTableController, SelectionController } from \"../../types\";\nimport { toArray } from \"../../util/arrays\";\nimport { ErrorBoundary } from \"../ErrorBoundary\";\nimport { ClearFilterSortButton } from \"../ClearFilterSortButton\";\n\nexport type EntityCollectionViewStartActionsProps<M extends Record<string, any>> = {\n    collection: EntityCollection<M>;\n    path: string;\n    relativePath: string;\n    parentCollectionIds: string[];\n    selectionController: SelectionController<M>;\n    tableController: EntityTableController<M>;\n    collectionEntitiesCount: number;\n}\n\nexport function EntityCollectionViewStartActions<M extends Record<string, any>>({\n                                                                                    collection,\n                                                                                    relativePath,\n                                                                                    parentCollectionIds,\n                                                                                    path,\n                                                                                    selectionController,\n                                                                                    tableController,\n                                                                                    collectionEntitiesCount\n                                                                                }: EntityCollectionViewStartActionsProps<M>) {\n\n    const context = useFireCMSContext();\n\n    const customizationController = useCustomizationController();\n    const plugins = customizationController.plugins ?? [];\n\n    const actionProps: CollectionActionsProps = {\n        path,\n        relativePath,\n        parentCollectionIds,\n        collection,\n        selectionController,\n        context,\n        tableController,\n        collectionEntitiesCount\n    };\n    const actions: React.ReactNode[] = [\n        <ClearFilterSortButton\n            key={\"clear_filter\"}\n            tableController={tableController}\n            enabled={!collection.forceFilter}/>\n    ];\n\n    if (plugins) {\n        plugins.forEach((plugin, i) => {\n            if (plugin.collectionView?.CollectionActionsStart) {\n                actions.push(...toArray(plugin.collectionView?.CollectionActionsStart)\n                    .map((Action, j) => (\n                        <ErrorBoundary key={`plugin_actions_${i}_${j}`}>\n                            <Action {...actionProps} {...plugin.collectionView?.collectionActionsStartProps}/>\n                        </ErrorBoundary>\n                    )));\n            }\n        });\n    }\n\n    return (\n        <>\n            {actions}\n        </>\n    );\n}\n","import React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport equal from \"react-fast-compare\"\n\nimport {\n    AdditionalFieldDelegate,\n    CollectionSize,\n    Entity,\n    EntityAction,\n    EntityCollection,\n    FilterValues,\n    PartialEntityCollection,\n    PropertyOrBuilder,\n    ResolvedProperty,\n    SaveEntityProps\n} from \"../../types\";\nimport {\n    EntityCollectionRowActions,\n    EntityCollectionTable,\n    useDataSourceEntityCollectionTableController\n} from \"../EntityCollectionTable\";\n\nimport {\n    canCreateEntity,\n    canDeleteEntity,\n    canEditEntity,\n    getPropertyInPath,\n    mergeDeep,\n    resolveCollection,\n    resolveProperty\n} from \"../../util\";\nimport { ReferencePreview } from \"../../preview\";\nimport {\n    saveEntityWithCallbacks,\n    useAuthController,\n    useCustomizationController,\n    useDataSource,\n    useFireCMSContext,\n    useLargeLayout,\n    useNavigationController,\n    useSideEntityController\n} from \"../../hooks\";\nimport { useUserConfigurationPersistence } from \"../../hooks/useUserConfigurationPersistence\";\nimport { EntityCollectionViewActions } from \"./EntityCollectionViewActions\";\nimport {\n    AddIcon,\n    Button,\n    cn,\n    IconButton,\n    KeyboardTabIcon,\n    Markdown,\n    Popover,\n    SearchIcon,\n    Skeleton,\n    Tooltip,\n    Typography\n} from \"@firecms/ui\";\nimport { setIn } from \"@firecms/formex\";\nimport { getSubcollectionColumnId } from \"../EntityCollectionTable/internal/common\";\nimport {\n    OnCellValueChange,\n    OnColumnResizeParams,\n    UniqueFieldValidator,\n    useColumnIds,\n    useTableSearchHelper\n} from \"../common\";\nimport { PopupFormField } from \"../EntityCollectionTable/internal/popup_field/PopupFormField\";\nimport { GetPropertyForProps } from \"../EntityCollectionTable/EntityCollectionTableProps\";\nimport { copyEntityAction, deleteEntityAction, editEntityAction } from \"../common/default_entity_actions\";\nimport { DeleteEntityDialog } from \"../DeleteEntityDialog\";\nimport { useAnalyticsController } from \"../../hooks/useAnalyticsController\";\nimport { useSelectionController } from \"./useSelectionController\";\nimport { EntityCollectionViewStartActions } from \"./EntityCollectionViewStartActions\";\n\nconst COLLECTION_GROUP_PARENT_ID = \"collectionGroupParent\";\n\n/**\n * @group Components\n */\nexport type EntityCollectionViewProps<M extends Record<string, any>> = {\n    /**\n     * Complete path where this collection is located.\n     * It defaults to the collection path if not provided.\n     */\n    fullPath?: string;\n    /**\n     * If this is a subcollection, specify the parent collection ids.\n     */\n    parentCollectionIds?: string[];\n    /**\n     * Whether this is a subcollection or not.\n     */\n    isSubCollection?: boolean;\n\n    className?: string;\n\n} & EntityCollection<M>;\n\n/**\n * This component is in charge of binding a datasource path with an {@link EntityCollection}\n * where it's configuration is defined. It includes an infinite scrolling table\n * and a 'Add' new entities button,\n *\n * This component is the default one used for displaying entity collections\n * and is in charge of generating all the specific actions and customization\n * of the lower level {@link EntityCollectionTable}\n *\n * Please **note** that you only need to use this component if you are building\n * a custom view. If you just need to create a default view you can do it\n * exclusively with config options.\n *\n * If you need a lower level implementation with more granular options, you\n * can use {@link EntityCollectionTable}.\n *\n * If you need a generic table that is not bound to the datasource or entities and\n * properties at all, you can check {@link VirtualTable}\n *\n * @param fullPath\n * @param collection\n * @constructor\n * @group Components\n */\nexport const EntityCollectionView = React.memo(\n    function EntityCollectionView<M extends Record<string, any>>({\n                                                                     fullPath: fullPathProp,\n                                                                     parentCollectionIds,\n                                                                     isSubCollection,\n                                                                     className,\n                                                                     ...collectionProp\n                                                                 }: EntityCollectionViewProps<M>\n    ) {\n\n        const context = useFireCMSContext();\n        const fullPath = fullPathProp ?? collectionProp.path;\n        const dataSource = useDataSource(collectionProp);\n        const navigation = useNavigationController();\n        const sideEntityController = useSideEntityController();\n        const authController = useAuthController();\n        const userConfigPersistence = useUserConfigurationPersistence();\n        const analyticsController = useAnalyticsController();\n        const customizationController = useCustomizationController();\n\n        const containerRef = React.useRef<HTMLDivElement>(null);\n\n        const collection = useMemo(() => {\n            const userOverride = userConfigPersistence?.getCollectionConfig<M>(fullPath);\n            return (userOverride ? mergeDeep(collectionProp, userOverride) : collectionProp) as EntityCollection<M>;\n        }, [collectionProp, fullPath, userConfigPersistence?.getCollectionConfig]);\n\n        const collectionRef = React.useRef(collection);\n        useEffect(() => {\n            collectionRef.current = collection;\n        }, [collection]);\n\n        const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);\n        const [selectedNavigationEntity, setSelectedNavigationEntity] = useState<Entity<M> | undefined>(undefined);\n        const [deleteEntityClicked, setDeleteEntityClicked] = React.useState<Entity<M> | Entity<M>[] | undefined>(undefined);\n\n        const [lastDeleteTimestamp, setLastDeleteTimestamp] = React.useState<number>(0);\n\n        // number of entities in the collection\n        const [docsCount, setDocsCount] = useState<number>(0);\n\n        const unselectNavigatedEntity = useCallback(() => {\n            const currentSelection = selectedNavigationEntity;\n            setTimeout(() => {\n                if (currentSelection === selectedNavigationEntity)\n                    setSelectedNavigationEntity(undefined);\n            }, 2400);\n        }, [selectedNavigationEntity]);\n\n        const checkInlineEditing = useCallback((entity?: Entity<any>): boolean => {\n            const collection = collectionRef.current;\n            if (!canEditEntity(collection, authController, fullPath, entity ?? null)) {\n                return false;\n            }\n            return collection.inlineEditing === undefined || collection.inlineEditing;\n        }, [authController, fullPath]);\n\n        const selectionEnabled = collection.selectionEnabled === undefined || collection.selectionEnabled;\n        const hoverRow = !checkInlineEditing();\n\n        const [popOverOpen, setPopOverOpen] = useState(false);\n\n        const selectionController = useSelectionController<M>();\n        const usedSelectionController = collection.selectionController ?? selectionController;\n        const {\n            selectedEntities,\n            isEntitySelected,\n            setSelectedEntities\n        } = usedSelectionController;\n\n        useEffect(() => {\n            setDeleteEntityClicked(undefined);\n        }, [selectedEntities]);\n\n        const tableController = useDataSourceEntityCollectionTableController<M>({\n            fullPath,\n            collection,\n            lastDeleteTimestamp\n        });\n\n        const tableKey = React.useRef<string>(Math.random().toString(36));\n        const popupCell = tableController.popupCell;\n\n        const onPopupClose = useCallback(() => {\n            tableController.setPopupCell?.(undefined);\n        }, [tableController.setPopupCell]);\n\n        const onEntityClick = useCallback((clickedEntity: Entity<M>) => {\n            console.log(\"Entity clicked\", clickedEntity)\n            const collection = collectionRef.current;\n            setSelectedNavigationEntity(clickedEntity);\n            analyticsController.onAnalyticsEvent?.(\"edit_entity_clicked\", {\n                path: clickedEntity.path,\n                entityId: clickedEntity.id\n            });\n            return sideEntityController.open({\n                entityId: clickedEntity.id,\n                path: clickedEntity.path,\n                collection,\n                updateUrl: true,\n                onClose: unselectNavigatedEntity,\n            });\n        }, [unselectNavigatedEntity, sideEntityController]);\n\n        const onNewClick = useCallback(() => {\n\n            const collection = collectionRef.current;\n            analyticsController.onAnalyticsEvent?.(\"new_entity_click\", {\n                path: fullPath\n            });\n            sideEntityController.open({\n                path: fullPath,\n                collection,\n                updateUrl: true,\n                onClose: unselectNavigatedEntity,\n            });\n        }, [fullPath, sideEntityController]);\n\n        const onMultipleDeleteClick = () => {\n            analyticsController.onAnalyticsEvent?.(\"multiple_delete_dialog_open\", {\n                path: fullPath\n            });\n            setDeleteEntityClicked(selectedEntities);\n        };\n\n        const internalOnEntityDelete = (_path: string, entity: Entity<M>) => {\n            analyticsController.onAnalyticsEvent?.(\"single_entity_deleted\", {\n                path: fullPath\n            });\n            setSelectedEntities((selectedEntities) => selectedEntities.filter((e) => e.id !== entity.id));\n            setLastDeleteTimestamp(Date.now());\n        };\n\n        const internalOnMultipleEntitiesDelete = (_path: string, entities: Entity<M>[]) => {\n            analyticsController.onAnalyticsEvent?.(\"multiple_entities_deleted\", {\n                path: fullPath\n            });\n            setSelectedEntities([]);\n            setDeleteEntityClicked(undefined);\n            setLastDeleteTimestamp(Date.now());\n        };\n\n        let AddColumnComponent: React.ComponentType<{\n            fullPath: string,\n            parentCollectionIds: string[],\n            collection: EntityCollection;\n        }> | undefined\n\n        // we are only using the first plugin that implements this\n        if (customizationController?.plugins) {\n            AddColumnComponent = customizationController.plugins.find(plugin => plugin.collectionView?.AddColumnComponent)?.collectionView?.AddColumnComponent;\n        }\n\n        const onCollectionModifiedForUser = useCallback((path: string, partialCollection: PartialEntityCollection<M>) => {\n            if (userConfigPersistence) {\n                const currentStoredConfig = userConfigPersistence.getCollectionConfig(path);\n                const updatedConfig = mergeDeep(currentStoredConfig, partialCollection);\n                userConfigPersistence.onCollectionModified(path, updatedConfig);\n            }\n        }, [userConfigPersistence]);\n\n        const onColumnResize = useCallback(({\n                                                width,\n                                                key\n                                            }: OnColumnResizeParams) => {\n\n            const collection = collectionRef.current;\n            // Only for property columns\n            if (!getPropertyInPath(collection.properties, key)) return;\n            const localCollection = buildPropertyWidthOverwrite(key, width);\n            onCollectionModifiedForUser(fullPath, localCollection);\n        }, [onCollectionModifiedForUser, fullPath]);\n\n        const onSizeChanged = useCallback((size: CollectionSize) => {\n            if (userConfigPersistence)\n                onCollectionModifiedForUser(fullPath, { defaultSize: size })\n        }, [onCollectionModifiedForUser, fullPath, userConfigPersistence]);\n\n        const createEnabled = canCreateEntity(collection, authController, fullPath, null);\n\n        const uniqueFieldValidator: UniqueFieldValidator = useCallback(\n            ({\n                 name,\n                 value,\n                 property,\n                 entityId\n             }) => dataSource.checkUniqueField(fullPath, name, value, entityId),\n            [fullPath]);\n\n        const onValueChange: OnCellValueChange<any, any> = ({\n                                                                value,\n                                                                propertyKey,\n                                                                onValueUpdated,\n                                                                setError,\n                                                                data: entity,\n                                                            }) => {\n\n            const updatedValues = setIn({ ...entity.values }, propertyKey, value);\n\n            const saveProps: SaveEntityProps = {\n                path: fullPath,\n                entityId: entity.id,\n                values: updatedValues,\n                previousValues: entity.values,\n                collection,\n                status: \"existing\"\n            };\n\n            return saveEntityWithCallbacks({\n                ...saveProps,\n                collection,\n                dataSource,\n                context,\n                onSaveSuccess: () => {\n                    setError(undefined);\n                    onValueUpdated();\n                },\n                onSaveFailure: (e: Error) => {\n                    console.error(\"Save failure\");\n                    console.error(e);\n                    setError(e);\n                }\n            });\n\n        };\n\n        const resolvedFullPath = navigation.resolveAliasesFrom(fullPath);\n        const resolvedCollection = useMemo(() => resolveCollection<M>({\n            collection,\n            path: fullPath,\n            fields: customizationController.propertyConfigs\n        }), [collection, fullPath]);\n\n        const getPropertyFor = useCallback(({\n                                                propertyKey,\n                                                entity\n                                            }: GetPropertyForProps<M>) => {\n            let propertyOrBuilder: PropertyOrBuilder<any, M> | undefined = getPropertyInPath<M>(collection.properties, propertyKey);\n\n            // we might not find the property in the collection if combining property builders and map spread\n            if (!propertyOrBuilder) {\n                // these 2 properties are coming from the resolved collection with default values\n                propertyOrBuilder = getPropertyInPath<M>(resolvedCollection.properties, propertyKey);\n            }\n\n            return resolveProperty({\n                propertyKey,\n                propertyOrBuilder,\n                path: fullPath,\n                values: entity.values,\n                entityId: entity.id,\n                fields: customizationController.propertyConfigs\n            });\n        }, [collection.properties, customizationController.propertyConfigs, fullPath, resolvedCollection.properties]);\n\n        const displayedColumnIds = useColumnIds(resolvedCollection, true);\n\n        const additionalFields = useMemo(() => {\n            const subcollectionColumns: AdditionalFieldDelegate<M, any>[] = collection.subcollections?.map((subcollection) => {\n                return {\n                    key: getSubcollectionColumnId(subcollection),\n                    name: subcollection.name,\n                    width: 200,\n                    dependencies: [],\n                    Builder: ({ entity }) => (\n                        <Button color={\"primary\"}\n                                variant={\"outlined\"}\n                                startIcon={<KeyboardTabIcon size={\"small\"}/>}\n                                onClick={(event: any) => {\n                                    event.stopPropagation();\n                                    sideEntityController.open({\n                                        path: fullPath,\n                                        entityId: entity.id,\n                                        selectedSubPath: subcollection.id ?? subcollection.path,\n                                        collection,\n                                        updateUrl: true,\n                                    });\n                                }}>\n                            {subcollection.name}\n                        </Button>\n                    )\n                };\n            }) ?? [];\n\n            const collectionGroupParentCollections: AdditionalFieldDelegate<M, any>[] = collection.collectionGroup\n                ? [{\n                    key: COLLECTION_GROUP_PARENT_ID,\n                    name: \"Parent entities\",\n                    width: 260,\n                    dependencies: [],\n                    Builder: ({ entity }) => {\n                        const collectionsWithPath = navigation.getParentReferencesFromPath(entity.path);\n                        return (\n                            <div className={\"flex flex-col gap-2 w-full\"}>\n                                {collectionsWithPath.map((reference) => {\n                                    return (\n                                        <ReferencePreview\n                                            key={reference.path + \"/\" + reference.id}\n                                            reference={reference}\n                                            size={\"tiny\"}/>\n                                    );\n                                })}\n                            </div>\n                        );\n                    }\n                }]\n                : [];\n\n            return [\n                ...(collection.additionalFields ?? []),\n                ...subcollectionColumns,\n                ...collectionGroupParentCollections\n            ];\n        }, [collection, fullPath, sideEntityController]);\n\n        const updateLastDeleteTimestamp = useCallback(() => {\n            setLastDeleteTimestamp(Date.now());\n        }, []);\n\n        const largeLayout = useLargeLayout();\n\n        const getActionsForEntity = ({\n                                         entity,\n                                         customEntityActions\n                                     }: {\n            entity?: Entity<M>,\n            customEntityActions?: EntityAction[]\n        }): EntityAction[] => {\n            const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity) : true;\n            const actions: EntityAction[] = [editEntityAction];\n            if (createEnabled)\n                actions.push(copyEntityAction);\n            if (deleteEnabled)\n                actions.push(deleteEntityAction);\n            if (customEntityActions)\n                actions.push(...customEntityActions);\n            return actions;\n        };\n\n        const getIdColumnWidth = () => {\n            const entityActions = getActionsForEntity({});\n            const collapsedActions = entityActions.filter(a => a.collapsed !== false);\n            const uncollapsedActions = entityActions.filter(a => a.collapsed === false);\n            const actionsWidth = uncollapsedActions.length * (largeLayout ? 40 : 30);\n            return (largeLayout ? (80 + actionsWidth) : (70 + actionsWidth)) + (collapsedActions.length > 0 ? (largeLayout ? 40 : 30) : 0);\n        };\n\n        const tableRowActionsBuilder = ({\n                                            entity,\n                                            size,\n                                            width,\n                                            frozen\n                                        }: {\n            entity: Entity<any>,\n            size: CollectionSize,\n            width: number,\n            frozen?: boolean\n        }) => {\n\n            const isSelected = isEntitySelected(entity);\n\n            const actions = getActionsForEntity({\n                entity,\n                customEntityActions: collection.entityActions\n            });\n\n            return (\n                <EntityCollectionRowActions\n                    entity={entity}\n                    width={width}\n                    frozen={frozen}\n                    isSelected={isSelected}\n                    selectionEnabled={selectionEnabled}\n                    size={size}\n                    highlightEntity={setSelectedNavigationEntity}\n                    unhighlightEntity={unselectNavigatedEntity}\n                    collection={collection}\n                    fullPath={fullPath}\n                    actions={actions}\n                    hideId={collection?.hideIdFromCollection}\n                    onCollectionChange={updateLastDeleteTimestamp}\n                    selectionController={usedSelectionController}\n                />\n            );\n\n        };\n\n        const title = <Popover\n            open={popOverOpen}\n            onOpenChange={setPopOverOpen}\n            enabled={Boolean(collection.description)}\n            trigger={<div className=\"flex flex-col items-start\">\n                <Typography\n                    variant={\"subtitle1\"}\n                    className={`leading-none truncate max-w-[160px] lg:max-w-[240px] ${collection.description ? \"cursor-pointer\" : \"cursor-auto\"}`}\n                    onClick={collection.description\n                        ? (e) => {\n                            setPopOverOpen(true);\n                            e.stopPropagation();\n                        }\n                        : undefined}>\n                    {`${collection.name}`}\n                </Typography>\n\n                <EntitiesCount\n                    fullPath={fullPath}\n                    collection={collection}\n                    filter={tableController.filterValues}\n                    sortBy={tableController.sortBy}\n                    onCountChange={setDocsCount}\n                />\n\n            </div>}\n        >\n\n            {collection.description && <div className=\"m-4 text-gray-900 dark:text-white\">\n                <Markdown source={collection.description}/>\n            </div>}\n\n        </Popover>;\n\n        const buildAdditionalHeaderWidget = useCallback(({\n                                                             property,\n                                                             propertyKey,\n                                                             onHover\n                                                         }: {\n            property: ResolvedProperty,\n            propertyKey: string,\n            onHover: boolean\n        }) => {\n            const collection = collectionRef.current;\n            if (!customizationController.plugins)\n                return null;\n            return <>\n                {customizationController.plugins.filter(plugin => plugin.collectionView?.HeaderAction)\n                    .map((plugin, i) => {\n                        const HeaderAction = plugin.collectionView!.HeaderAction!;\n                        return <HeaderAction\n                            onHover={onHover}\n                            key={`plugin_header_action_${i}`}\n                            propertyKey={propertyKey}\n                            property={property}\n                            fullPath={fullPath}\n                            collection={collection}\n                            parentCollectionIds={parentCollectionIds ?? []}/>;\n                    })}\n            </>;\n        }, [customizationController.plugins, fullPath, parentCollectionIds]);\n\n        const addColumnComponentInternal = AddColumnComponent\n            ? function () {\n                if (typeof AddColumnComponent === \"function\")\n                    return <AddColumnComponent fullPath={fullPath}\n                                               parentCollectionIds={parentCollectionIds ?? []}\n                                               collection={collection}/>;\n                return null;\n            }\n            : undefined;\n\n        const {\n            textSearchLoading,\n            textSearchInitialised,\n            onTextSearchClick,\n            textSearchEnabled\n        } = useTableSearchHelper({\n            collection,\n            fullPath: resolvedFullPath,\n            parentCollectionIds\n        });\n\n        return (\n            <div className={cn(\"overflow-hidden h-full w-full rounded-md\", className)}\n                 ref={containerRef}>\n                <EntityCollectionTable\n                    key={`collection_table_${fullPath}`}\n                    additionalFields={additionalFields}\n                    tableController={tableController}\n                    enablePopupIcon={true}\n                    displayedColumnIds={displayedColumnIds}\n                    onSizeChanged={onSizeChanged}\n                    onEntityClick={onEntityClick}\n                    onColumnResize={onColumnResize}\n                    onValueChange={onValueChange}\n                    tableRowActionsBuilder={tableRowActionsBuilder}\n                    uniqueFieldValidator={uniqueFieldValidator}\n                    title={title}\n                    selectionController={usedSelectionController}\n                    highlightedEntities={selectedNavigationEntity ? [selectedNavigationEntity] : []}\n                    defaultSize={collection.defaultSize}\n                    properties={resolvedCollection.properties}\n                    getPropertyFor={getPropertyFor}\n                    onTextSearchClick={textSearchInitialised ? undefined : onTextSearchClick}\n                    textSearchLoading={textSearchLoading}\n                    textSearchEnabled={textSearchEnabled}\n                    actionsStart={<EntityCollectionViewStartActions\n                        parentCollectionIds={parentCollectionIds ?? []}\n                        collection={collection}\n                        tableController={tableController}\n                        path={fullPath}\n                        relativePath={collection.path}\n                        selectionController={usedSelectionController}\n                        collectionEntitiesCount={docsCount}/>}\n                    actions={<EntityCollectionViewActions\n                        parentCollectionIds={parentCollectionIds ?? []}\n                        collection={collection}\n                        tableController={tableController}\n                        onMultipleDeleteClick={onMultipleDeleteClick}\n                        onNewClick={onNewClick}\n                        path={fullPath}\n                        relativePath={collection.path}\n                        selectionController={usedSelectionController}\n                        selectionEnabled={selectionEnabled}\n                        collectionEntitiesCount={docsCount}\n                    />}\n                    emptyComponent={canCreateEntities && tableController.filterValues === undefined && tableController.sortBy === undefined\n                        ? <div className=\"flex flex-col items-center justify-center\">\n                            <Typography variant={\"subtitle2\"}>So empty...</Typography>\n                            <Button\n                                color={\"primary\"}\n                                variant={\"outlined\"}\n                                onClick={onNewClick}\n                                className=\"mt-4\"\n                            >\n                                <AddIcon/>\n                                Create your first entity\n                            </Button>\n                        </div>\n                        : <Typography variant={\"label\"}>No results with the applied filter/sort</Typography>\n                    }\n                    hoverRow={hoverRow}\n                    inlineEditing={checkInlineEditing()}\n                    AdditionalHeaderWidget={buildAdditionalHeaderWidget}\n                    AddColumnComponent={addColumnComponentInternal}\n                    getIdColumnWidth={getIdColumnWidth}\n                    additionalIDHeaderWidget={<EntityIdHeaderWidget\n                        path={fullPath}\n                        collection={collection}/>}\n                />\n\n                <PopupFormField\n                    key={`popup_form_${popupCell?.propertyKey}_${popupCell?.entity?.id}`}\n                    open={Boolean(popupCell)}\n                    onClose={onPopupClose}\n                    cellRect={popupCell?.cellRect}\n                    propertyKey={popupCell?.propertyKey}\n                    collection={collection}\n                    entity={popupCell?.entity}\n                    tableKey={tableKey.current}\n                    customFieldValidator={uniqueFieldValidator}\n                    path={resolvedFullPath}\n                    onCellValueChange={onValueChange}\n                    container={containerRef.current}/>\n\n                {deleteEntityClicked &&\n                    <DeleteEntityDialog\n                        entityOrEntitiesToDelete={deleteEntityClicked}\n                        path={fullPath}\n                        collection={collection}\n                        callbacks={collection.callbacks}\n                        open={Boolean(deleteEntityClicked)}\n                        onEntityDelete={internalOnEntityDelete}\n                        onMultipleEntitiesDelete={internalOnMultipleEntitiesDelete}\n                        onClose={() => setDeleteEntityClicked(undefined)}/>}\n\n            </div>\n        );\n    }, (a, b) => {\n        return equal(a.fullPath, b.fullPath) &&\n            equal(a.parentCollectionIds, b.parentCollectionIds) &&\n            equal(a.isSubCollection, b.isSubCollection) &&\n            equal(a.className, b.className) &&\n            equal(a.properties, b.properties) &&\n            equal(a.propertiesOrder, b.propertiesOrder) &&\n            equal(a.hideIdFromCollection, b.hideIdFromCollection) &&\n            equal(a.inlineEditing, b.inlineEditing) &&\n            equal(a.selectionEnabled, b.selectionEnabled) &&\n            equal(a.selectionController, b.selectionController) &&\n            equal(a.Actions, b.Actions) &&\n            equal(a.defaultSize, b.defaultSize) &&\n            equal(a.initialFilter, b.initialFilter) &&\n            equal(a.initialSort, b.initialSort) &&\n            equal(a.textSearchEnabled, b.textSearchEnabled) &&\n            equal(a.additionalFields, b.additionalFields) &&\n            equal(a.sideDialogWidth, b.sideDialogWidth) &&\n            equal(a.forceFilter, b.forceFilter);\n    }) as React.FunctionComponent<EntityCollectionViewProps<any>>\n\nfunction EntitiesCount({\n                           fullPath,\n                           collection,\n                           filter,\n                           sortBy,\n                           onCountChange\n                       }: {\n    fullPath: string,\n    collection: EntityCollection,\n    filter?: FilterValues<any>,\n    sortBy?: [string, \"asc\" | \"desc\"],\n    onCountChange?: (count: number) => void,\n}) {\n\n    const dataSource = useDataSource(collection);\n    const navigation = useNavigationController();\n    const [count, setCount] = useState<number | undefined>(undefined);\n    const [error, setError] = useState<Error | undefined>(undefined);\n\n    const sortByProperty = sortBy ? sortBy[0] : undefined;\n    const currentSort = sortBy ? sortBy[1] : undefined;\n    const resolvedPath = useMemo(() => navigation.resolveAliasesFrom(fullPath), [fullPath, navigation.resolveAliasesFrom]);\n\n    useEffect(() => {\n        if (dataSource.countEntities)\n            dataSource.countEntities({\n                path: resolvedPath,\n                collection,\n                filter,\n                orderBy: sortByProperty,\n                order: currentSort\n            }).then(setCount).catch(setError);\n    }, [fullPath, dataSource.countEntities, resolvedPath, collection, filter, sortByProperty, currentSort]);\n\n    useEffect(() => {\n        if (onCountChange) {\n            setError(undefined);\n            onCountChange(count ?? 0);\n        }\n    }, [onCountChange, count]);\n\n    if (error) {\n        return null;\n    }\n\n    return <Typography\n        className=\"w-full text-ellipsis block overflow-hidden whitespace-nowrap max-w-xs text-left w-fit-content\"\n        variant={\"caption\"}\n        color={\"secondary\"}>\n        {count !== undefined ? `${count} entities` : <Skeleton className={\"w-full max-w-[80px] mt-1\"}/>}\n    </Typography>;\n}\n\nfunction buildPropertyWidthOverwrite(key: string, width: number): PartialEntityCollection {\n    if (key.includes(\".\")) {\n        const [parentKey, ...childKey] = key.split(\".\");\n        return { properties: { [parentKey]: buildPropertyWidthOverwrite(childKey.join(\".\"), width) } } as PartialEntityCollection;\n    }\n    return { properties: { [key]: { columnWidth: width } } } as PartialEntityCollection;\n}\n\nfunction EntityIdHeaderWidget({\n                                  collection,\n                                  path\n                              }: {\n    collection: EntityCollection,\n    path: string\n}) {\n    const [openPopup, setOpenPopup] = React.useState(false);\n    const [searchString, setSearchString] = React.useState(\"\");\n    const sideEntityController = useSideEntityController();\n    return (\n        <Tooltip title={!openPopup ? \"Find by ID\" : undefined}>\n            <Popover\n                open={openPopup}\n                onOpenChange={setOpenPopup}\n                trigger={\n                    <IconButton size={\"small\"}>\n                        <SearchIcon size={\"small\"}/>\n                    </IconButton>\n                }\n            >\n                <form noValidate={true}\n                      onSubmit={(e) => {\n                          e.preventDefault();\n                          if (!searchString) return;\n                          setOpenPopup(false);\n                          return sideEntityController.open({\n                              entityId: searchString.trim(),\n                              path,\n                              collection,\n                              updateUrl: true,\n                          });\n                      }}\n                      className={\"text-gray-900 dark:text-white w-96 max-w-full\"}>\n\n                    <div className=\"flex p-2 w-full gap-4\">\n                        <input\n                            autoFocus={openPopup}\n                            placeholder={\"Find entity by ID\"}\n                            // size={\"small\"}\n                            onChange={(e) => {\n                                setSearchString(e.target.value);\n                            }}\n                            value={searchString}\n                            className={\"flex-grow bg-transparent outline-none p-1\"}/>\n                        <Button variant={\"outlined\"}\n                                disabled={!(searchString.trim())}\n                                type={\"submit\"}\n                        >Go</Button>\n                    </div>\n                </form>\n            </Popover>\n\n        </Tooltip>\n    );\n}\n","import React from \"react\";\nimport { Link as ReactLink } from \"react-router-dom\";\nimport { Button, Typography } from \"@firecms/ui\";\n\nexport function NotFoundPage() {\n\n    return (\n        <div className=\"flex w-full h-full\">\n            <div className=\"m-auto flex items-center flex-col\"\n            >\n                <Typography variant={\"h4\"} align={\"center\"}\n                            gutterBottom={true}>\n                    Page not found\n                </Typography>\n                <Typography align={\"center\"} gutterBottom={true}>\n                    This page does not exist or you may not have access to it\n                </Typography>\n                <Button\n                    variant={\"text\"}\n                    component={ReactLink}\n                    to={\"/\"}>Back to home</Button>\n            </div>\n        </div>\n    );\n}\n","import React from \"react\";\n\nexport function FireCMSLogo({\n                                width,\n                                height,\n                                className,\n                                style\n                            }: {\n    width?: string,\n    height?: string,\n    className?: string,\n    style?: React.CSSProperties\n}) {\n    return (\n        <svg\n            width={width ?? \"100%\"} height={height ?? \"100%\"}\n            viewBox=\"0 0 599 599\" version=\"1.1\"\n            style={style}\n            className={className}\n            xmlns=\"http://www.w3.org/2000/svg\">\n            <defs>\n                <radialGradient cx=\"28.6213569%\" cy=\"43.1133328%\"\n                                fx=\"28.6213569%\"\n                                fy=\"43.1133328%\" r=\"71.5003456%\"\n                                gradientTransform=\"translate(0.286214,0.431133),rotate(3.343450),scale(1.000000,0.996175),translate(-0.286214,-0.431133)\"\n                                id=\"radialGradient-1\">\n                    <stop stopColor=\"#FF5B79\" offset=\"0%\"/>\n                    <stop stopColor=\"#FA5574\" offset=\"28.0930803%\"/>\n                    <stop stopColor=\"#EC4C51\" offset=\"44.7242531%\"/>\n                    <stop stopColor=\"#9543C1\" offset=\"71.4578165%\"/>\n                    <stop stopColor=\"#3857B3\" offset=\"100%\"/>\n                </radialGradient>\n                <radialGradient cx=\"53.6205516%\" cy=\"47.2473036%\"\n                                fx=\"53.6205516%\"\n                                fy=\"47.2473036%\" r=\"50.8229649%\"\n                                gradientTransform=\"translate(0.536206,0.472473),rotate(90.000000),scale(1.000000,1.206631),translate(-0.536206,-0.472473)\"\n                                id=\"radialGradient-2\">\n                    <stop stopColor=\"#68294F\" stopOpacity=\"0\" offset=\"0%\"/>\n                    <stop stopColor=\"#5E2548\" stopOpacity=\"0.04641108\"\n                          offset=\"75.3503173%\"/>\n                    <stop stopColor=\"#0D060B\" stopOpacity=\"0.437431709\"\n                          offset=\"100%\"/>\n                </radialGradient>\n                <radialGradient cx=\"53.8605015%\" cy=\"48.1990423%\"\n                                fx=\"53.8605015%\"\n                                fy=\"48.1990423%\" r=\"59.9151549%\"\n                                gradientTransform=\"translate(0.538605,0.481990),rotate(180.000000),scale(1.000000,0.925027),translate(-0.538605,-0.481990)\"\n                                id=\"radialGradient-3\">\n                    <stop stopColor=\"#68294F\" stopOpacity=\"0\" offset=\"0%\"/>\n                    <stop stopColor=\"#5E2548\" stopOpacity=\"0.04641108\"\n                          offset=\"84.0867343%\"/>\n                    <stop stopColor=\"#FF0000\" stopOpacity=\"0.567324765\"\n                          offset=\"100%\"/>\n                </radialGradient>\n            </defs>\n            <g id=\"Page-1\" stroke=\"none\" strokeWidth=\"1\" fill=\"none\"\n               fillRule=\"evenodd\">\n                <g id=\"firecms_logo\">\n                    <circle fill=\"url(#radialGradient-1)\" cx=\"299.5\"\n                            cy=\"299.5\"\n                            r=\"299.5\"/>\n                    <circle fill=\"url(#radialGradient-2)\" cx=\"299.5\"\n                            cy=\"299.5\"\n                            r=\"299.5\"/>\n                    <circle fill=\"url(#radialGradient-3)\" cx=\"299.5\"\n                            cy=\"299.5\"\n                            r=\"299.5\"/>\n                </g>\n            </g>\n        </svg>\n    );\n\n}\n","import React from \"react\";\n\nimport { Link as ReactLink } from \"react-router-dom\";\nimport { ErrorBoundary, FireCMSLogo } from \"../components\";\nimport {\n    Avatar,\n    cn,\n    DarkModeIcon,\n    IconButton,\n    LightModeIcon,\n    LogoutIcon,\n    Menu,\n    MenuItem,\n    Skeleton,\n    Typography\n} from \"@firecms/ui\";\nimport { useAuthController, useLargeLayout, useModeController, useNavigationController } from \"../hooks\";\nimport { User } from \"../types\";\n\nexport type FireCMSAppBarProps<ADDITIONAL_PROPS = object> = {\n\n    title: React.ReactNode;\n    /**\n     * A component that gets rendered on the upper side of the main toolbar\n     */\n    endAdornment?: React.ReactNode;\n\n    startAdornment?: React.ReactNode;\n\n    dropDownActions?: React.ReactNode;\n\n    includeDrawer?: boolean;\n\n    drawerOpen: boolean;\n\n    className?: string;\n\n    style?: React.CSSProperties;\n\n    logo?: string;\n\n    user?: User;\n} & ADDITIONAL_PROPS;\n\n/**\n * This component renders the main app bar of FireCMS.\n * You will likely not need to use this component directly.\n *\n * @param title\n * @param toolbarExtraWidget\n * @param drawerOpen\n * @constructor\n */\nexport const FireCMSAppBar = function FireCMSAppBar({\n                                                        title,\n                                                        endAdornment,\n                                                        startAdornment,\n                                                        drawerOpen,\n                                                        dropDownActions,\n                                                        includeDrawer,\n                                                        className,\n                                                        style,\n                                                        logo,\n                                                        user: userProp\n                                                    }: FireCMSAppBarProps) {\n    const navigation = useNavigationController();\n\n    const authController = useAuthController();\n    const {\n        mode,\n        toggleMode\n    } = useModeController();\n\n    const largeLayout = useLargeLayout();\n\n    const user = userProp ?? authController.user;\n\n    let avatarComponent: JSX.Element;\n    if (user && user.photoURL) {\n        avatarComponent = <Avatar\n            src={user.photoURL}/>;\n    } else if (user === undefined || authController.initialLoading) {\n        avatarComponent = <div className={\"p-1 flex justify-center\"}>\n            <Skeleton className={\"w-10 h-10 rounded-full\"}/>\n        </div>;\n    } else {\n        const initial = user?.displayName\n            ? user.displayName[0].toUpperCase()\n            : (user?.email ? user.email[0].toUpperCase() : \"A\");\n        avatarComponent = <Avatar>{initial}</Avatar>;\n    }\n\n    return (\n        <div\n            style={style}\n            className={cn(\"pr-2\",\n                {\n                    \"ml-[17rem]\": drawerOpen && largeLayout,\n                    \"ml-16\": includeDrawer && !(drawerOpen && largeLayout),\n                    \"h-16\": true,\n                    \"z-10\": largeLayout,\n                    \"transition-all\": true,\n                    \"ease-in\": true,\n                    \"duration-75\": true,\n                    \"w-full\": !includeDrawer,\n                    \"w-[calc(100%-64px)]\": includeDrawer && !(drawerOpen && largeLayout),\n                    \"w-[calc(100%-17rem)]\": includeDrawer && (drawerOpen && largeLayout),\n                    \"duration-150\": drawerOpen && largeLayout,\n                    fixed: true\n                },\n                className)}>\n\n            <div className=\"flex flex-row gap-2 px-4 h-full items-center\">\n\n                {navigation && <div className=\"mr-8 hidden lg:block\">\n                    <ReactLink\n                        className=\"visited:text-inherit visited:dark:text-inherit\"\n                        to={navigation?.basePath ?? \"/\"}\n                    >\n                        <div className={\"flex flex-row gap-4\"}>\n                            {!includeDrawer && (logo\n                                ? <img src={logo}\n                                       alt=\"Logo\"\n                                       className={cn(\"w-[32px] h-[32px]\")}/>\n                                : <FireCMSLogo width={\"32px\"} height={\"32px\"}/>)}\n\n                            {typeof title === \"string\"\n                                ? <Typography variant=\"subtitle1\"\n                                              noWrap\n                                              className={\"ml-2 !font-medium\"}>\n                                    {title}\n                                </Typography>\n                                : title}\n                        </div>\n                    </ReactLink>\n                </div>}\n\n                {startAdornment}\n\n                <div className={\"flex-grow\"}/>\n\n                {endAdornment &&\n                    <ErrorBoundary>\n                        {endAdornment}\n                    </ErrorBoundary>}\n\n                <IconButton\n                    color=\"inherit\"\n                    aria-label=\"Open drawer\"\n                    onClick={toggleMode}\n                    size=\"large\">\n                    {mode === \"dark\"\n                        ? <DarkModeIcon/>\n                        : <LightModeIcon/>}\n                </IconButton>\n\n                <Menu trigger={avatarComponent}>\n                    {user && <div className={\"px-4 py-2 mb-2\"}>\n                        {user.displayName && <Typography variant={\"body1\"} color={\"secondary\"}>\n                            {user.displayName}\n                        </Typography>}\n                        {user.email && <Typography variant={\"body2\"} color={\"secondary\"}>\n                            {user.email}\n                        </Typography>}\n                    </div>}\n\n                    {dropDownActions}\n\n                    {!dropDownActions && <MenuItem onClick={authController.signOut}>\n                        <LogoutIcon/>\n                        Log Out\n                    </MenuItem>}\n\n                </Menu>\n\n            </div>\n        </div>\n    );\n}\n","import React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { DragDropContext, Draggable, DraggableProvided, Droppable } from \"@hello-pangea/dnd\";\n\nimport { getHashValue } from \"../util\";\nimport {\n    AddIcon,\n    Button,\n    ContentCopyIcon,\n    fieldBackgroundHoverMixin, HandleIcon,\n    IconButton,\n    Menu,\n    MenuItem,\n    RemoveIcon,\n    Tooltip,\n    useOutsideAlerter\n} from \"@firecms/ui\";\n\ninterface ArrayContainerProps<T> {\n    droppableId: string;\n    value: T[];\n    addLabel: string;\n    buildEntry: (index: number, internalId: number) => React.ReactNode;\n    disabled?: boolean;\n    size?: \"small\" | \"medium\";\n    onInternalIdAdded?: (id: number) => void;\n    includeAddButton?: boolean;\n    newDefaultEntry: T;\n    onValueChange: (value: T[]) => void\n}\n\nconst buildIdsMap = (value: any[]) =>\n    value && Array.isArray(value) && value.length > 0\n        ? value.map((v, index) => {\n            if (!v) return {};\n            return ({\n                [getHashValue(v) + index]: getRandomId()\n            });\n        }).reduce((a, b) => ({ ...a, ...b }), {})\n        : {}\n\n/**\n * @group Form custom fields\n */\nexport function ArrayContainer<T>({\n                                      droppableId,\n                                      addLabel,\n                                      value,\n                                      disabled = false,\n                                      buildEntry,\n                                      size = \"medium\",\n                                      onInternalIdAdded,\n                                      includeAddButton,\n                                      newDefaultEntry,\n                                      onValueChange\n                                  }: ArrayContainerProps<T>) {\n\n    const hasValue = value && Array.isArray(value) && value.length > 0;\n\n    // Used to track the ids that have displayed the initial show animation\n    const internalIdsRef = useRef<Record<string, number>>(buildIdsMap(value));\n\n    const [internalIds, setInternalIds] = useState<number[]>(\n        hasValue\n            ? Object.values(internalIdsRef.current)\n            : []);\n\n    useEffect(() => {\n        if (hasValue && value && value.length !== internalIds.length) {\n            const newInternalIds = value.map((v, index) => {\n                const hashValue = getHashValue(v) + index;\n                if (hashValue in internalIdsRef.current) {\n                    return internalIdsRef.current[hashValue];\n                } else {\n                    const newInternalId = getRandomId();\n                    internalIdsRef.current[hashValue] = newInternalId;\n                    return newInternalId;\n                }\n            });\n            setInternalIds(newInternalIds);\n        }\n    }, [hasValue, internalIds.length, value]);\n\n    const insertInEnd = (e: React.SyntheticEvent) => {\n        e.preventDefault();\n        if (disabled) return;\n        const id = getRandomId();\n        const newIds: number[] = [...internalIds, id];\n        if (onInternalIdAdded)\n            onInternalIdAdded(id);\n        setInternalIds(newIds);\n        onValueChange([...(value ?? []), newDefaultEntry]);\n    };\n\n    const remove = (index: number) => {\n        const newIds = [...internalIds];\n        newIds.splice(index, 1);\n        setInternalIds(newIds);\n        onValueChange(value.filter((_, i) => i !== index));\n    };\n\n    const copy = (index: number) => {\n        const id = getRandomId();\n        const copyingItem = value[index];\n        const newIds: number[] = [\n            ...internalIds.splice(0, index + 1),\n            id,\n            ...internalIds.splice(index + 1, internalIds.length - index - 1)];\n        if (onInternalIdAdded)\n            onInternalIdAdded(id);\n        setInternalIds(newIds);\n        // insert value in index + 1\n        onValueChange([...value.slice(0, index + 1), copyingItem, ...value.slice(index + 1)]);\n    };\n\n    const onDragEnd = (result: any) => {\n        // dropped outside the list\n        if (!result.destination) {\n            return;\n        }\n        const sourceIndex = result.source.index;\n        const destinationIndex = result.destination.index;\n\n        const newIds = [...internalIds];\n        const temp = newIds[sourceIndex];\n        newIds[sourceIndex] = newIds[destinationIndex];\n        newIds[destinationIndex] = temp;\n        setInternalIds(newIds);\n\n        onValueChange(arrayMove(value, sourceIndex, destinationIndex));\n    };\n\n    return (\n        <DragDropContext onDragEnd={onDragEnd}>\n            <Droppable droppableId={droppableId}\n                       renderClone={(provided, snapshot, rubric) => {\n                           const index = rubric.source.index;\n                           const internalId = internalIds[index];\n                           return (\n                               <ArrayContainerItem\n                                   provided={provided}\n                                   internalId={internalId}\n                                   index={index}\n                                   size={size}\n                                   disabled={disabled}\n                                   buildEntry={buildEntry}\n                                   remove={remove}\n                                   copy={copy}\n                                   isDragging={snapshot.isDragging}\n                               />\n                           );\n                       }}\n            >\n                {(droppableProvided, droppableSnapshot) => (\n                    <div\n                        {...droppableProvided.droppableProps}\n                        ref={droppableProvided.innerRef}>\n                        {hasValue && internalIds.map((internalId: number, index: number) => {\n                            return (\n                                <Draggable\n                                    key={`array_field_${internalId}`}\n                                    draggableId={`array_field_${internalId}`}\n                                    isDragDisabled={disabled}\n                                    index={index}>\n                                    {(provided, snapshot) => (\n                                        <ArrayContainerItem\n                                            provided={provided}\n                                            internalId={internalId}\n                                            index={index}\n                                            size={size}\n                                            disabled={disabled}\n                                            buildEntry={buildEntry}\n                                            remove={remove}\n                                            copy={copy}\n                                            isDragging={snapshot.isDragging}\n                                        />\n                                    )}\n                                </Draggable>\n                            );\n                        })}\n\n                        {droppableProvided.placeholder}\n\n                        {includeAddButton && <div className=\"py-4 justify-center text-left\">\n                            <Button\n                                variant={\"text\"}\n                                size={size === \"small\" ? \"small\" : \"medium\"}\n                                color=\"primary\"\n                                disabled={disabled}\n                                startIcon={<AddIcon/>}\n                                onClick={insertInEnd}>\n                                {addLabel ?? \"Add\"}\n                            </Button>\n                        </div>}\n                    </div>\n                )}\n            </Droppable>\n        </DragDropContext>\n    );\n}\n\ntype ArrayContainerItemProps = {\n    provided: DraggableProvided,\n    index: number,\n    internalId: number,\n    size?: \"small\" | \"medium\",\n    disabled: boolean,\n    buildEntry: (index: number, internalId: number) => React.ReactNode,\n    remove: (index: number) => void,\n    copy: (index: number) => void,\n    isDragging: boolean,\n};\n\nexport function ArrayContainerItem({\n                                       provided,\n                                       index,\n                                       internalId,\n                                       size,\n                                       disabled,\n                                       buildEntry,\n                                       remove,\n                                       copy,\n                                       isDragging\n                                   }: ArrayContainerItemProps) {\n\n    const [onHover, setOnHover] = React.useState(false);\n    const setOnHoverTrue = useCallback(() => setOnHover(true), []);\n    const setOnHoverFalse = useCallback(() => setOnHover(false), []);\n\n    return <div\n        onMouseEnter={setOnHoverTrue}\n        onMouseMove={setOnHoverTrue}\n        onMouseLeave={setOnHoverFalse}\n        ref={provided.innerRef}\n        {...provided.draggableProps}\n        style={provided.draggableProps.style}\n        className={`${\n            (isDragging || onHover) ? fieldBackgroundHoverMixin : \"\"\n        } mb-1 rounded-md opacity-100`}\n    >\n        <div\n            className=\"flex items-start\">\n            <div className=\"flex-grow w-[calc(100%-48px)] text-text-primary dark:text-text-primary-dark\">\n                {buildEntry(index, internalId)}\n            </div>\n            <ArrayItemOptions direction={size === \"small\" ? \"row\" : \"column\"}\n                              disabled={disabled}\n                              remove={remove}\n                              index={index}\n                              provided={provided}\n                              copy={copy}/>\n        </div>\n    </div>;\n}\n\n\nexport function ArrayItemOptions({\n                                     direction,\n                                     disabled,\n                                     remove,\n                                     index,\n                                     provided,\n                                     copy,\n                                 }: {\n    direction?: \"row\" | \"column\",\n    disabled: boolean,\n    remove: (index: number) => void,\n    index: number,\n    provided: any,\n    copy: (index: number) => void\n}) {\n\n    const [menuOpen, setMenuOpen] = useState(false);\n\n    const iconRef = React.useRef<HTMLDivElement>(null);\n    useOutsideAlerter(iconRef, () => setMenuOpen(false));\n\n    return <div className={`pl-2 pt-1 pb-4 flex ${direction === \"row\" ? \"flex-row-reverse\" : \"flex-col\"} items-center`}\n                ref={iconRef}\n                {...provided.dragHandleProps}>\n        <Tooltip\n            delayDuration={400}\n            open={menuOpen ? false : undefined}\n            side={direction === \"column\" ? \"left\" : undefined}\n            title=\"Drag to move. Click for more options\">\n\n            <IconButton\n                size=\"small\"\n                disabled={disabled}\n                onClick={() => setMenuOpen(true)}\n                onDragStart={(e: any) => {\n                    setMenuOpen(false);\n                }}\n                className={`cursor-${disabled ? \"inherit\" : \"grab\"}`}>\n                <HandleIcon/>\n            </IconButton>\n\n            <Menu\n                portalContainer={iconRef.current}\n                open={menuOpen}\n                trigger={<div/>}>\n\n                <MenuItem dense onClick={(e) => {\n                    setMenuOpen(false);\n                    remove(index);\n                }}>\n                    <RemoveIcon size={\"small\"}/>\n                    Remove\n                </MenuItem>\n                <MenuItem dense onClick={() => {\n                    setMenuOpen(false);\n                    copy(index);\n                }}>\n                    <ContentCopyIcon size={\"small\"}/>\n                    Copy\n                </MenuItem>\n\n            </Menu>\n\n        </Tooltip>\n\n    </div>;\n}\n\nfunction arrayMove(value: any[], sourceIndex: number, destinationIndex: number) {\n    const result = Array.from(value);\n    const [removed] = result.splice(sourceIndex, 1);\n    result.splice(destinationIndex, 0, removed);\n    return result;\n}\n\nexport function getRandomId() {\n    return Math.floor(Math.random() * Math.floor(Number.MAX_SAFE_INTEGER));\n}\n","import { ArrayContainer } from \"../../components\";\nimport React from \"react\";\n\ninterface ArrayContainerProps<T> {\n    value: T[];\n    name: string;\n    addLabel: string;\n    buildEntry: (index: number, internalId: number) => React.ReactNode;\n    disabled?: boolean;\n    small?: boolean;\n    onInternalIdAdded?: (id: number) => void;\n    includeAddButton?: boolean;\n    newDefaultEntry?: T | null;\n    setFieldValue: (field: string, value: any, shouldValidate?: boolean | undefined) => void;\n}\n\n/**\n * @group Form custom fields\n */\nexport function FormikArrayContainer<T>({\n                                            name,\n                                            addLabel,\n                                            value,\n                                            disabled = false,\n                                            buildEntry,\n                                            small,\n                                            onInternalIdAdded,\n                                            includeAddButton,\n                                            newDefaultEntry = null,\n                                            setFieldValue\n                                        }: ArrayContainerProps<T>) {\n\n    return <ArrayContainer droppableId={name}\n                           addLabel={addLabel}\n                           value={value}\n                           disabled={disabled}\n                           buildEntry={buildEntry}\n                           size={small ? \"small\" : \"medium\"}\n                           onInternalIdAdded={onInternalIdAdded}\n                           includeAddButton={includeAddButton}\n                           newDefaultEntry={newDefaultEntry}\n                           onValueChange={(value) => setFieldValue(name, value)}\n    />;\n}\n","import { ResolvedProperty } from \"../../types\";\nimport { IconButton, InfoIcon, Tooltip, Typography } from \"@firecms/ui\";\n\n/**\n * Component in charge of rendering the description of a field\n * as well as the error message if any.\n */\nexport function FieldHelperText({\n                                    error,\n                                    showError,\n                                    property,\n                                    includeDescription = true,\n                                    disabled\n                                }: {\n                                    error?: string,\n                                    showError: boolean,\n                                    property: ResolvedProperty,\n                                    includeDescription?: boolean,\n                                    disabled?: boolean,\n                                }\n) {\n\n    const hasDescription = property.description || property.longDescription;\n\n    if (!(showError && error) && (!includeDescription || !hasDescription))\n        return null;\n\n    if (showError && error) {\n        return <Typography variant={\"caption\"}\n                           className={\"ml-3.5 text-red-500 dark:text-red-500\"}>\n            {error}\n        </Typography>\n    }\n\n    const disabledTooltip: string | undefined = typeof property.disabled === \"object\" ? property.disabled.disabledMessage : undefined;\n\n    return <div className={\"flex ml-3.5 mt-1\"}>\n        <Typography variant={\"caption\"}\n                    color={disabled ? \"disabled\" : \"secondary\"}\n                    className={\"flex-grow\"}>\n            {disabledTooltip || property.description}\n        </Typography>\n\n        {property.longDescription &&\n            <Tooltip title={property.longDescription}\n                     side=\"bottom\"\n            >\n                <IconButton\n                    size={\"small\"}\n                    className=\"self-start\">\n\n                    <InfoIcon color={\"disabled\"}\n                              size={\"small\"}/>\n                </IconButton>\n            </Tooltip>}\n\n    </div>\n}\n","import React from \"react\";\n\ninterface LabelWithIconProps {\n    icon: React.ReactNode;\n    title?: string;\n    small?: boolean;\n    className?: string;\n    required?: boolean;\n}\n\n/**\n * Render the label of with an icon and the title of a property\n * @group Form custom fields\n */\nexport function LabelWithIcon({\n                                  icon,\n                                  title,\n                                  small,\n                                  className,\n                                  required\n                              }: LabelWithIconProps) {\n    return (\n        <span\n            className={`inline-flex items-center my-0.5  ${small ? \"gap-1\" : \"gap-2\"} ${className ?? \"\"}`}>\n\n            {icon}\n\n            <span\n                className={`text-start font-medium text-${small ? \"base\" : \"sm\"} origin-top-left transform ${small ? \"translate-x-2 scale-75\" : \"\"}`}>{(title ?? \"\") + (required ? \" *\" : \"\")}</span>\n\n        </span>\n    );\n}\n","import React, { useCallback } from \"react\";\n\nimport { EnumType, FieldProps } from \"../../types\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { EnumValuesChip } from \"../../preview\";\nimport { getIconForProperty } from \"../../util\";\nimport { ClearIcon, cn, IconButton, Select, SelectItem } from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\ntype SelectProps<T extends EnumType> = FieldProps<T>;\n\n/**\n * If `enumValues` are set in the string config, this field renders a select\n * where each option is a colored chip.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function SelectFieldBinding<T extends EnumType>({\n                                                           propertyKey,\n                                                           value,\n                                                           setValue,\n                                                           error,\n                                                           showError,\n                                                           disabled,\n                                                           autoFocus,\n                                                           touched,\n                                                           property,\n                                                           includeDescription\n                                                       }: SelectProps<T>) {\n\n    console.log(\"SelectFieldBinding\", propertyKey, value,)\n\n    const enumValues = property.enumValues;\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    const handleClearClick = useCallback((e: React.MouseEvent) => {\n        e.stopPropagation();\n        e.preventDefault();\n        setValue(null);\n    }, [setValue]);\n\n    return (\n        <>\n\n            <Select\n                value={value !== undefined && value != null ? value.toString() : \"\"}\n                disabled={disabled}\n                position=\"item-aligned\"\n                inputClassName={cn(\"w-full\")}\n                label={<LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                                      required={property.validation?.required}\n                                      title={property.name}\n                                      className={\"text-text-secondary dark:text-text-secondary-dark ml-3.5\"}\n                />}\n                endAdornment={\n                    property.clearable && <IconButton\n                        onClick={handleClearClick}>\n                        <ClearIcon/>\n                    </IconButton>\n                }\n                onValueChange={(updatedValue: string) => {\n                    const newValue = updatedValue\n                        ? (property.dataType === \"number\" ? parseFloat(updatedValue) : updatedValue)\n                        : null;\n                    return setValue(newValue as T);\n                }}\n                renderValue={(enumKey: any) => {\n                    console.log(\"renderValue\", enumKey)\n                    return <EnumValuesChip\n                        enumKey={enumKey}\n                        enumValues={enumValues}\n                        size={\"medium\"}/>;\n                }}\n            >\n                {enumValues && enumValues.map((option) => {\n                    return <SelectItem\n                        key={option.id}\n                        value={String(option.id)}>\n                        <EnumValuesChip\n                            enumKey={String(option.id)}\n                            enumValues={enumValues}\n                            size={\"medium\"}/>\n                    </SelectItem>\n                })}\n            </Select>\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n}\n","import React, { useCallback } from \"react\";\n\nimport { EnumType, FieldProps, ResolvedProperty } from \"../../types\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { EnumValuesChip } from \"../../preview\";\nimport { enumToObjectEntries, getIconForProperty, getLabelOrConfigFrom } from \"../../util\";\nimport { CloseIcon, MultiSelect, MultiSelectItem } from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\n/**\n * This fields renders a dropdown with multiple selection.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function MultiSelectBinding({\n                                       propertyKey,\n                                       value,\n                                       setValue,\n                                       error,\n                                       showError,\n                                       disabled,\n                                       property,\n                                       includeDescription,\n                                       autoFocus\n                                   }: FieldProps<EnumType[], any, any>) {\n\n    const of: ResolvedProperty<any> | ResolvedProperty<any>[] = property.of;\n    if (!of) {\n        throw Error(\"Using wrong component ArrayEnumSelect\");\n    }\n\n    if (Array.isArray(of)) {\n        throw Error(\"Using array properties instead of single one in `of` in ArrayProperty\");\n    }\n\n    if (of.dataType !== \"string\" && of.dataType !== \"number\") {\n        throw Error(\"Field misconfiguration: array field of type string or number\");\n    }\n\n    const enumValues = enumToObjectEntries(of.enumValues);\n    if (!enumValues) {\n        console.error(property);\n        throw Error(\"Field misconfiguration: array field of type string or number needs to have enumValues\");\n    }\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    const validValue = !!value && Array.isArray(value);\n\n    const renderValue = useCallback((enumKey: string, list: boolean) => {\n        const enumValue = enumKey !== undefined ? getLabelOrConfigFrom(enumValues, enumKey) : undefined;\n        return <EnumValuesChip\n            enumKey={enumKey}\n            enumValues={enumValues}\n            size={\"medium\"}\n            key={enumKey}>\n            {enumValue?.label ?? enumKey}\n            {!list && <button\n                className=\"ml-1 ring-offset-background rounded-full outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n                onMouseDown={(e) => {\n                    e.preventDefault();\n                    e.stopPropagation();\n                }}\n                onClick={(e) => {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    setValue(value.filter(v => v !== enumKey));\n                }}\n            >\n                <CloseIcon size=\"smallest\"/>\n            </button>}\n        </EnumValuesChip>;\n    }, [enumValues, setValue, value]);\n\n    return (\n        <div className=\"mt-0.5 ml-0.5  mt-2\">\n            <MultiSelect\n                value={validValue ? value.map((v) => v.toString()) : []}\n                disabled={disabled}\n                label={<LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                                      required={property.validation?.required}\n                                      title={property.name}\n                                      className={\"text-text-secondary dark:text-text-secondary-dark ml-3.5\"}/>}\n                renderValue={useCallback((v: string) => renderValue(v, false), [renderValue])}\n                onMultiValueChange={(updatedValue: string[]) => {\n                    let newValue: EnumType[] | null;\n                    if (of && (of as ResolvedProperty)?.dataType === \"number\") {\n                        newValue = updatedValue ? (updatedValue as string[]).map((e) => parseFloat(e)) : [];\n                    } else {\n                        newValue = updatedValue;\n                    }\n                    return setValue(newValue);\n                }}>\n                {enumValues.map((enumValue) => String(enumValue.id)).map((enumKey) => (\n                    <MultiSelectItem key={enumKey} value={enumKey}>\n                        {renderValue(enumKey, true)}\n                    </MultiSelectItem>))}\n            </MultiSelect>\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </div>\n    );\n}\n","import React, { useCallback, useMemo } from \"react\";\nimport { Entity, EntityCollection, EntityReference, FieldProps, ResolvedProperty } from \"../../types\";\nimport { ReferencePreview } from \"../../preview\";\nimport { FieldHelperText, FormikArrayContainer, LabelWithIcon } from \"../components\";\nimport { ErrorView } from \"../../components\";\nimport { getIconForProperty, getReferenceFrom } from \"../../util\";\n\nimport { useNavigationController, useReferenceDialog } from \"../../hooks\";\nimport { Button, cn, ExpandablePanel, fieldBackgroundMixin } from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\ntype ArrayOfReferencesFieldProps = FieldProps<EntityReference[]>;\n\n/**\n * This field allows selecting multiple references.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function ArrayOfReferencesFieldBinding({\n                                                  propertyKey,\n                                                  value,\n                                                  error,\n                                                  showError,\n                                                  disabled,\n                                                  isSubmitting,\n                                                  tableMode,\n                                                  property,\n                                                  includeDescription,\n                                                  setValue,\n                                                  setFieldValue\n                                              }: ArrayOfReferencesFieldProps) {\n\n    const ofProperty = property.of as ResolvedProperty;\n    if (ofProperty.dataType !== \"reference\") {\n        throw Error(\"ArrayOfReferencesField expected a property containing references\");\n    }\n\n    const expanded = property.expanded === undefined ? true : property.expanded;\n    const selectedEntityIds = value && Array.isArray(value) ? value.map((ref) => ref.id) : [];\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    const navigationController = useNavigationController();\n    const collection: EntityCollection | undefined = useMemo(() => {\n        return ofProperty.path ? navigationController.getCollection(ofProperty.path) : undefined;\n    }, [ofProperty.path]);\n\n    if (!collection) {\n        throw Error(`Couldn't find the corresponding collection for the path: ${ofProperty.path}`);\n    }\n\n    const onMultipleEntitiesSelected = useCallback((entities: Entity<any>[]) => {\n        console.debug(\"onMultipleEntitiesSelected\", entities);\n        setValue(entities.map(e => getReferenceFrom(e)));\n    }, [setValue]);\n\n    const referenceDialogController = useReferenceDialog({\n            multiselect: true,\n            path: ofProperty.path,\n            collection,\n            onMultipleEntitiesSelected,\n            selectedEntityIds,\n            forceFilter: ofProperty.forceFilter\n        }\n    );\n\n    const onEntryClick = useCallback((e: React.SyntheticEvent) => {\n        e.preventDefault();\n        referenceDialogController.open();\n    }, [referenceDialogController]);\n\n    const buildEntry = useCallback((index: number, internalId: number) => {\n        const entryValue = value && value.length > index ? value[index] : undefined;\n        if (!entryValue)\n            return <div>Internal ERROR</div>;\n        return (\n                <ReferencePreview\n                    key={internalId}\n                    disabled={!ofProperty.path}\n                    previewProperties={ofProperty.previewProperties}\n                    size={\"medium\"}\n                    onClick={onEntryClick}\n                    hover={!disabled}\n                    reference={entryValue}\n                />\n        );\n    }, [ofProperty.path, ofProperty.previewProperties, value]);\n\n    const title = (\n        <LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                       required={property.validation?.required}\n                       title={property.name}\n                       className={\"text-text-secondary dark:text-text-secondary-dark\"}/>\n    );\n\n    const body = <>\n        {!collection && <ErrorView\n            error={\"The specified collection does not exist. Check console\"}/>}\n\n        {collection && <div className={\"group\"}>\n\n            <FormikArrayContainer value={value}\n                                  addLabel={property.name ? \"Add reference to \" + property.name : \"Add reference\"}\n                                  name={propertyKey}\n                                  buildEntry={buildEntry}\n                                  disabled={isSubmitting}\n                                  setFieldValue={setFieldValue}\n                                  newDefaultEntry={property.of.defaultValue}/>\n\n            <Button\n                className=\"my-4 justify-center text-left\"\n                variant=\"outlined\"\n                color=\"primary\"\n                disabled={isSubmitting}\n                onClick={onEntryClick}>\n                Edit {property.name}\n            </Button>\n        </div>}\n    </>;\n\n    return (\n        <>\n\n            {!tableMode &&\n                <ExpandablePanel\n                    titleClassName={fieldBackgroundMixin}\n                    className={cn(\"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2\", fieldBackgroundMixin)}\n                    initiallyExpanded={expanded}\n                    title={title}>\n                    {body}\n                </ExpandablePanel>}\n\n            {tableMode && body}\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n}\n","import React from \"react\";\n\nimport { Entity, EntityCollection, ResolvedStringProperty } from \"../../types\";\nimport { PreviewSize, PropertyPreview } from \"../../preview\";\n\nimport { cn, IconButton, paperMixin, RemoveIcon, Tooltip } from \"@firecms/ui\";\nimport { ErrorBoundary } from \"../../components\";\n\ninterface StorageItemPreviewProps {\n    name: string;\n    property: ResolvedStringProperty;\n    value: string,\n    entity: Entity<any>,\n    onRemove: (value: string) => void;\n    size: PreviewSize;\n    disabled: boolean;\n    collection: EntityCollection;\n}\n\nexport function StorageItemPreview({\n                                       name,\n                                       property,\n                                       value,\n                                       entity,\n                                       onRemove,\n                                       disabled,\n                                       size,\n                                       collection\n                                   }: StorageItemPreviewProps) {\n\n    return (\n        <div className={cn(paperMixin,\n            \"relative m-4 border-box flex items-center justify-center\",\n            size === \"medium\" ? \"min-w-[220px] min-h-[220px] max-w-[220px]\" : \"min-w-[118px] min-h-[118px] max-w-[118px]\")}>\n\n            {!disabled &&\n                <div\n                    className=\"absolute rounded-full -top-2 -right-2 z-10 bg-white dark:bg-gray-900\">\n\n                    <Tooltip\n                        title=\"Remove\">\n                        <IconButton\n                            size={\"small\"}\n                            onClick={(event) => {\n                                event.stopPropagation();\n                                onRemove(value);\n                            }}>\n                            <RemoveIcon size={\"small\"}/>\n                        </IconButton>\n                    </Tooltip>\n                </div>\n            }\n\n            {value &&\n                <ErrorBoundary>\n                    <PropertyPreview propertyKey={name}\n                                     value={value}\n                                     property={property}\n                        // entity={entity}\n                                     size={size}/>\n                </ErrorBoundary>\n            }\n\n\n        </div>\n    );\n\n}\n","import React from \"react\";\n\nimport { coolIconKeys, debounce, Icon, IconButton, iconKeys, SearchBar, Tooltip } from \"@firecms/ui\";\nimport { iconSynonyms, iconsSearch } from \"../util\";\n\nconst UPDATE_SEARCH_INDEX_WAIT_MS = 220;\n\nif (iconSynonyms && process.env.NODE_ENV !== \"production\") {\n    Object.keys(iconSynonyms).forEach((icon: string) => {\n        if (!iconKeys.includes(icon)) {\n            console.warn(`The icon ${icon} no longer exists. Remove it from \\`iconSynonyms\\``);\n        }\n    });\n}\n\nexport interface SearchIconsProps {\n    selectedIcon?: string;\n    onIconSelected?: (icon: string) => void;\n}\n\nexport function SearchIconsView({\n                                selectedIcon = \"\",\n                                onIconSelected\n                            }: SearchIconsProps) {\n    const [keys, setKeys] = React.useState<string[] | null>(null);\n    const [query, setQuery] = React.useState<string>(\"\");\n\n    const updateSearchResults = React.useMemo(() =>\n        debounce((value: string) => {\n            if (!value || value === \"\") {\n                setKeys(null);\n            } else {\n                const searchResult = iconsSearch.search(value);\n                setKeys(searchResult.map((e: any) => e.key));\n            }\n        }, UPDATE_SEARCH_INDEX_WAIT_MS), []\n    );\n\n    React.useEffect(() => {\n        updateSearchResults(query);\n        return () => {\n            updateSearchResults.clear();\n        };\n    }, [query, updateSearchResults]);\n\n    const icons = keys === null ? coolIconKeys : keys;\n\n    return (\n        <>\n            <SearchBar\n                autoFocus\n                innerClassName={\"w-full sticky top-0 z-10\"}\n                onTextSearch={(value?: string) => setQuery(value ?? \"\")}\n                placeholder=\"Search for more icons…\"\n            />\n\n            <div className={\"flex max-w-full flex-wrap mt-4\"}>\n                {icons.map((icon: string) => {\n                    return (\n                        <Tooltip title={icon} key={icon}>\n                            <IconButton\n                                shape={\"square\"}\n                                toggled={selectedIcon === icon}\n                                onClick={onIconSelected ? () => onIconSelected(icon) : undefined}\n                                className=\"box-content m-1\"\n                            >\n                                <Icon iconKey={icon} size={24}/>\n                            </IconButton>\n                        </Tooltip>\n                    );\n                })}\n            </div>\n        </>\n    );\n}\n","import React, { useCallback } from \"react\";\n\nimport {\n    ArrayProperty,\n    Entity,\n    EntityCollection,\n    FieldProps,\n    ResolvedArrayProperty,\n    ResolvedStringProperty,\n    StorageConfig\n} from \"../../types\";\nimport { useDropzone } from \"react-dropzone\";\nimport { PreviewSize } from \"../../preview\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\n\nimport { getIconForProperty, isReadOnly } from \"../../util\";\nimport { useSnackbarController, useStorageSource } from \"../../hooks\";\nimport { DragDropContext, Draggable, Droppable } from \"@hello-pangea/dnd\";\nimport { StorageFieldItem, useStorageUploadController } from \"../../util/useStorageUploadController\";\nimport { StorageUploadProgress } from \"../components/StorageUploadProgress\";\nimport { StorageItemPreview } from \"../components/StorageItemPreview\";\nimport {\n    cn,\n    fieldBackgroundDisabledMixin,\n    fieldBackgroundHoverMixin,\n    fieldBackgroundMixin,\n    focusedMixin,\n    Typography\n} from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\nconst dropZoneClasses = \"box-border relative pt-[2px] items-center border border-transparent min-h-[254px] outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid\";\nconst disabledClasses = \"border-dotted-gray\"\nconst nonActiveDropClasses = \"hover:bg-field-hover dark:hover:bg-field-hover-dark\"\nconst activeDropClasses = \"pt-0 border-2 border-solid\"\nconst acceptDropClasses = \"transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-green-500\"\nconst rejectDropClasses = \"transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-red-500\"\n\ntype StorageUploadFieldProps = FieldProps<string | string[]>;\n\n/**\n * Field that allows to upload files to Google Cloud Storage.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function StorageUploadFieldBinding({\n                                              propertyKey,\n                                              value,\n                                              setValue,\n                                              error,\n                                              showError,\n                                              autoFocus,\n                                              tableMode,\n                                              property,\n                                              includeDescription,\n                                              context,\n                                              isSubmitting,\n                                          }: StorageUploadFieldProps) {\n\n    if (!context.entityId)\n        throw new Error(\"StorageUploadFieldBinding: Entity id is null\");\n\n    const storageSource = useStorageSource(context.collection);\n    const disabled = isReadOnly(property) || !!property.disabled || isSubmitting;\n\n    const {\n        internalValue,\n        setInternalValue,\n        onFilesAdded,\n        storage,\n        onFileUploadComplete,\n        storagePathBuilder,\n        multipleFilesSupported\n    } = useStorageUploadController({\n        entityValues: context.values,\n        entityId: context.entityId,\n        path: context.path,\n        property,\n        propertyKey,\n        value,\n        storageSource,\n        disabled,\n        onChange: setValue\n    });\n\n    useClearRestoreValue<string | string[]>({\n        property,\n        value,\n        setValue\n    });\n\n    const entity: Entity<any> = {\n        id: context.entityId,\n        values: context.values,\n        path: context.path\n    };\n\n    return (\n\n        <>\n\n            {!tableMode &&\n                <LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                               required={property.validation?.required}\n                               title={property.name}\n                               className={\"text-text-secondary dark:text-text-secondary-dark ml-3.5\"}/>}\n\n            <StorageUpload\n                value={internalValue}\n                collection={context.collection}\n                name={propertyKey}\n                disabled={disabled}\n                autoFocus={autoFocus}\n                property={property}\n                onChange={setValue}\n                setInternalValue={setInternalValue}\n                onFilesAdded={onFilesAdded}\n                entity={entity}\n                onFileUploadComplete={onFileUploadComplete}\n                storagePathBuilder={storagePathBuilder}\n                storage={storage}\n                multipleFilesSupported={multipleFilesSupported}/>\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n}\n\nfunction FileDropComponent({\n                               storage,\n                               collection,\n                               disabled,\n                               isDraggingOver,\n                               onFilesAdded,\n                               multipleFilesSupported,\n                               droppableProvided,\n                               autoFocus,\n                               internalValue,\n                               property,\n                               entity,\n                               onClear,\n                               metadata,\n                               storagePathBuilder,\n                               onFileUploadComplete,\n                               size,\n                               name,\n                               helpText\n                           }: {\n    storage: StorageConfig,\n    collection: EntityCollection,\n    disabled: boolean,\n    isDraggingOver: boolean,\n    droppableProvided: any,\n    onFilesAdded: (acceptedFiles: File[]) => void,\n    multipleFilesSupported: boolean,\n    autoFocus: boolean,\n    internalValue: StorageFieldItem[],\n    property: ResolvedStringProperty,\n    onClear: (clearedStoragePathOrDownloadUrl: string) => void,\n    metadata: any,\n    entity: Entity<any>;\n    storagePathBuilder: (file: File) => string,\n    onFileUploadComplete: (uploadedPath: string, entry: StorageFieldItem, fileMetadata?: any) => Promise<void>,\n    size: PreviewSize,\n    name: string,\n    helpText: string\n}) {\n\n    const snackbarContext = useSnackbarController();\n\n    const {\n        getRootProps,\n        getInputProps,\n        isDragActive,\n        isDragAccept,\n        isDragReject\n    } = useDropzone({\n            accept: storage.acceptedFiles ? storage.acceptedFiles.map(e => ({ [e]: [] })).reduce((a, b) => ({ ...a, ...b }), {}) : undefined,\n            disabled: disabled || isDraggingOver,\n            noDragEventsBubbling: true,\n            maxSize: storage.maxSize,\n            onDrop: onFilesAdded,\n            onDropRejected: (fileRejections, event) => {\n                for (const fileRejection of fileRejections) {\n                    for (const error of fileRejection.errors) {\n                        snackbarContext.open({\n                            type: \"error\",\n                            message: `Error uploading file: File is larger than ${storage.maxSize} bytes`\n                        });\n                    }\n                }\n            }\n        }\n    );\n\n    return (\n        <div\n            {...getRootProps()}\n            className={cn(\n                fieldBackgroundMixin,\n                disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,\n                dropZoneClasses,\n                multipleFilesSupported && internalValue.length ? \"\" : \"flex\",\n                focusedMixin,\n                {\n                    [nonActiveDropClasses]: !isDragActive,\n                    [activeDropClasses]: isDragActive,\n                    [rejectDropClasses]: isDragReject,\n                    [acceptDropClasses]: isDragAccept,\n                    [disabledClasses]: disabled\n                })}\n        >\n            <div\n                {...droppableProvided.droppableProps}\n                ref={droppableProvided.innerRef}\n                className={cn(\"flex items-center p-1 no-scrollbar\",\n                    multipleFilesSupported && internalValue.length ? \"overflow-auto\" : \"\",\n                    multipleFilesSupported && internalValue.length ? \"min-h-[180px]\" : \"min-h-[250px]\"\n                )}\n            >\n\n                <input\n                    autoFocus={autoFocus}\n                    {...getInputProps()} />\n\n                {internalValue.map((entry, index) => {\n                    let child: any;\n                    if (entry.storagePathOrDownloadUrl) {\n                        child = (\n                            <StorageItemPreview\n                                collection={collection}\n                                name={`storage_preview_${entry.storagePathOrDownloadUrl}`}\n                                property={property}\n                                disabled={disabled}\n                                entity={entity}\n                                value={entry.storagePathOrDownloadUrl}\n                                onRemove={onClear}\n                                size={entry.size}/>\n                        );\n                    } else if (entry.file) {\n                        child = (\n                            <StorageUploadProgress\n                                entry={entry}\n                                metadata={metadata}\n                                storagePath={storagePathBuilder(entry.file)}\n                                onFileUploadComplete={onFileUploadComplete}\n                                imageSize={size === \"medium\" ? 220 : 118}\n                                simple={false}\n                            />\n                        );\n                    }\n\n                    return (\n                        <Draggable\n                            key={`array_field_${name}_${entry.id}`}\n                            draggableId={`array_field_${name}_${entry.id}`}\n                            index={index}>\n                            {(provided, snapshot) => (\n                                <div\n                                    tabIndex={-1}\n                                    ref={provided.innerRef}\n                                    {...provided.draggableProps}\n                                    {...provided.dragHandleProps}\n                                    className={cn(focusedMixin, \"rounded-md\")}\n                                    style={{\n                                        ...provided.draggableProps.style\n                                    }}\n                                >\n                                    {child}\n                                </div>\n                            )}\n                        </Draggable>\n                    );\n                })\n                }\n\n                {droppableProvided.placeholder}\n\n            </div>\n\n            <div\n                className=\"flex-grow min-h-[38px] box-border m-2 text-center\">\n                <Typography align={\"center\"}\n                            variant={\"label\"}>\n                    {helpText}\n                </Typography>\n            </div>\n\n        </div>\n    );\n}\n\nexport interface StorageUploadProps {\n    value: StorageFieldItem[];\n    collection: EntityCollection;\n    setInternalValue: (v: StorageFieldItem[]) => void;\n    name: string;\n    property: ResolvedStringProperty | ResolvedArrayProperty<string[]>;\n    onChange: (value: string | string[] | null) => void;\n    multipleFilesSupported: boolean;\n    autoFocus: boolean;\n    disabled: boolean;\n    entity: Entity<any>;\n    storage: StorageConfig;\n    onFilesAdded: (acceptedFiles: File[]) => void;\n    storagePathBuilder: (file: File) => string;\n    onFileUploadComplete: (uploadedPath: string, entry: StorageFieldItem, fileMetadata?: any) => Promise<void>;\n}\n\nexport function StorageUpload({\n                                  collection,\n                                  property,\n                                  name,\n                                  value,\n                                  setInternalValue,\n                                  onChange,\n                                  multipleFilesSupported,\n                                  onFileUploadComplete,\n                                  disabled,\n                                  onFilesAdded,\n                                  autoFocus,\n                                  storage,\n                                  entity,\n                                  storagePathBuilder,\n                              }: StorageUploadProps) {\n\n    if (multipleFilesSupported) {\n        const arrayProperty = property as ResolvedArrayProperty<string[]>;\n        if (arrayProperty.of) {\n            if (Array.isArray(arrayProperty.of)) {\n                throw Error(\"Storage field using array must be of data type string\");\n            }\n            if (arrayProperty.of.dataType !== \"string\") {\n                throw Error(\"Storage field using array must be of data type string\");\n            }\n        } else {\n            throw Error(\"Storage field using array must be of data type string\");\n        }\n    }\n\n    const metadata: Record<string, unknown> | undefined = storage?.metadata;\n    const size = multipleFilesSupported ? \"small\" : \"medium\";\n\n    const moveItem = useCallback((fromIndex: number, toIndex: number) => {\n        if (!multipleFilesSupported) return;\n        const newValue = [...value];\n        const item = newValue[fromIndex];\n        newValue.splice(fromIndex, 1);\n        newValue.splice(toIndex, 0, item);\n        setInternalValue(newValue);\n        const fieldValue = newValue\n            .filter(e => !!e.storagePathOrDownloadUrl)\n            .map(e => e.storagePathOrDownloadUrl as string);\n        onChange(fieldValue);\n    }, [multipleFilesSupported, onChange, setInternalValue, value]);\n\n    const onDragEnd = useCallback((result: any) => {\n        // dropped outside the list\n        if (!result.destination) {\n            return;\n        }\n\n        moveItem(result.source.index, result.destination.index);\n\n    }, [moveItem])\n\n    const onClear = useCallback((clearedStoragePathOrDownloadUrl: string) => {\n        if (multipleFilesSupported) {\n            const newValue: StorageFieldItem[] = value.filter(v => v.storagePathOrDownloadUrl !== clearedStoragePathOrDownloadUrl);\n            onChange(newValue.filter(v => !!v.storagePathOrDownloadUrl).map(v => v.storagePathOrDownloadUrl as string));\n            setInternalValue(newValue);\n        } else {\n            onChange(null);\n            setInternalValue([]);\n        }\n    }, [value, multipleFilesSupported, onChange]);\n\n    const helpText = multipleFilesSupported\n        ? \"Drag 'n' drop some files here, or click to select files\"\n        : \"Drag 'n' drop a file here, or click to select one\";\n\n    const renderProperty: ResolvedStringProperty = multipleFilesSupported\n        ? (property as ArrayProperty<string[]>).of as ResolvedStringProperty\n        : property as ResolvedStringProperty;\n\n    return (\n        <DragDropContext onDragEnd={onDragEnd}>\n            <Droppable\n                droppableId={`droppable_${name}`}\n                direction=\"horizontal\"\n                renderClone={(provided, snapshot, rubric) => {\n                    const entry = value[rubric.source.index];\n                    return (\n                        <div\n                            ref={provided.innerRef}\n                            {...provided.draggableProps}\n                            {...provided.dragHandleProps}\n                            style={\n                                provided.draggableProps.style\n                            }\n                            className=\"rounded\"\n                        >\n                            <StorageItemPreview\n                                collection={collection}\n                                name={`storage_preview_${entry.storagePathOrDownloadUrl}`}\n                                property={renderProperty}\n                                disabled={true}\n                                entity={entity}\n                                value={entry.storagePathOrDownloadUrl as string}\n                                onRemove={onClear}\n                                size={entry.size}/>\n                        </div>\n                    );\n                }}\n            >\n                {(provided, snapshot) => {\n                    return <FileDropComponent storage={storage}\n                                              collection={collection}\n                                              disabled={disabled}\n                                              isDraggingOver={snapshot.isDraggingOver}\n                                              droppableProvided={provided}\n                                              onFilesAdded={onFilesAdded}\n                                              multipleFilesSupported={multipleFilesSupported}\n                                              autoFocus={autoFocus}\n                                              internalValue={value}\n                                              property={renderProperty}\n                                              entity={entity}\n                                              onClear={onClear}\n                                              metadata={metadata}\n                                              storagePathBuilder={storagePathBuilder}\n                                              onFileUploadComplete={onFileUploadComplete}\n                                              size={size}\n                                              name={name}\n                                              helpText={helpText}/>\n                }}\n            </Droppable>\n        </DragDropContext>\n    );\n\n}\n","import React, { useCallback } from \"react\";\n\nimport { ClearIcon, Collapse, IconButton, TextField } from \"@firecms/ui\";\nimport { FieldProps, PreviewType } from \"../../types\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { getIconForProperty } from \"../../util\";\nimport { PropertyPreview } from \"../../preview\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\ninterface TextFieldBindingProps<T extends string | number> extends FieldProps<T> {\n    allowInfinity?: boolean\n}\n\n/**\n * Generic text field.\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function TextFieldBinding<T extends string | number>({\n                                                                context,\n                                                                propertyKey,\n                                                                value,\n                                                                setValue,\n                                                                error,\n                                                                showError,\n                                                                disabled,\n                                                                autoFocus,\n                                                                property,\n                                                                includeDescription,\n                                                            }: TextFieldBindingProps<T>) {\n\n    let multiline: boolean | undefined;\n    let url: boolean | PreviewType | undefined;\n    if (property.dataType === \"string\") {\n        multiline = property.multiline;\n        url = property.url;\n    }\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    const handleClearClick = useCallback((e: React.MouseEvent) => {\n        e.stopPropagation();\n        e.preventDefault();\n        setValue(null);\n    }, [setValue]);\n\n    const onChange = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n        if (inputType === \"number\") {\n            const numberValue = event.target.value ? parseFloat(event.target.value) : undefined;\n            if (numberValue && isNaN(numberValue)) {\n                setValue(null);\n            } else if (numberValue !== undefined && numberValue !== null) {\n                setValue(numberValue as T);\n            } else {\n                setValue(null);\n            }\n        } else {\n            setValue(event.target.value as T);\n        }\n    };\n\n    const isMultiline = Boolean(multiline);\n\n    const inputType = property.dataType === \"number\" ? \"number\" : undefined;\n    return (\n        <>\n            <TextField\n                value={value}\n                onChange={onChange}\n                autoFocus={autoFocus}\n                label={<LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                                      required={property.validation?.required}\n                                      title={property.name}/>}\n                type={inputType}\n                multiline={isMultiline}\n                disabled={disabled}\n                endAdornment={\n                    property.clearable && <IconButton\n                        onClick={handleClearClick}>\n                        <ClearIcon/>\n                    </IconButton>\n                }\n                error={showError ? error : undefined}\n                inputClassName={error ? \"text-red-500 dark:text-red-600\" : \"\"}/>\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n            {url && <Collapse\n                className=\"mt-1 ml-1\"\n                in={Boolean(value)}>\n                <PropertyPreview\n                    value={value}\n                    property={property}\n                    size={\"medium\"}/>\n            </Collapse>}\n\n        </>\n    );\n\n}\n","import React from \"react\";\n\nimport { FieldProps } from \"../../types\";\nimport { getIconForProperty } from \"../../util\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { BooleanSwitchWithLabel } from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\ntype SwitchFieldProps = FieldProps<boolean>;\n\n/**\n * Simple boolean switch biding to a boolean property.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport const SwitchFieldBinding = React.forwardRef(function SwitchFieldBinding({\n                                                                                   propertyKey,\n                                                                                   value,\n                                                                                   setValue,\n                                                                                   error,\n                                                                                   showError,\n                                                                                   autoFocus,\n                                                                                   disabled,\n                                                                                   touched,\n                                                                                   property,\n                                                                                   includeDescription\n                                                                               }: SwitchFieldProps, ref) {\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    return (\n        <>\n\n            <BooleanSwitchWithLabel\n                value={value}\n                onValueChange={(v) => setValue(v)}\n                error={showError}\n                label={<LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                                      required={property.validation?.required}\n                                      title={property.name}/>}\n                disabled={disabled}\n                autoFocus={autoFocus}\n                size={\"medium\"}\n            />\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n        </>\n\n    );\n});\n","import React from \"react\";\n\nimport { FieldProps } from \"../../types\";\n\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { useCustomizationController } from \"../../hooks\";\nimport { getIconForProperty } from \"../../util\";\nimport { DateTimeField } from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\ntype DateTimeFieldProps = FieldProps<Date>;\n\n/**\n * Field that allows selecting a date\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function DateTimeFieldBinding({\n                                         propertyKey,\n                                         value,\n                                         setValue,\n                                         autoFocus,\n                                         error,\n                                         showError,\n                                         disabled,\n                                         touched,\n                                         property,\n                                         includeDescription\n                                     }: DateTimeFieldProps) {\n\n    const { locale } = useCustomizationController();\n    const internalValue = value || null;\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    return (\n        <>\n            <DateTimeField\n                value={internalValue}\n                onChange={(dateValue) => setValue(dateValue ?? null)}\n                size={\"medium\"}\n                mode={property.mode}\n                clearable={property.clearable}\n                locale={locale}\n                error={showError}\n                label={<LabelWithIcon\n                    icon={getIconForProperty(property, \"small\")}\n                    required={property.validation?.required}\n                    className={showError ? \"text-red-500 dark:text-red-500\" : \"text-text-secondary dark:text-text-secondary-dark\"}\n                    title={property.name}/>}\n            />\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n}\n","import React from \"react\";\n\nimport { Entity, FieldProps } from \"../../types\";\n\nimport { PropertyPreview } from \"../../preview\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { ErrorBoundary } from \"../../components\";\nimport { getIconForProperty } from \"../../util\";\nimport { cn, paperMixin } from \"@firecms/ui\";\n\n/**\n *\n * Simply render the non-editable preview of a field\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function ReadOnlyFieldBinding({\n                                         propertyKey,\n                                         value,\n                                         error,\n                                         showError,\n                                         tableMode,\n                                         property,\n                                         includeDescription,\n                                         context\n                                     }: FieldProps<any>) {\n\n    if (!context.entityId)\n        throw new Error(\"ReadOnlyFieldBinding: Entity id is null\");\n\n    const entity: Entity<any> = {\n        id: context.entityId!,\n        values: context.values,\n        path: context.path\n    };\n\n    return (\n\n        <>\n\n            {!tableMode && <LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                                          required={property.validation?.required}\n                                          title={property.name}\n                                          className={\"text-text-secondary dark:text-text-secondary-dark ml-3.5\"}/>\n            }\n\n            <div\n                className={cn(paperMixin, \"min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar\")}>\n\n                <ErrorBoundary>\n                    <PropertyPreview propertyKey={propertyKey}\n                                     value={value}\n                                     property={property}\n                        // entity={entity}\n                                     size={\"medium\"}/>\n                </ErrorBoundary>\n\n            </div>\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             property={property}/>\n\n        </>\n    );\n}\n","import React, { useCallback, useMemo } from \"react\";\n\nimport { Entity, EntityCollection, EntityReference, FieldProps } from \"../../types\";\nimport { useNavigationController, useReferenceDialog } from \"../../hooks\";\nimport { ReadOnlyFieldBinding } from \"./ReadOnlyFieldBinding\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { ErrorView } from \"../../components\";\nimport { ReferencePreview } from \"../../preview\";\nimport { getIconForProperty, getReferenceFrom } from \"../../util\";\nimport { Button } from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\n/**\n * Field that opens a reference selection dialog.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function ReferenceFieldBinding<M extends Record<string, any>>(props: FieldProps<EntityReference>) {\n\n    if (typeof props.property.path !== \"string\") {\n        return <ReadOnlyFieldBinding {...props}/>\n    }\n\n    return <ReferenceFieldBindingInternal {...props}/>;\n\n}\n\nfunction ReferenceFieldBindingInternal<M extends Record<string, any>>({\n                                                                          value,\n                                                                          setValue,\n                                                                          error,\n                                                                          showError,\n                                                                          isSubmitting,\n                                                                          disabled,\n                                                                          touched,\n                                                                          autoFocus,\n                                                                          property,\n                                                                          includeDescription,\n                                                                          context\n                                                                      }: FieldProps<EntityReference>) {\n    if (!property.path) {\n        throw new Error(\"Property path is required for ReferenceFieldBinding\");\n    }\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    const validValue = value && value.isEntityReference && value.isEntityReference();\n\n    const navigationController = useNavigationController();\n    const collection: EntityCollection | undefined = useMemo(() => {\n        return property.path ? navigationController.getCollection(property.path) : undefined;\n    }, [property.path]);\n\n    if (!collection) {\n        throw Error(`Couldn't find the corresponding collection for the path: ${property.path}`);\n    }\n\n    const onSingleEntitySelected = useCallback((e: Entity<any> | null) => {\n        setValue(e ? getReferenceFrom(e) : null);\n    }, [setValue]);\n\n    const referenceDialogController = useReferenceDialog({\n            multiselect: false,\n            path: property.path,\n            collection,\n            onSingleEntitySelected,\n            selectedEntityIds: validValue ? [value.id] : undefined,\n            forceFilter: property.forceFilter\n        }\n    );\n\n    const onEntryClick = useCallback((e: React.SyntheticEvent) => {\n        e.preventDefault();\n        referenceDialogController.open();\n    }, [referenceDialogController]);\n\n    return (\n        <>\n            <LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                           required={property.validation?.required}\n                           title={property.name}\n                           className={\"text-text-secondary dark:text-text-secondary-dark ml-3.5\"}/>\n\n            {!collection && <ErrorView\n                error={\"The specified collection does not exist. Check console\"}/>}\n\n            {collection && <>\n\n                {value && <ReferencePreview\n                    disabled={!property.path}\n                    previewProperties={property.previewProperties}\n                    hover={!disabled}\n                    size={\"medium\"}\n                    onClick={disabled || isSubmitting ? undefined : onEntryClick}\n                    reference={value}\n                />}\n\n                {!value && <div className=\"justify-center text-left\">\n                    <Button variant=\"outlined\"\n                            color=\"primary\"\n                            disabled={disabled || isSubmitting}\n                            onClick={onEntryClick}>\n                        Edit {property.name}\n                    </Button>\n                </div>}\n            </>}\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n\n}\n","import React, { ComponentType, ReactElement, useCallback, useRef } from \"react\";\nimport equal from \"react-fast-compare\"\n\nimport { Field, FieldProps as FormexFieldProps, getIn } from \"@firecms/formex\";\n\nimport {\n    CMSType,\n    EntityCollection,\n    FieldProps,\n    FireCMSPlugin,\n    PluginFieldBuilderParams,\n    Property,\n    PropertyFieldBindingProps,\n    PropertyOrBuilder,\n    ResolvedProperty\n} from \"../types\";\nimport { ReadOnlyFieldBinding } from \"./field_bindings/ReadOnlyFieldBinding\";\n\nimport { isHidden, isPropertyBuilder, isReadOnly, resolveProperty } from \"../util\";\nimport { useCustomizationController } from \"../hooks\";\nimport { Typography } from \"@firecms/ui\";\nimport { getFieldConfig, getFieldId } from \"../core\";\nimport { ErrorBoundary } from \"../components\";\n\n/**\n * This component renders a form field creating the corresponding configuration\n * from a property. For example if bound to a string property, it will generate\n * a text field.\n *\n * You can use it when you are creating a custom field, and need to\n * render additional fields mapped to properties. This is useful if you\n * need to build a complex property mapping, like an array where each index\n * is a different property.\n *\n * Please note that if you build a custom field in a component, the\n * **validation** passed in the property will have no effect. You need to set\n * the validation in the `EntityCollection` definition.\n *\n * @param propertyKey You can use nested names such as `address.street` or `friends[2]`\n * @param property\n * @param context\n * @param includeDescription\n * @param underlyingValueHasChanged\n * @param disabled\n * @param tableMode\n * @param partOfArray\n * @param autoFocus\n * @group Form custom fields\n */\nexport const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a: PropertyFieldBindingProps<any>, b: PropertyFieldBindingProps<any>) => {\n    if (a.propertyKey !== b.propertyKey) {\n        return false;\n    }\n    const aIsBuilder = isPropertyBuilder(a.property) || a.property.fromBuilder;\n    const bIsBuilder = isPropertyBuilder(b.property) || b.property.fromBuilder;\n\n    const baseCheck = (aIsBuilder === bIsBuilder || equal(a.property, b.property)) &&\n        a.disabled === b.disabled;\n    if (!baseCheck) {\n        return false;\n    }\n\n    if (shouldPropertyReRender(b.property)) {\n        return false;\n    }\n\n    return false;\n}) as typeof PropertyFieldBindingInternal;\n\nfunction PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Record<string, any> = Record<string, any>>\n({\n     propertyKey,\n     property,\n     context,\n     includeDescription,\n     underlyingValueHasChanged,\n     disabled,\n     tableMode,\n     partOfArray,\n     partOfBlock,\n     autoFocus,\n }: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {\n\n    const customizationController = useCustomizationController();\n\n    return (\n        <Field\n            name={propertyKey}\n        >\n            {(fieldProps) => {\n\n                let Component: ComponentType<FieldProps<T>> | undefined;\n                const resolvedProperty: ResolvedProperty<T> | null = resolveProperty({\n                    propertyKey,\n                    propertyOrBuilder: property,\n                    values: fieldProps.form.values,\n                    path: context.path,\n                    entityId: context.entityId,\n                    fields: customizationController.propertyConfigs\n                });\n\n                if (resolvedProperty === null || isHidden(resolvedProperty)) {\n                    return <></>;\n                } else if (isReadOnly(resolvedProperty)) {\n                    Component = ReadOnlyFieldBinding;\n                } else if (resolvedProperty.Field) {\n                    if (typeof resolvedProperty.Field === \"function\") {\n                        Component = resolvedProperty.Field as ComponentType<FieldProps<any>>;\n                    }\n                } else {\n                    const propertyConfig = getFieldConfig(resolvedProperty, customizationController.propertyConfigs);\n                    if (!propertyConfig) {\n                        console.log(\"INTERNAL: Could not find field config for property\", { propertyKey, resolvedProperty, fields: customizationController.propertyConfigs, propertyConfig });\n                        throw new Error(`INTERNAL: Could not find field config for property ${propertyKey}`);\n                    }\n                    const configProperty = resolveProperty({\n                        propertyOrBuilder: propertyConfig.property,\n                        values: fieldProps.form.values,\n                        path: context.path,\n                        entityId: context.entityId,\n                        fields: customizationController.propertyConfigs\n                    });\n                    Component = configProperty.Field as ComponentType<FieldProps<T>>;\n                }\n                if (!Component) {\n                    console.warn(`No field component found for property ${propertyKey}`);\n                    console.warn(\"Property:\", property);\n                    return (\n                        <div>{`Currently the field ${resolvedProperty.dataType} is not supported`}</div>\n                    );\n                }\n\n                const componentProps: ResolvedPropertyFieldBindingProps<T, M> = {\n                    propertyKey,\n                    property: resolvedProperty,\n                    includeDescription,\n                    underlyingValueHasChanged,\n                    context,\n                    disabled,\n                    tableMode,\n                    partOfArray,\n                    partOfBlock,\n                    autoFocus\n                };\n\n                return <FieldInternal\n                    Component={Component as ComponentType<FieldProps>}\n                    componentProps={componentProps}\n                    fieldProps={fieldProps}/>;\n            }}\n        </Field>\n    );\n\n}\n\ntype ResolvedPropertyFieldBindingProps<T extends CMSType = CMSType, M extends Record<string, any> = Record<string, any>> =\n    Omit<PropertyFieldBindingProps<T, M>, \"property\">\n    & {\n    property: ResolvedProperty<T>\n};\n\nfunction FieldInternal<T extends CMSType, CustomProps, M extends Record<string, any>>\n({\n     Component,\n     componentProps: {\n         propertyKey,\n         property,\n         includeDescription,\n         underlyingValueHasChanged,\n         tableMode,\n         partOfArray,\n         partOfBlock,\n         autoFocus,\n         context,\n         disabled\n     },\n     fieldProps\n }:\n     {\n         Component: ComponentType<FieldProps<T, any, M>>,\n         componentProps: ResolvedPropertyFieldBindingProps<T, M>,\n         fieldProps: FormexFieldProps<T, any>\n     }) {\n\n    const { plugins } = useCustomizationController();\n\n    const customFieldProps: any = property.customProps;\n    const value = fieldProps.field.value;\n    // const initialValue = fieldProps.meta.initialValue;\n    const error = getIn(fieldProps.form.errors, propertyKey);\n    const touched = getIn(fieldProps.form.touched, propertyKey);\n\n    const showError: boolean = error &&\n        (fieldProps.form.submitCount > 0 || property.validation?.unique) &&\n        (!Array.isArray(error) || !!error.filter((e: any) => !!e).length);\n\n    const WrappedComponent: ComponentType<FieldProps<T, any, M>> | null = useWrappedComponent(context.path, context.collection, propertyKey, property, Component, plugins);\n    const UsedComponent: ComponentType<FieldProps<T>> = WrappedComponent ?? Component;\n\n    const isSubmitting = fieldProps.form.isSubmitting;\n\n    const setValue = useCallback((value: T | null, shouldValidate?: boolean) => {\n        fieldProps.form.setFieldTouched(propertyKey, true, false);\n        fieldProps.form.setFieldValue(propertyKey, value, shouldValidate);\n    }, []);\n\n    const setFieldValue = useCallback((otherPropertyKey: string, value: CMSType | null, shouldValidate?: boolean) => {\n        fieldProps.form.setFieldTouched(propertyKey, true, false);\n        fieldProps.form.setFieldValue(otherPropertyKey, value, shouldValidate);\n    }, []);\n\n    const cmsFieldProps: FieldProps<T, CustomProps, M> = {\n        propertyKey,\n        value: value as T,\n        // initialValue,\n        setValue,\n        setFieldValue,\n        error,\n        touched,\n        showError,\n        isSubmitting,\n        includeDescription: includeDescription ?? true,\n        property: property as ResolvedProperty<T>,\n        disabled: disabled ?? false,\n        underlyingValueHasChanged: underlyingValueHasChanged ?? false,\n        tableMode: tableMode ?? false,\n        partOfArray: partOfArray ?? false,\n        partOfBlock: partOfBlock ?? false,\n        autoFocus: autoFocus ?? false,\n        customProps: customFieldProps,\n        context\n    };\n\n    return (\n        <ErrorBoundary>\n\n            <UsedComponent {...cmsFieldProps}/>\n\n            {underlyingValueHasChanged && !isSubmitting &&\n                <Typography variant={\"caption\"} className={\"ml-3.5\"}>\n                    This value has been updated elsewhere\n                </Typography>}\n\n        </ErrorBoundary>);\n\n}\n\nconst shouldPropertyReRender = (property: PropertyOrBuilder | ResolvedProperty, plugins?: FireCMSPlugin[]): boolean => {\n    if (plugins?.some((plugin) => plugin.form?.fieldBuilder)) {\n        return true;\n    }\n    if (isPropertyBuilder(property)) {\n        return true;\n    }\n    const defAProperty = property as Property | ResolvedProperty;\n    const rerenderThisProperty = Boolean(defAProperty.Field) || (\"fromBuilder\" in defAProperty && defAProperty.fromBuilder);\n    if (defAProperty.dataType === \"map\" && defAProperty.properties) {\n        return rerenderThisProperty || Object.values(defAProperty.properties).some((childProperty) => shouldPropertyReRender(childProperty, plugins));\n    } else if (defAProperty.dataType === \"array\" && \"resolvedProperties\" in defAProperty) {\n        // @ts-ignore\n        return rerenderThisProperty || defAProperty.resolvedProperties?.some((childProperty) => childProperty && shouldPropertyReRender(childProperty, plugins));\n    } else {\n        return rerenderThisProperty;\n    }\n}\n\nfunction useWrappedComponent<T extends CMSType = CMSType, M extends Record<string, any> = any>(\n    path: string,\n    collection: EntityCollection<M>,\n    propertyKey: string,\n    property: ResolvedProperty<T>,\n    Component: ComponentType<FieldProps<T, any, M>>,\n    plugins?: FireCMSPlugin[]\n): ComponentType<FieldProps<T, any, M>> | null {\n\n    const wrapperRef = useRef<ComponentType<FieldProps<T, any, M>> | null>((() => {\n        let Wrapper: ComponentType<FieldProps<T, any, M>> | null = null;\n        if (plugins) {\n            plugins.forEach((plugin) => {\n                const fieldId = getFieldId(property);\n                if (fieldId && plugin.form?.fieldBuilder) {\n                    const params: PluginFieldBuilderParams<T> = {\n                        fieldConfigId: fieldId,\n                        propertyKey,\n                        property,\n                        Field: Component,\n                        plugin,\n                        path,\n                        collection\n                    };\n                    const enabled = plugin.form?.fieldBuilderEnabled?.(params);\n                    if (enabled === undefined || enabled)\n                        Wrapper = plugin.form.fieldBuilder(params) || Wrapper;\n                }\n                if (!fieldId) {\n                    console.warn(\"INTERNAL: Field id not found for property\", property);\n                }\n            });\n        }\n        return Wrapper;\n    })());\n\n    return wrapperRef.current;\n}\n","import React from \"react\";\nimport { FieldProps, Properties, ResolvedProperties } from \"../../types\";\n\nimport { ErrorBoundary } from \"../../components\";\nimport { getIconForProperty, isHidden, pick } from \"../../util\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { PropertyFieldBinding } from \"../PropertyFieldBinding\";\nimport { ExpandablePanel, InputLabel, Select, SelectItem } from \"@firecms/ui\";\n\n/**\n * Field that renders the children property fields\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function MapFieldBinding({\n                                    propertyKey,\n                                    value,\n                                    showError,\n                                    error,\n                                    disabled,\n                                    property,\n                                    setValue,\n                                    partOfBlock,\n                                    tableMode,\n                                    includeDescription,\n                                    underlyingValueHasChanged,\n                                    autoFocus,\n                                    context\n                                }: FieldProps<Record<string, any>>) {\n\n    const pickOnlySomeKeys = property.pickOnlySomeKeys || false;\n    const expanded = (property.expanded === undefined ? true : property.expanded) || autoFocus;\n\n    if (!property.properties) {\n        throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${propertyKey}`);\n    }\n\n    let mapProperties: ResolvedProperties;\n    if (pickOnlySomeKeys) {\n        if (value) {\n            mapProperties = pick(property.properties,\n                ...Object.keys(value)\n                    .filter(key => key in property.properties!)\n            );\n        } else {\n            mapProperties = {};\n        }\n    } else {\n        mapProperties = property.properties;\n    }\n\n    const mapFormView = <>\n        <div className=\"py-1 flex flex-col space-y-2\">\n            {Object.entries(mapProperties)\n                .filter(([_, property]) => !isHidden(property))\n                .map(([entryKey, childProperty], index) => {\n                        const fieldProps = {\n                            propertyKey: `${propertyKey}.${entryKey}`,\n                            disabled,\n                            property: childProperty,\n                            includeDescription,\n                            underlyingValueHasChanged,\n                            context,\n                            tableMode: false,\n                            partOfArray: false,\n                            partOfBlock: false,\n                            autoFocus: autoFocus && index === 0\n                        };\n                        return (\n                            <div key={`map-${propertyKey}-${index}`}>\n                                <ErrorBoundary>\n                                    <PropertyFieldBinding\n                                        {...fieldProps}/>\n                                </ErrorBoundary>\n                            </div>\n                        );\n                    }\n                )}\n        </div>\n\n        {/*{pickOnlySomeKeys && buildPickKeysSelect(disabled, property.properties, setValue, value)}*/}\n\n    </>;\n\n    const title = (\n        <LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                       required={property.validation?.required}\n                       title={property.name}\n                       className={\"text-text-secondary dark:text-text-secondary-dark\"}/>\n    );\n\n    return (\n        <ErrorBoundary>\n\n            {!tableMode && !partOfBlock && <ExpandablePanel initiallyExpanded={expanded}\n                                                            className={\"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2 bg-slate-50 bg-opacity-50 dark:bg-gray-900\"}\n                                                            title={title}>{mapFormView}</ExpandablePanel>}\n\n            {(tableMode || partOfBlock) && mapFormView}\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error ? (typeof error === \"string\" ? error : \"A property of this map has an error\") : undefined}\n                             disabled={disabled}\n                             property={property}/>\n\n        </ErrorBoundary>\n    );\n}\n\nconst buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue: (value: any) => void, value: any) => {\n\n    const keys = Object.keys(properties)\n        .filter((key) => !value || !(key in value));\n\n    const handleAddProperty = (updatedValue: string | string[]) => {\n        setValue({\n            ...value,\n            [updatedValue as string]: null\n        });\n    };\n\n    if (!keys.length) return <></>;\n\n    return <div className={\"m-4\"}>\n        <InputLabel>Add property</InputLabel>\n        <Select\n            value={\"\"}\n            disabled={disabled}\n            onValueChange={handleAddProperty}\n            renderValue={(key) => (properties as Properties)[key].name || key}>\n            {keys.map((key) => <SelectItem key={key}\n                                           value={key}>{(properties as Properties)[key].name || key}</SelectItem>)}\n        </Select>\n    </div>;\n};\n","import React, { useEffect, useState } from \"react\";\nimport { DataType, FieldProps, GeoPoint } from \"../../types\";\n\nimport { ArrayContainer } from \"../../components\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport {\n    AddIcon,\n    ArrowDropDownIcon,\n    BooleanSwitchWithLabel,\n    Button,\n    cn,\n    DateTimeField,\n    defaultBorderMixin,\n    ExpandablePanel,\n    IconButton,\n    Menu,\n    MenuItem,\n    RemoveIcon,\n    TextField,\n    Typography\n} from \"@firecms/ui\";\nimport { getDefaultValueForDataType, getIconForProperty } from \"../../util\";\nimport { useCustomizationController } from \"../../hooks\";\n\ntype MapEditViewRowState = [number, {\n    key: string,\n    dataType: DataType\n}];\n\n/**\n * Field that allows edition of key value pairs.\n *\n * @group Form fields\n */\nexport function KeyValueFieldBinding({\n                                         propertyKey,\n                                         value,\n                                         showError,\n                                         error,\n                                         disabled,\n                                         property,\n                                         setValue,\n                                         tableMode,\n                                         includeDescription,\n                                         underlyingValueHasChanged,\n                                         autoFocus,\n                                         context\n                                     }: FieldProps<Record<string, any>>) {\n\n    const expanded = (property.expanded === undefined ? true : property.expanded) || autoFocus;\n\n    if (!property.keyValue) {\n        throw Error(`Your property ${propertyKey} needs to have the 'keyValue' prop in order to use this field binding`);\n    }\n    const mapFormView = <MapEditView value={value}\n                                     setValue={setValue}\n                                     disabled={disabled}\n                                     fieldName={property.name ?? propertyKey}/>;\n\n    const title = <LabelWithIcon\n        icon={getIconForProperty(property, \"small\")}\n        required={property.validation?.required}\n        title={property.name}\n        className={\"text-text-secondary dark:text-text-secondary-dark\"}/>;\n\n    return (\n        <>\n\n            {!tableMode && <ExpandablePanel initiallyExpanded={expanded}\n                                            title={title}\n                                            className={\"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2\"}>{mapFormView}</ExpandablePanel>}\n\n            {tableMode && mapFormView}\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n}\n\ninterface MapEditViewParams<T extends Record<string, any>> {\n    value?: T;\n    setValue: (value: (T | null)) => void;\n    fieldName?: string,\n    disabled?: boolean\n}\n\nfunction MapEditView<T extends Record<string, any>>({\n                                                        value,\n                                                        setValue,\n                                                        fieldName,\n                                                        disabled\n                                                    }: MapEditViewParams<T>) {\n    const [internalState, setInternalState] = React.useState<MapEditViewRowState[]>(\n        Object.keys(value ?? {}).map((key) => [getRandomId(), {\n            key,\n            dataType: getDataType(value?.[key]) ?? \"string\"\n        }])\n    );\n\n    useEffect(() => {\n        const currentKeys = internalState.map(([id, { key }]) => key);\n        const newKeys = Object.entries(value ?? {}).filter(([key, v]) => v !== undefined).map(([key]) => key);\n        const keysToAdd = newKeys.filter((key) => !currentKeys.includes(key));\n        const keysToRemove = currentKeys.filter((key) => !newKeys.includes(key));\n        const newRowIds = [...internalState];\n        keysToAdd.forEach((key) => {\n            newRowIds.push([getRandomId(), {\n                key,\n                dataType: getDataType(value?.[key]) ?? \"string\"\n            }]);\n        });\n        keysToRemove.forEach((key) => {\n            const index = newRowIds.findIndex(([id, { key: k }]) => k === key);\n            newRowIds.splice(index, 1);\n        });\n        setInternalState(newRowIds);\n    }, [value]);\n\n    const originalValue = React.useRef<T>(value ?? {} as T);\n\n    const updateDataType = (rowId: number, dataType: DataType) => {\n        if (!rowId) {\n            console.warn(\"No key selected for data type update\");\n            return;\n        }\n        setInternalState(internalState.map((row) => {\n            if (row[0] === rowId) {\n                return [row[0], {\n                    key: row[1].key,\n                    dataType\n                }];\n            }\n            return row;\n        }));\n        setValue({\n            ...(value ?? {} as T),\n            [internalState.find((row) => row[0] === rowId)?.[1].key ?? \"\"]: getDefaultValueForDataType(dataType)\n        })\n    };\n\n    return <div className=\"py-1 flex flex-col gap-1\">\n        {internalState\n            .map(([rowId, {\n                    key: fieldKey,\n                    dataType\n                }], index) => {\n                    const entryValue = fieldKey ? value?.[fieldKey] : \"\";\n                    const onFieldKeyChange = (newKey: string) => {\n\n                        setInternalState(internalState.map((currentRowId) => {\n                            if (currentRowId[0] === rowId) {\n                                return [rowId, {\n                                    key: newKey ?? \"\",\n                                    dataType: currentRowId[1].dataType\n                                }];\n                            }\n                            return currentRowId;\n                        }));\n\n                        if (typeof value === \"object\" && newKey in value) {\n                            // if the key is already there, don't delete the previous value\n                            return;\n                        }\n\n                        const newValue = { ...(value ?? {}) } as T;\n                        if (typeof originalValue.current === \"object\" && fieldKey in originalValue.current) {\n                            // @ts-ignore\n                            newValue[fieldKey] = undefined; // set to undefined to remove from the object, the datasource will remove it from the backend\n                        } else {\n                            // @ts-ignore\n                            delete newValue[fieldKey];\n                        }\n                        setValue({\n                            ...newValue,\n                            [newKey ?? \"\"]: entryValue\n                        });\n                    };\n                    return <MapKeyValueRow rowId={rowId}\n                                           key={rowId}\n                                           fieldKey={fieldKey}\n                                           value={value ?? {} as T}\n                                           onDeleteClick={() => {\n                                               const newValue = { ...(value ?? {}) as T };\n                                               if (originalValue.current && fieldKey in originalValue.current) {\n                                                   // @ts-ignore\n                                                   newValue[fieldKey] = undefined;\n                                               } else {\n                                                   // @ts-ignore\n                                                   delete newValue[fieldKey];\n                                               }\n                                               setInternalState(internalState.filter((currentRowId) => currentRowId[0] !== rowId));\n                                               setValue({\n                                                   ...newValue\n                                               });\n                                           }}\n                                           onFieldKeyChange={onFieldKeyChange}\n                                           setValue={setValue}\n                                           entryValue={entryValue}\n                                           dataType={dataType}\n                                           disabled={disabled}\n                                           updateDataType={updateDataType}/>;\n                }\n            )}\n\n        <Button variant={\"text\"}\n                size={\"small\"}\n                color=\"primary\"\n                className=\"w-full\"\n                disabled={disabled}\n                startIcon={<AddIcon/>}\n                onClick={(e) => {\n                    e.preventDefault();\n                    setValue({\n                        ...(value ?? {} as T),\n                        \"\": null\n                    });\n                    setInternalState([...internalState, [getRandomId(), {\n                        key: \"\",\n                        dataType: \"string\"\n                    }]]);\n                }\n                }>\n            {fieldName ? `Add to ${fieldName}` : \"Add\"}\n        </Button>\n\n    </div>;\n}\n\nfunction MapKeyValueRow<T extends Record<string, any>>({\n                                                           rowId,\n                                                           fieldKey,\n                                                           value,\n                                                           onFieldKeyChange,\n                                                           onDeleteClick,\n                                                           setValue,\n                                                           entryValue,\n                                                           dataType,\n                                                           updateDataType,\n                                                           disabled\n                                                       }: {\n    rowId: number,\n    fieldKey: string,\n    value: T,\n    onFieldKeyChange: (newKey: string) => void,\n    onDeleteClick: () => void,\n    setValue: (value: (T | null)) => void,\n    entryValue: any,\n    dataType: DataType,\n    disabled?: boolean,\n    updateDataType: (rowId: number, dataType: DataType) => void\n}) {\n\n    const { locale } = useCustomizationController();\n\n    function buildInput(entryValue: any, fieldKey: string, dataType: DataType) {\n        if (dataType === \"string\" || dataType === \"number\") {\n            return <TextField\n                key={dataType}\n                placeholder={\"value\"}\n                value={entryValue}\n                type={dataType === \"number\" ? \"number\" : \"text\"}\n                size={\"small\"}\n                disabled={disabled || !fieldKey}\n                onChange={(event) => {\n                    if (dataType === \"number\") {\n                        const numberValue = event.target.value ? parseFloat(event.target.value) : undefined;\n                        if (numberValue && isNaN(numberValue)) {\n                            setValue({\n                                ...value,\n                                [fieldKey]: null\n                            });\n                        } else if (numberValue !== undefined && numberValue !== null) {\n                            setValue({\n                                ...value,\n                                [fieldKey]: numberValue\n                            });\n                        } else {\n                            setValue({\n                                ...value,\n                                [fieldKey]: null\n                            });\n                        }\n                    } else {\n                        setValue({\n                            ...value,\n                            [fieldKey]: event.target.value\n                        });\n                    }\n                }}/>;\n        } else if (dataType === \"date\") {\n            return <DateTimeField value={entryValue}\n                                  size={\"small\"}\n                                  locale={locale}\n                                  disabled={disabled || !fieldKey}\n                                  onChange={(date) => {\n                                      setValue({\n                                          ...value,\n                                          [fieldKey]: date\n                                      });\n                                  }}/>;\n        } else if (dataType === \"boolean\") {\n            return <BooleanSwitchWithLabel value={entryValue}\n                                           size={\"small\"}\n                                           position={\"start\"}\n                                           disabled={disabled || !fieldKey}\n                                           onValueChange={(newValue) => {\n                                               setValue({\n                                                   ...value,\n                                                   [fieldKey]: newValue\n                                               });\n                                           }}/>;\n        } else if (dataType === \"array\") {\n            return <div\n                className={cn(defaultBorderMixin, \"ml-2 pl-2 border-l border-solid\")}>\n                <ArrayContainer value={entryValue}\n                                newDefaultEntry={\"\"}\n                                droppableId={rowId.toString()}\n                                addLabel={fieldKey ? `Add to ${fieldKey}` : \"Add\"}\n                                size={\"small\"}\n                                disabled={disabled || !fieldKey}\n                                includeAddButton={true}\n                                onValueChange={(newValue) => {\n                                    setValue({\n                                        ...value,\n                                        [fieldKey]: newValue\n                                    });\n                                }}\n                                buildEntry={(index, internalId) => {\n                                    return <ArrayKeyValueRow\n                                        index={index}\n                                        id={internalId}\n                                        value={entryValue[index]}\n                                        disabled={disabled || !fieldKey}\n                                        setValue={(newValue) => {\n                                            const newArrayValue = [...entryValue];\n                                            newArrayValue[index] = newValue;\n                                            setValue({\n                                                ...value,\n                                                [fieldKey]: newArrayValue\n                                            });\n                                        }}\n                                    />\n                                }}/>\n            </div>;\n        } else if (dataType === \"map\") {\n            return <div\n                className={cn(defaultBorderMixin, \"ml-2 pl-2 border-l border-solid\")}>\n                <MapEditView value={entryValue}\n                             fieldName={fieldKey}\n                             setValue={(updatedValue) => {\n                                 setValue({\n                                     ...value,\n                                     [fieldKey]: updatedValue\n                                 });\n                             }}/>\n            </div>;\n        } else {\n            return <Typography\n                variant={\"caption\"}>\n                {`Data type ${dataType} not supported yet`}\n            </Typography>;\n        }\n    }\n\n    function doUpdateDataType(dataType: DataType) {\n        updateDataType(rowId, dataType);\n    }\n\n    return (<>\n            <Typography key={rowId.toString()}\n                        component={\"div\"}\n                        className=\"font-mono flex flex-row gap-1\">\n                <div className=\"w-[200px] max-w-[25%]\">\n                    <TextField\n                        value={fieldKey}\n                        placeholder={\"key\"}\n                        disabled={disabled || (entryValue !== undefined && entryValue !== null && entryValue !== \"\")}\n                        size={\"small\"}\n                        onChange={(event) => {\n                            onFieldKeyChange(event.target.value);\n                        }}/>\n                </div>\n\n                <div className=\"flex-grow\">\n                    {(dataType !== \"map\" && dataType !== \"array\") && buildInput(entryValue, fieldKey, dataType)}\n                </div>\n                <Menu\n                    trigger={<IconButton size={\"small\"}\n                                         className=\"h-7 w-7\">\n                        <ArrowDropDownIcon/>\n                    </IconButton>}\n                >\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"string\")}>string</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"number\")}>number</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"boolean\")}>boolean</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"date\")}>date</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"map\")}>map</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"array\")}>array</MenuItem>\n                </Menu>\n\n                <IconButton aria-label=\"delete\"\n                            size={\"small\"}\n                            onClick={onDeleteClick}\n                            className=\"h-7 w-7\">\n                    <RemoveIcon size={\"small\"}/>\n                </IconButton>\n            </Typography>\n\n            {(dataType === \"map\" || dataType === \"array\") && buildInput(entryValue, fieldKey, dataType)}\n\n        </>\n\n    );\n}\n\nfunction ArrayKeyValueRow<T>({\n                                 id,\n                                 index,\n                                 value,\n                                 setValue\n                             }: {\n    id: number,\n    index: number,\n    value: T,\n    setValue: (value: T | null) => void,\n    disabled?: boolean,\n}) {\n\n    const { locale } = useCustomizationController();\n    const [selectedDataType, setSelectedDataType] = useState<DataType>(getDataType(value) ?? \"string\");\n\n    function doUpdateDataType(dataType: DataType) {\n        setSelectedDataType(dataType);\n    }\n\n    function buildInput(entryValue: any, dataType: DataType) {\n        if (dataType === \"string\" || dataType === \"number\") {\n            return <TextField value={entryValue}\n                              type={dataType === \"number\" ? \"number\" : \"text\"}\n                              size={\"small\"}\n                              onChange={(event) => {\n                                  if (dataType === \"number\") {\n                                      const numberValue = event.target.value ? parseFloat(event.target.value) : undefined;\n                                      if (numberValue && isNaN(numberValue)) {\n                                          setValue(null);\n                                      } else if (numberValue !== undefined && numberValue !== null) {\n                                          setValue(numberValue as T);\n                                      } else {\n                                          setValue(null);\n                                      }\n                                  } else {\n                                      setValue(event.target.value as T);\n                                  }\n                              }}/>;\n        } else if (dataType === \"date\") {\n            return <DateTimeField value={entryValue}\n                                  size={\"small\"}\n                                  locale={locale}\n                                  onChange={(date) => {\n                                      setValue(date as T);\n                                  }}/>;\n        } else if (dataType === \"boolean\") {\n            return <BooleanSwitchWithLabel value={entryValue}\n                                           size={\"small\"}\n                                           position={\"start\"}\n                                           onValueChange={(v) => {\n                                               setValue(v as T);\n                                           }}/>;\n        } else if (dataType === \"array\") {\n            return <Typography variant={\"caption\"}>\n                Arrays of arrays are not supported.\n            </Typography>;\n        } else if (dataType === \"map\") {\n            return <div className={cn(defaultBorderMixin, \"ml-2 pl-2 border-l border-solid\")}>\n                <MapEditView value={entryValue}\n                             setValue={(updatedValue) => {\n                                 setValue(updatedValue);\n                             }}/>\n            </div>;\n        } else {\n            return <Typography\n                variant={\"caption\"}>\n                {`Data type ${dataType} not supported yet`}\n            </Typography>;\n        }\n    }\n\n    return (<>\n            <Typography key={id.toString()}\n                        component={\"div\"}\n                        className=\"font-mono flex min-h-12 flex-row gap-1 items-center\">\n\n                <div className=\"flex-grow\">\n                    {selectedDataType !== \"map\" && buildInput(value, selectedDataType)}\n                </div>\n\n                <Menu\n                    trigger={<IconButton size={\"small\"}\n                                         className=\"h-7 w-7\">\n                        <ArrowDropDownIcon/>\n                    </IconButton>}>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"string\")}>string</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"number\")}>number</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"boolean\")}>boolean</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"map\")}>map</MenuItem>\n                    <MenuItem dense\n                              onClick={() => doUpdateDataType(\"date\")}>date</MenuItem>\n                </Menu>\n\n            </Typography>\n\n            {selectedDataType === \"map\" && buildInput(value, selectedDataType)}\n\n        </>\n\n    );\n}\n\nfunction getRandomId() {\n    return Math.floor(Math.random() * Math.floor(Number.MAX_SAFE_INTEGER));\n}\n\nfunction getDataType(value: any): DataType | undefined {\n    if (typeof value === \"string\" || value === null) {\n        return \"string\";\n    } else if (typeof value === \"number\") {\n        return \"number\";\n    } else if (typeof value === \"boolean\") {\n        return \"boolean\";\n    } else if (Array.isArray(value)) {\n        return \"array\";\n    } else if (value instanceof Date) {\n        return \"date\";\n    } else if (value?.isEntityReference && value?.isEntityReference()) {\n        return \"reference\";\n    } else if (value instanceof GeoPoint) {\n        return \"geopoint\";\n    } else if (typeof value === \"object\") {\n        return \"map\";\n    }\n\n    return undefined;\n}\n","import React, { useState } from \"react\";\nimport { CMSType, FieldProps, ResolvedProperty } from \"../../types\";\nimport { FieldHelperText, FormikArrayContainer, LabelWithIcon } from \"../components\";\nimport { ErrorBoundary } from \"../../components\";\nimport { getIconForProperty } from \"../../util\";\nimport { PropertyFieldBinding } from \"../PropertyFieldBinding\";\nimport { ExpandablePanel } from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\n/**\n * Generic array field that allows reordering and renders the child property\n * as nodes.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function RepeatFieldBinding<T extends Array<any>>({\n                                                             propertyKey,\n                                                             value,\n                                                             error,\n                                                             showError,\n                                                             isSubmitting,\n                                                             setValue,\n                                                             setFieldValue,\n                                                             tableMode,\n                                                             property,\n                                                             includeDescription,\n                                                             underlyingValueHasChanged,\n                                                             context,\n                                                             disabled\n                                                         }: FieldProps<T>) {\n\n    if (!property.of)\n        throw Error(\"RepeatFieldBinding misconfiguration. Property `of` not set\");\n\n    if (!property.resolvedProperties || !Array.isArray(property.resolvedProperties))\n        throw Error(\"RepeatFieldBinding - Internal error: Expected array in 'property.resolvedProperties'\");\n\n    const expanded = property.expanded === undefined ? true : property.expanded;\n    const ofProperty: ResolvedProperty<CMSType[]> = property.of as ResolvedProperty<CMSType[]>;\n\n    const [lastAddedId, setLastAddedId] = useState<number | undefined>();\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    const buildEntry = (index: number, internalId: number) => {\n        const childProperty = property.resolvedProperties[index] ?? ofProperty;\n        const fieldProps = {\n            propertyKey: `${propertyKey}.${index}`,\n            disabled,\n            property: childProperty,\n            includeDescription,\n            underlyingValueHasChanged,\n            context,\n            tableMode: false,\n            partOfArray: true,\n            partOfBlock: false,\n            autoFocus: internalId === lastAddedId\n        };\n        return <ErrorBoundary>\n            <PropertyFieldBinding {...fieldProps}/>\n        </ErrorBoundary>;\n    };\n\n    const arrayContainer = <FormikArrayContainer value={value}\n                                                 addLabel={property.name ? \"Add entry to \" + property.name : \"Add entry\"}\n                                                 name={propertyKey}\n                                                 setFieldValue={setFieldValue}\n                                                 buildEntry={buildEntry}\n                                                 onInternalIdAdded={setLastAddedId}\n                                                 disabled={isSubmitting || Boolean(property.disabled)}\n                                                 includeAddButton={!property.disabled}\n                                                 newDefaultEntry={property.of.defaultValue}/>;\n\n    const title = (<LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                                  required={property.validation?.required}\n                                  title={property.name}\n                                  className={\"text-text-secondary dark:text-text-secondary-dark\"}/>);\n\n    return (\n\n        <>\n\n            {!tableMode && <ExpandablePanel initiallyExpanded={expanded}\n                                            className={\"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2\"}\n                                            title={title}>\n                {arrayContainer}\n            </ExpandablePanel>}\n\n            {tableMode && arrayContainer}\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n}\n","import React, { useCallback, useEffect, useState } from \"react\";\n\nimport { Field, useFormex } from \"@firecms/formex\";\n\nimport { FieldHelperText, FormikArrayContainer, LabelWithIcon } from \"../components\";\nimport { PropertyFieldBinding } from \"../PropertyFieldBinding\";\nimport { EnumValuesChip } from \"../../preview\";\nimport { FieldProps, FormContext, PropertyFieldBindingProps, PropertyOrBuilder } from \"../../types\";\nimport { getDefaultValueFor, getIconForProperty, } from \"../../util\";\nimport { DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE } from \"../../util/common\";\nimport { cn, ExpandablePanel, paperMixin, Select, SelectItem, Typography } from \"@firecms/ui\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\n/**\n * If the `oneOf` property is specified, this fields render each array entry as\n * a `type` select and the corresponding field widget to the selected `type.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function BlockFieldBinding<T extends Array<any>>({\n                                                            propertyKey,\n                                                            value,\n                                                            error,\n                                                            showError,\n                                                            isSubmitting,\n                                                            setValue,\n                                                            setFieldValue,\n                                                            tableMode,\n                                                            property,\n                                                            includeDescription,\n                                                            underlyingValueHasChanged,\n                                                            context,\n                                                            disabled\n                                                        }: FieldProps<T>) {\n\n    if (!property.oneOf)\n        throw Error(\"ArrayOneOfField misconfiguration. Property `oneOf` not set\");\n\n    const expanded = property.expanded === undefined ? true : property.expanded;\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    const [lastAddedId, setLastAddedId] = useState<number | undefined>();\n\n    const buildEntry = useCallback((index: number, internalId: number) => {\n        return <BlockEntry\n            key={`array_one_of_${index}`}\n            name={`${propertyKey}.${index}`}\n            index={index}\n            value={value[index]}\n            typeField={property.oneOf!.typeField ?? DEFAULT_ONE_OF_TYPE}\n            valueField={property.oneOf!.valueField ?? DEFAULT_ONE_OF_VALUE}\n            properties={property.oneOf!.properties}\n            autoFocus={internalId === lastAddedId}\n            context={context}/>;\n    }, [context, lastAddedId, property.oneOf, propertyKey, value]);\n\n    const title = (\n        <LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                       required={property.validation?.required}\n                       title={property.name}\n                       className={\"text-text-secondary dark:text-text-secondary-dark\"}/>\n    );\n\n    const firstOneOfKey = Object.keys(property.oneOf.properties)[0];\n    const body = <FormikArrayContainer value={value}\n                                       name={propertyKey}\n                                       addLabel={property.name ? \"Add entry to \" + property.name : \"Add entry\"}\n                                       buildEntry={buildEntry}\n                                       onInternalIdAdded={setLastAddedId}\n                                       disabled={isSubmitting || Boolean(property.disabled)}\n                                       includeAddButton={!property.disabled}\n                                       setFieldValue={setFieldValue}\n                                       newDefaultEntry={{\n                                           [property.oneOf!.typeField ?? DEFAULT_ONE_OF_TYPE]: firstOneOfKey,\n                                           [property.oneOf!.valueField ?? DEFAULT_ONE_OF_VALUE]: getDefaultValueFor(property.oneOf.properties[firstOneOfKey])\n                                       }}/>;\n    return (\n\n        <>\n\n            {!tableMode &&\n                <ExpandablePanel\n                    className={\"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2\"}\n                    initiallyExpanded={expanded}\n                    title={title}>\n                    {body}\n                </ExpandablePanel>}\n\n            {tableMode && body}\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n}\n\ninterface BlockEntryProps {\n    name: string;\n    index: number;\n    value: any;\n    /**\n     * Name of the field to use as the discriminator for type\n     * Defaults to `type`\n     */\n    typeField: string;\n    /**\n     * Name of the  field to use as the value\n     * Defaults to `value`\n     */\n    valueField: string;\n\n    autoFocus: boolean;\n    /**\n     * Record of properties, where the key is the `type` and the value\n     * is the corresponding property\n     */\n    properties: Record<string, PropertyOrBuilder>;\n\n    /**\n     * Additional values related to the state of the form or the entity\n     */\n    context: FormContext<any>;\n\n}\n\nfunction BlockEntry({\n                        name,\n                        index,\n                        value,\n                        typeField,\n                        valueField,\n                        properties,\n                        autoFocus,\n                        context\n                    }: BlockEntryProps) {\n\n    const type = value && value[typeField];\n    const [typeInternal, setTypeInternal] = useState<string | undefined>(type ?? undefined);\n\n    const formex = useFormex();\n\n    useEffect(() => {\n        if (!type) {\n            updateType(Object.keys(properties)[0]);\n        }\n    }, []);\n\n    useEffect(() => {\n        if (type !== typeInternal) {\n            setTypeInternal(type);\n        }\n    }, [type]);\n\n    const property = typeInternal ? properties[typeInternal] : undefined;\n\n    const enumValuesConfigs = Object.entries(properties)\n        .map(([key, property]) => ({\n            id: key,\n            label: property.name ?? key\n        }));\n\n    const typeFieldName = `${name}.${typeField}`;\n    const valueFieldName = `${name}.${valueField}`;\n\n    const fieldProps: PropertyFieldBindingProps<any, any> | undefined = property\n        ? {\n            propertyKey: valueFieldName,\n            property,\n            context,\n            autoFocus,\n            partOfArray: false,\n            partOfBlock: true,\n            tableMode: false\n        }\n        : undefined;\n\n    const updateType = (newType: any) => {\n        const newSelectedProperty = newType ? properties[newType] : undefined;\n        setTypeInternal(newType);\n        formex.setFieldTouched(typeFieldName, true);\n        formex.setFieldValue(typeFieldName, newType);\n        formex.setFieldValue(valueFieldName, newSelectedProperty ? getDefaultValueFor(newSelectedProperty) : null);\n    };\n\n    return (\n        <div className={cn(paperMixin, \"bg-transparent p-4 my-4 py-8\")}>\n\n            <Field\n                name={typeFieldName}\n            >\n                {(fieldProps) => {\n                    const value1 = fieldProps.field.value !== undefined && fieldProps.field.value !== null ? fieldProps.field.value as string : \"\";\n                    return (\n                        <>\n                            <Select\n                                className=\"mb-2\"\n                                placeholder={<Typography variant={\"caption\"}\n                                                         className={\"px-4 py-2 font-medium\"}>Type</Typography>}\n                                size={\"small\"}\n                                position={\"item-aligned\"}\n                                value={value1}\n                                renderValue={(enumKey: any) =>\n                                    <EnumValuesChip\n                                        enumKey={enumKey}\n                                        enumValues={enumValuesConfigs}\n                                        size={\"small\"}/>\n                                }\n                                onValueChange={(value) => {\n                                    updateType(value);\n                                }}>\n                                {enumValuesConfigs.map((enumConfig) => (\n                                    <SelectItem\n                                        key={enumConfig.id}\n                                        value={String(enumConfig.id)}>\n                                        <EnumValuesChip\n                                            enumKey={enumConfig.id}\n                                            enumValues={enumValuesConfigs}\n                                            size={\"small\"}/>\n                                    </SelectItem>)\n                                )}\n                            </Select>\n                        </>\n                    );\n                }\n                }\n            </Field>\n\n            {fieldProps && (\n                // It is important to use this key to force a re-render of the field on type change\n                <PropertyFieldBinding key={`form_control_${name}_${typeInternal}`} {...fieldProps}/>\n            )}\n\n        </div>\n    );\n}\n","import React, { useDeferredValue, useEffect, useRef } from \"react\";\n\n// @ts-ignore\nimport MarkdownIt from \"markdown-it\";\nimport MdEditor, { Plugins } from \"react-markdown-editor-lite\";\n\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { FieldProps } from \"../../types\";\nimport { getIconForProperty } from \"../../util\";\nimport {\n    cn,\n    fieldBackgroundDisabledMixin,\n    fieldBackgroundHoverMixin,\n    fieldBackgroundMixin,\n    Typography,\n    useInjectStyles\n} from \"@firecms/ui\";\n\nconst mdParser = new MarkdownIt();\ntry {\n    MdEditor.use(Plugins.AutoResize, {\n        min: 100\n    })\n    MdEditor.unuse(Plugins.FontUnderline)\n    MdEditor.unuse(Plugins.Clear);\n} catch (e) {\n    // this fails in some tests, we can ignore it\n}\n\n/**\n * Render a markdown field that allows edition and seeing the preview.\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function MarkdownFieldBinding({\n                                         propertyKey,\n                                         value,\n                                         setValue,\n                                         error,\n                                         showError,\n                                         disabled,\n                                         autoFocus,\n                                         touched,\n                                         property,\n                                         tableMode,\n                                         includeDescription,\n                                         context\n                                     }: FieldProps<string>) {\n\n    const [internalValue, setInternalValue] = React.useState(value);\n    const valueRef = useRef(value);\n\n    useInjectStyles(\"MarkdownFieldBinding\", markdownCss);\n\n    const deferred = useDeferredValue({\n        internalValue,\n        value\n    });\n\n    useEffect(() => {\n        valueRef.current = value;\n        setInternalValue(value);\n    }, [value]);\n\n    useEffect(() => {\n        if (deferred.internalValue !== valueRef.current)\n            setValue(deferred.internalValue);\n    }, [deferred]);\n\n    return (\n        <>\n\n            {!tableMode && <Typography variant={\"caption\"}\n                                       className={\"flex-grow\"}>\n                <LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                               required={property.validation?.required}\n                               title={property.name}\n                               className={\"text-text-secondary dark:text-text-secondary-dark ml-3.5\"}/>\n            </Typography>}\n\n            <MdEditor value={internalValue ?? \"\"}\n                      className={cn(fieldBackgroundMixin,\n                          disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,\n                          \"text-base\")}\n                      readOnly={disabled}\n                      renderHTML={text => mdParser.render(text)}\n                      view={{\n                          menu: true,\n                          md: true,\n                          html: false\n                      }}\n                      onChange={({\n                                     html,\n                                     text\n                                 }) => {\n                          setInternalValue(text ?? null);\n                      }}/>\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n\n}\n\nconst markdownCss = `\n  @font-face {\n    font-family: rmel-iconfont;\n    src: url(data:application/vnd.ms-fontobject;base64,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NS4BJyMOAd0VGwEBGxWRFRsbFWEcFBQcYRUbGxWRFRsBARsCK2EVGxsVkRUbAQEbKRySARsVYRwpGwEBGxWRFRsBHwEbFZEVGwEBGykcYRUbwwEbFWEcKRsBARsVkRUb/qscKRsBARsVkRUbGxUBtRQcYRUbGxWRFRsBARsAAAAAAAASAN4AAQAAAAAAAAAVAAAAAQAAAAAAAQANABUAAQAAAAAAAgAHACIAAQAAAAAAAwANACkAAQAAAAAABAANADYAAQAAAAAABQALAEMAAQAAAAAABgANAE4AAQAAAAAACgArAFsAAQAAAAAACwATAIYAAwABBAkAAAAqAJkAAwABBAkAAQAaAMMAAwABBAkAAgAOAN0AAwABBAkAAwAaAOsAAwABBAkABAAaAQUAAwABBAkABQAWAR8AAwABBAkABgAaATUAAwABBAkACgBWAU8AAwABBAkACwAmAaUKQ3JlYXRlZCBieSBpY29uZm9udApybWVsLWljb25mb250UmVndWxhcnJtZWwtaWNvbmZvbnRybWVsLWljb25mb250VmVyc2lvbiAxLjBybWVsLWljb25mb250R2VuZXJhdGVkIGJ5IHN2ZzJ0dGYgZnJvbSBGb250ZWxsbyBwcm9qZWN0Lmh0dHA6Ly9mb250ZWxsby5jb20ACgBDAHIAZQBhAHQAZQBkACAAYgB5ACAAaQBjAG8AbgBmAG8AbgB0AAoAcgBtAGUAbAAtAGkAYwBvAG4AZgBvAG4AdABSAGUAZwB1AGwAYQByAHIAbQBlAGwALQBpAGMAbwBuAGYAbwBuAHQAcgBtAGUAbAAtAGkAYwBvAG4AZgBvAG4AdABWAGUAcgBzAGkAbwBuACAAMQAuADAAcgBtAGUAbAAtAGkAYwBvAG4AZgBvAG4AdABHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwADdGFiCGtleWJvYXJkBmRlbGV0ZQpjb2RlLWJsb2NrBGNvZGUKdmlzaWJpbGl0eQp2aWV3LXNwbGl0BGxpbmsEcmVkbwR1bmRvBGJvbGQGaXRhbGljDGxpc3Qtb3JkZXJlZA5saXN0LXVub3JkZXJlZAVxdW90ZQ1zdHJpa2V0aHJvdWdoCXVuZGVybGluZQR3cmFwCWZvbnQtc2l6ZQRncmlkBWltYWdlC2V4cGFuZC1sZXNzC2V4cGFuZC1tb3JlD2Z1bGxzY3JlZW4tZXhpdApmdWxsc2NyZWVuAAAAAAA=);\n    src: url(data:font/ttf;base64,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) format(\"truetype\")\n  }\n\n  .rmel-iconfont {\n    font-family: rmel-iconfont !important;\n    font-size: 16px;\n    font-style: normal;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale\n  }\n\n  .rmel-icon-tab:before {\n    content: \"\\\\e76d\"\n  }\n\n  .rmel-icon-keyboard:before {\n    content: \"\\\\ed80\"\n  }\n\n  .rmel-icon-delete:before {\n    content: \"\\\\ed3c\"\n  }\n\n  .rmel-icon-code-block:before {\n    content: \"\\\\e941\"\n  }\n\n  .rmel-icon-code:before {\n    content: \"\\\\ed3b\"\n  }\n\n  .rmel-icon-visibility:before {\n    content: \"\\\\ed44\"\n  }\n\n  .rmel-icon-view-split:before {\n    content: \"\\\\ed45\"\n  }\n\n  .rmel-icon-link:before {\n    content: \"\\\\ed5f\"\n  }\n\n  .rmel-icon-redo:before {\n    content: \"\\\\ed60\"\n  }\n\n  .rmel-icon-undo:before {\n    content: \"\\\\ed61\"\n  }\n\n  .rmel-icon-bold:before {\n    content: \"\\\\ed6f\"\n  }\n\n  .rmel-icon-italic:before {\n    content: \"\\\\ed70\"\n  }\n\n  .rmel-icon-list-ordered:before {\n    content: \"\\\\ed71\"\n  }\n\n  .rmel-icon-list-unordered:before {\n    content: \"\\\\ed72\"\n  }\n\n  .rmel-icon-quote:before {\n    content: \"\\\\ed73\"\n  }\n\n  .rmel-icon-strikethrough:before {\n    content: \"\\\\ed74\"\n  }\n\n  .rmel-icon-underline:before {\n    content: \"\\\\ed75\"\n  }\n\n  .rmel-icon-wrap:before {\n    content: \"\\\\ed77\"\n  }\n\n  .rmel-icon-font-size:before {\n    content: \"\\\\ed78\"\n  }\n\n  .rmel-icon-grid:before {\n    content: \"\\\\ed8c\"\n  }\n\n  .rmel-icon-image:before {\n    content: \"\\\\ed8d\"\n  }\n\n  .rmel-icon-expand-less:before {\n    content: \"\\\\ed9f\"\n  }\n\n  .rmel-icon-expand-more:before {\n    content: \"\\\\eda0\"\n  }\n\n  .rmel-icon-fullscreen-exit:before {\n    content: \"\\\\eda1\"\n  }\n\n  .rmel-icon-fullscreen:before {\n    content: \"\\\\eda2\"\n  }\n\n  .rc-md-editor {\n    padding-bottom: 1px;\n    position: relative;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box;\n    display: -webkit-box;\n    display: -webkit-flex;\n    display: -ms-flexbox;\n    display: flex;\n    overflow: hidden;\n    -webkit-box-orient: vertical;\n    -webkit-box-direction: normal;\n    -webkit-flex-direction: column;\n    -ms-flex-direction: column;\n    flex-direction: column;\n            border-radius: 6px;\n  }\n\n  .rc-md-editor.full {\n    width: 100%;\n    height: 100% !important;\n    position: fixed;\n    left: 0;\n    top: 0;\n    z-index: 1000\n  }\n\n  .rc-md-editor .editor-container {\n    -webkit-box-flex: 1;\n    -webkit-flex: 1;\n    -ms-flex: 1;\n    flex: 1;\n    display: -webkit-box;\n    display: -webkit-flex;\n    display: -ms-flexbox;\n    display: flex;\n    width: 100%;\n    min-height: 0;\n    position: relative;\n\n  }\n\n  .rc-md-editor .editor-container > .section {\n    -webkit-box-flex: 1;\n    -webkit-flex-grow: 1;\n    -ms-flex-positive: 1;\n    flex-grow: 1;\n    -webkit-flex-shrink: 1;\n    -ms-flex-negative: 1;\n    flex-shrink: 1;\n    -webkit-flex-basis: 1px;\n    -ms-flex-preferred-size: 1px;\n    flex-basis: 1px;\n    padding: 0px 8px;\n            border: none\n  }\n\n  .rc-md-editor .editor-container > .section.in-visible {\n    display: none\n  }\n\n  .rc-md-editor .editor-container > .section > .section-container {\n    padding: 8x 16px 16px\n  }\n\n  .rc-md-editor .editor-container > .section:last-child {\n    border-radius: unset\n  }\n\n  .rc-md-editor .editor-container .sec-md {\n    min-height: 0;\n    min-width: 0;\n    overflow: hidden;\n  }\n\n  .rc-md-editor .editor-container .sec-md .input {\n    background: transparent;\n    font-size: 1rem;\n    display: block;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box;\n    width: 100%;\n    height: 100%;\n    overflow-y: scroll;\n    border: none;\n    resize: none;\n    outline: none;\n    min-height: 0;\n    color: inherit;\n    line-height: 1.7;\n\n  }\n\n  .rc-md-editor .editor-container .sec-html {\n    min-height: 0;\n    min-width: 0;\n\n  }\n\n  .rc-md-editor .editor-container .sec-html .html-wrap {\n    height: 100%;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box;\n    overflow: auto\n  }\n\n  .custom-html-style {\n    color: inherit\n  }\n\n  .custom-html-style h1 {\n    font-size: 32px;\n    padding: 0;\n    border: none;\n    font-weight: 700;\n    margin: 32px 0;\n    line-height: 1.2\n  }\n\n  .custom-html-style h2 {\n    font-size: 24px;\n    padding: 0;\n    border: none;\n    font-weight: 700;\n    margin: 24px 0;\n    line-height: 1.7\n  }\n\n  .custom-html-style h3 {\n    font-size: 18px;\n    margin: 18px 0;\n    padding: 0;\n    line-height: 1.7;\n    border: none\n  }\n\n  .custom-html-style p {\n    font-size: 16px;\n    line-height: 1.7;\n    margin: 8px 0\n  }\n\n  .custom-html-style a {\n  }\n\n  .custom-html-style a:hover {\n    text-decoration: none\n  }\n\n  .custom-html-style strong {\n    font-weight: 700\n  }\n\n  .custom-html-style ol, .custom-html-style ul {\n    font-size: 16px;\n    line-height: 28px;\n    padding-left: 36px\n  }\n\n  .custom-html-style li {\n    margin-bottom: 8px;\n    line-height: 1.7\n  }\n\n  .custom-html-style hr {\n    margin-top: 20px;\n    margin-bottom: 20px;\n    border: 0;\n  }\n\n  .custom-html-style pre {\n    display: block;\n    padding: 20px;\n    line-height: 28px;\n    word-break: break-word\n  }\n\n  .custom-html-style code, .custom-html-style pre {\n    font-size: 16px;\n    border-radius: 0;\n    overflow-x: auto\n  }\n\n  .custom-html-style code {\n    padding: 3px 0;\n    margin: 0;\n    word-break: normal\n  }\n\n  .custom-html-style code:after, .custom-html-style code:before {\n    letter-spacing: 0\n  }\n\n  .custom-html-style blockquote {\n    position: relative;\n    margin: 16px 0;\n    padding: 5px 8px 5px 30px;\n    background: none repeat scroll 0 0 ${\"rgb(39 39 41)\"};\n    color: inherit;\n    border: none;\n    border-left: 10px solid #d6dbdf\n  }\n\n  .custom-html-style img, .custom-html-style video {\n    max-width: 100%\n  }\n\n  .custom-html-style table {\n    font-size: 16px;\n    line-height: 1.7;\n    max-width: 100%;\n    overflow: auto;\n\n    border-collapse: collapse;\n    border-spacing: 0;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box\n  }\n\n  .custom-html-style table td, .custom-html-style table th {\n    word-break: break-all;\n    word-wrap: break-word;\n    white-space: normal\n  }\n\n  .custom-html-style table tr {\n  }\n\n  .custom-html-style table tr:nth-of-type(2n) {\n    background-color: transparent\n  }\n\n  .custom-html-style table th {\n    text-align: center;\n    font-weight: 700;\n\n    padding: 10px 6px;\n    background-color: #f5f7fa;\n    word-break: break-word\n  }\n\n  .custom-html-style table td {\n\n    text-align: left;\n    padding: 10px 15px;\n    word-break: break-word;\n    min-width: 60px\n  }\n\n  .rc-md-editor .drop-wrap {\n    display: block;\n    position: absolute;\n    left: 0;\n    top: 28px;\n    z-index: 2;\n    min-width: 20px;\n    padding: 10px 0;\n    text-align: center;\n    border-style: solid;\n    border-width: 1px\n  }\n\n  .rc-md-editor .drop-wrap.hidden {\n    display: none !important\n  }\n\n  .rc-md-editor .rc-md-navigation {\n    min-height: 38px;\n    padding: 0 8px;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box;\n    font-size: 16px;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    -ms-user-select: none;\n    user-select: none;\n    display: -webkit-box;\n    display: -webkit-flex;\n    display: -ms-flexbox;\n    display: flex;\n    -webkit-box-orient: horizontal;\n    -webkit-box-direction: normal;\n    -webkit-flex-direction: row;\n    -ms-flex-direction: row;\n    flex-direction: row;\n    -webkit-box-pack: justify;\n    -webkit-justify-content: space-between;\n    -ms-flex-pack: justify;\n    justify-content: space-between;\n            color: \"inherit\",\n\n  }\n\n  .rc-md-editor .rc-md-navigation.in-visible {\n    display: none\n  }\n\n  .rc-md-editor .rc-md-navigation .navigation-nav {\n    -webkit-box-align: center;\n    -webkit-align-items: center;\n    -ms-flex-align: center;\n    align-items: center;\n    -webkit-box-pack: center;\n    -webkit-justify-content: center;\n    -ms-flex-pack: center;\n    justify-content: center;\n    font-size: 16px;\n  }\n\n  .rc-md-editor .rc-md-navigation .button-wrap, .rc-md-editor .rc-md-navigation .navigation-nav {\n    display: -webkit-box;\n    display: -webkit-flex;\n    display: -ms-flexbox;\n    display: flex;\n    -webkit-box-orient: horizontal;\n    -webkit-box-direction: normal;\n    -webkit-flex-direction: row;\n    -ms-flex-direction: row;\n    flex-direction: row\n  }\n\n  .rc-md-editor .rc-md-navigation .button-wrap {\n    -webkit-flex-wrap: wrap;\n    -ms-flex-wrap: wrap;\n    flex-wrap: wrap\n  }\n\n  .rc-md-editor .rc-md-navigation .button-wrap .button {\n    position: relative;\n    min-width: 22px;\n    height: 28px;\n    margin-left: 3px;\n    margin-right: -2px;\n    display: inline-block;\n    cursor: pointer;\n    line-height: 28px;\n    text-align: center;\n  }\n\n  .rc-md-editor .rc-md-navigation .button-wrap .button:hover {\n  }\n\n  .rc-md-editor .rc-md-navigation .button-wrap .button.disabled {\n    cursor: not-allowed\n  }\n\n  .rc-md-editor .rc-md-navigation .button-wrap .button:first-of-type {\n    margin-left: 0\n  }\n\n  .rc-md-editor .rc-md-navigation .button-wrap .button:last-child {\n    margin-right: 0\n  }\n\n  .rc-md-editor .rc-md-navigation .button-wrap .rmel-iconfont {\n    font-size: 18px\n  }\n\n  .rc-md-editor .rc-md-navigation li, .rc-md-editor .rc-md-navigation ul {\n    list-style: none;\n    margin: 0;\n    padding: 0\n  }\n\n  .rc-md-editor .rc-md-navigation .h1, .rc-md-editor .rc-md-navigation .h2, .rc-md-editor .rc-md-navigation .h3, .rc-md-editor .rc-md-navigation .h4, .rc-md-editor .rc-md-navigation .h5, .rc-md-editor .rc-md-navigation .h6, .rc-md-editor .rc-md-navigation h1, .rc-md-editor .rc-md-navigation h2, .rc-md-editor .rc-md-navigation h3, .rc-md-editor .rc-md-navigation h4, .rc-md-editor .rc-md-navigation h5, .rc-md-editor .rc-md-navigation h6 {\n    font-family: inherit;\n    font-weight: 500;\n    color: inherit;\n    padding: 0;\n    margin: 0;\n    line-height: 1.1\n  }\n\n  .rc-md-editor .rc-md-navigation h1 {\n    font-size: 34px\n  }\n\n  .rc-md-editor .rc-md-navigation h2 {\n    font-size: 30px\n  }\n\n  .rc-md-editor .rc-md-navigation h3 {\n    font-size: 24px\n  }\n\n  .rc-md-editor .rc-md-navigation h4 {\n    font-size: 18px\n  }\n\n  .rc-md-editor .rc-md-navigation h5 {\n    font-size: 16px\n  }\n\n  .rc-md-editor .rc-md-navigation h6 {\n    font-size: 12px\n  }\n\n  .rc-md-editor .tool-bar {\n    position: absolute;\n    z-index: 1;\n    right: 8px;\n    top: 8px\n  }\n\n  .rc-md-editor .tool-bar .button {\n    min-width: 24px;\n    height: 28px;\n    margin-right: 5px;\n    display: inline-block;\n    cursor: pointer;\n    font-size: 16px;\n    line-height: 28px;\n    text-align: center;\n    color: #999\n  }\n\n  .rc-md-editor .tool-bar .button:hover {\n    color: inherit\n  }\n\n  .rc-md-editor .rc-md-gray-100 {\n    display: block;\n    width: 1px;\n  }\n\n  .rc-md-editor .table-list.wrap {\n    position: relative;\n    margin: 0 10px;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box\n  }\n\n  .rc-md-editor .table-list.wrap .list-item {\n    position: absolute;\n    top: 0;\n    left: 0;\n    display: inline-block;\n    width: 20px;\n    height: 20px;\n    border-radius: 4px\n  }\n\n  .rc-md-editor .table-list.wrap .list-item.active {\n  }\n\n  .rc-md-editor .tab-map-list .list-item {\n    width: 120px;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box\n  }\n\n  .rc-md-editor .tab-map-list .list-item:hover {\n  }\n\n  .rc-md-editor .tab-map-list .list-item.active {\n    font-weight: 700\n  }\n\n  .rc-md-editor .header-list .list-item {\n    width: 100px;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box;\n    padding: 8px 0\n  }\n\n  .rc-md-editor .header-list .list-item:hover {\n  }\n\n`;\n","import React from \"react\";\nimport { FieldProps } from \"../../types\";\nimport { FieldHelperText, LabelWithIcon } from \"../components\";\nimport { PropertyFieldBinding } from \"../PropertyFieldBinding\";\nimport { ExpandablePanel } from \"@firecms/ui\";\nimport { getIconForProperty } from \"../../util\";\nimport { useClearRestoreValue } from \"../useClearRestoreValue\";\n\n/**\n * Array field used for custom\n *\n * This is one of the internal components that get mapped natively inside forms\n * and tables to the specified properties.\n * @group Form fields\n */\nexport function ArrayCustomShapedFieldBinding<T extends Array<any>>({\n                                                                        propertyKey,\n                                                                        value,\n                                                                        error,\n                                                                        showError,\n                                                                        isSubmitting,\n                                                                        setValue,\n                                                                        tableMode,\n                                                                        property,\n                                                                        includeDescription,\n                                                                        underlyingValueHasChanged,\n                                                                        context,\n                                                                        disabled\n                                                                    }: FieldProps<T, any, any>) {\n\n    if (!Array.isArray(property.resolvedProperties))\n        throw Error(\"ArrayCustomShapedFieldBinding misconfiguration. Property `of` not set\");\n\n    const expanded = property.expanded === undefined ? true : property.expanded;\n\n    useClearRestoreValue({\n        property,\n        value,\n        setValue\n    });\n\n    const title = <LabelWithIcon icon={getIconForProperty(property, \"small\")}\n                                 required={property.validation?.required}\n                                 className={\"text-text-secondary dark:text-text-secondary-dark\"}\n                                 title={property.name}/>;\n\n    const body = property.resolvedProperties.map((childProperty, index) => {\n        const fieldProps = {\n            propertyKey: `${propertyKey}[${index}]`,\n            disabled,\n            property: childProperty,\n            includeDescription,\n            underlyingValueHasChanged,\n            context,\n            tableMode: false,\n            partOfArray: true,\n            partOfBlock: false,\n            autoFocus: false\n        };\n        return <div key={`custom_shaped_array_${index}`} className=\"pb-4\">\n            <PropertyFieldBinding {...fieldProps}/>\n        </div>;\n    });\n\n    return (\n\n        <>\n\n            {!tableMode &&\n                <ExpandablePanel initiallyExpanded={expanded}\n                                 title={title}\n                                 className={\"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2\"}>\n                    {body}\n                </ExpandablePanel>}\n\n            {tableMode && body}\n\n            <FieldHelperText includeDescription={includeDescription}\n                             showError={showError}\n                             error={error}\n                             disabled={disabled}\n                             property={property}/>\n\n        </>\n    );\n}\n","import React, { useEffect } from \"react\";\nimport { useFormex } from \"@firecms/formex\";\n\nexport const ErrorFocus = ({ containerRef }:\n                               {\n                                   containerRef?: React.RefObject<HTMLDivElement>\n                               }) => {\n    const { isSubmitting, isValidating, errors } = useFormex();\n\n    useEffect(() => {\n        const keys = Object.keys(errors);\n\n        // Whenever there are errors and the form is submitting but finished validating.\n        if (keys.length > 0 && isSubmitting && !isValidating) {\n            const errorElement = containerRef?.current?.querySelector<HTMLDivElement>(\n                `#form_field_${keys[0]}`\n            );\n\n            if (errorElement && containerRef?.current) {\n                const scrollableParent = getScrollableParent(containerRef.current);\n                if (scrollableParent) {\n                    const top = errorElement.getBoundingClientRect().top;\n                    scrollableParent.scrollTo({\n                        top: scrollableParent.scrollTop + top - 196,\n                        behavior: \"smooth\"\n                    });\n                }\n                const input = errorElement.querySelector(\"input\");\n                if (input) input.focus();\n            }\n        }\n    }, [isSubmitting, isValidating, errors, containerRef]);\n\n    // This component does not render anything by itself.\n    return null;\n};\n\nconst isScrollable = (ele: HTMLElement | null) => {\n    const hasScrollableContent = ele && ele.scrollHeight > ele.clientHeight;\n\n    const overflowYStyle = ele ? window.getComputedStyle(ele).overflowY : null;\n    const isOverflowHidden = overflowYStyle && overflowYStyle.indexOf(\"hidden\") !== -1;\n\n    return hasScrollableContent && !isOverflowHidden;\n};\n\nconst getScrollableParent = (ele: HTMLElement | null): HTMLElement | null => {\n    return (!ele || ele === document.body)\n        ? document.body\n        : (isScrollable(ele) ? ele : getScrollableParent(ele.parentNode as HTMLElement));\n};\n","import React, { useMemo } from \"react\";\n\n// import { ErrorMessage } from \"@firecms/formex\";\nimport { Entity, EntityStatus, EnumValueConfig, EnumValues } from \"../../types\";\n\nimport { useClipboard, useSnackbarController } from \"../../hooks\";\nimport { enumToObjectEntries } from \"../../util\";\nimport {\n    CircularProgress,\n    ContentCopyIcon,\n    IconButton,\n    OpenInNewIcon,\n    Select,\n    SelectItem,\n    TextField,\n    Tooltip,\n    Typography\n} from \"@firecms/ui\";\nimport { EnumValuesChip } from \"../../preview\";\nimport { useCustomizationController } from \"../../hooks/useCustomizationController\";\nimport { CustomizationController } from \"../../types/customization_controller\";\nimport { useFormex } from \"@firecms/formex\";\n\nexport function CustomIdField<M extends Record<string, any>>({\n                                                                 customId,\n                                                                 entityId,\n                                                                 status,\n                                                                 onChange,\n                                                                 error,\n                                                                 entity,\n                                                                 loading\n                                                             }: {\n    customId?: boolean | EnumValues | \"optional\"\n    entityId?: string\n    status: EntityStatus,\n    onChange: (id?: string) => void,\n    error: boolean,\n    entity: Entity<M> | undefined,\n    loading: boolean\n}) {\n\n    const { errors } = useFormex();\n    const disabled = status === \"existing\" || !customId;\n    const idSetAutomatically = status !== \"existing\" && !customId;\n\n    const enumValues: EnumValueConfig[] | undefined = useMemo(() => {\n        if (!customId || typeof customId === \"boolean\" || customId === \"optional\")\n            return undefined;\n        return enumToObjectEntries(customId);\n    }, [customId]);\n\n    const snackbarController = useSnackbarController();\n    const { copy } = useClipboard({\n        onSuccess: (text) => snackbarController.open({\n            type: \"success\",\n            message: `Copied ${text}`\n        })\n    });\n\n    const customizationController: CustomizationController = useCustomizationController();\n\n    const fieldProps = {\n        label: idSetAutomatically ? \"ID is set automatically\" : \"ID\",\n        disabled: disabled || loading,\n        name: \"id\",\n        value: (entity && status === \"existing\" ? entity.id : entityId) ?? \"\",\n        endAdornment: loading ? <CircularProgress size={\"small\"}/> : (entity\n                ? (\n                    <>\n\n                        <Tooltip title={\"Copy\"}>\n                            <IconButton onClick={(e) => copy(entity.id)}\n                                        aria-label=\"copy-id\">\n                                <ContentCopyIcon size={\"small\"}/>\n                            </IconButton>\n                        </Tooltip>\n\n                        {customizationController?.entityLinkBuilder &&\n                            <Tooltip title={\"Open in the console\"}>\n                                <IconButton component={\"a\"}\n                                            href={customizationController.entityLinkBuilder({ entity })}\n                                            rel=\"noopener noreferrer\"\n                                            target=\"_blank\"\n                                            onClick={(e) => e.stopPropagation()}\n                                            aria-label=\"go-to-datasource\">\n                                    <OpenInNewIcon size={\"small\"}/>\n                                </IconButton>\n                            </Tooltip>}\n\n                    </>\n                )\n                : undefined\n        )\n    };\n\n    return (\n        <>\n\n            {enumValues &&\n                <Select\n                    error={error}\n                    onValueChange={(v) => onChange(v as string)}\n                    {...fieldProps}\n                    renderValue={(option) => {\n                        const enumConfig = enumValues.find(e => e.id === option);\n                        if (!enumConfig) return option;\n                        return `${enumConfig.id} - ${enumConfig.label}`;\n                    }}\n                >\n                    {enumValues.map((enumConfig) => (\n                        <SelectItem\n                            key={enumConfig.id}\n                            value={String(enumConfig.id)}>\n                            <EnumValuesChip\n                                enumKey={enumConfig.id}\n                                enumValues={enumValues}\n                                size={\"medium\"}/>\n                        </SelectItem>)\n                    )}\n                </Select>}\n\n            {!enumValues &&\n                <TextField {...fieldProps}\n                           error={error}\n                           placeholder={customId === \"optional\" ? \"Autogenerated ID, it can be manually changed\" : (status === \"new\" || status === \"copy\" ? \"ID of the new document\" : \"ID of the document\")}\n                           onChange={(event) => {\n                               let value = event.target.value;\n                               if (value) value = value.trim();\n                               return onChange(value.length ? value : undefined);\n                           }}/>}\n\n            {errors.id && <Typography variant={\"caption\"}\n                                      className={\"ml-3.5 text-red-500 dark:text-red-500\"}>\n                {errors.id}\n            </Typography>}\n\n        </>\n    );\n}\n","import { ContentCopyIcon, IconButton, Typography } from \"@firecms/ui\";\nimport { useCallback, useState } from \"react\";\n\nexport function PropertyIdCopyTooltipContent({ propertyId }: { propertyId: string }) {\n\n    const [copied, setCopied] = useState(false);\n\n    return (\n        <div className={\"flex flex-row gap-2 items-center justify-center text-white\"}>\n            <div>\n                <Typography variant={\"caption\"} className={\"min-w-20 text-slate-400\"}\n                            color={\"disabled\"}>{copied ? \"Copied\" : \"Property ID\"}</Typography>\n                <Typography variant={\"caption\"} className={\"text-white\"}><code>{propertyId}</code></Typography>\n            </div>\n            <IconButton size={\"small\"}>\n                <ContentCopyIcon size={\"smallest\"}\n                                  className={\"text-white\"}\n                                  onClick={useCallback(() => {\n                                      navigator.clipboard.writeText(propertyId);\n                                      setCopied(true);\n                                      setTimeout(() => setCopied(false), 2000);\n                                  }, [propertyId])}\n                />\n            </IconButton>\n        </div>\n    );\n}\n","import React, { MutableRefObject, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport {\n    CMSAnalyticsEvent,\n    Entity,\n    EntityAction,\n    EntityCollection,\n    EntityStatus,\n    EntityValues,\n    FormContext,\n    PluginFormActionProps,\n    PropertyFieldBindingProps,\n    ResolvedEntityCollection\n} from \"../types\";\nimport { Formex, FormexController, getIn, setIn, useCreateFormex } from \"@firecms/formex\";\nimport { PropertyFieldBinding } from \"./PropertyFieldBinding\";\nimport { CustomFieldValidator, getYupEntitySchema } from \"./validation\";\nimport equal from \"react-fast-compare\"\nimport {\n    canCreateEntity,\n    canDeleteEntity,\n    getDefaultValuesFor,\n    getEntityTitlePropertyKey,\n    getValueInPath,\n    isHidden,\n    isReadOnly,\n    resolveCollection\n} from \"../util\";\nimport {\n    useAuthController,\n    useCustomizationController,\n    useDataSource,\n    useFireCMSContext,\n    useSideEntityController\n} from \"../hooks\";\nimport { ErrorFocus } from \"./components/ErrorFocus\";\nimport { CustomIdField } from \"./components/CustomIdField\";\nimport { Alert, Button, cn, DialogActions, IconButton, Tooltip, Typography } from \"@firecms/ui\";\nimport { ErrorBoundary } from \"../components\";\nimport {\n    copyEntityAction,\n    deleteEntityAction\n} from \"../components/common/default_entity_actions\";\nimport { useAnalyticsController } from \"../hooks/useAnalyticsController\";\nimport { ValidationError } from \"yup\";\nimport { PropertyIdCopyTooltipContent } from \"../components/PropertyIdCopyTooltipContent\";\n\n/**\n * @group Components\n */\nexport interface EntityFormProps<M extends Record<string, any>> {\n\n    /**\n     * New or existing status\n     */\n    status: EntityStatus;\n\n    /**\n     * Path of the collection this entity is located\n     */\n    path: string;\n\n    /**\n     * The collection is used to build the fields of the form\n     */\n    collection: EntityCollection<M>\n\n    /**\n     * The updated entity is passed from the parent component when the underlying data\n     * has changed in the datasource\n     */\n    entity?: Entity<M>;\n\n    /**\n     * The callback function called when Save is clicked and validation is correct\n     */\n    onEntitySaveRequested: (\n        props: EntityFormSaveParams<M>\n    ) => Promise<void>;\n\n    /**\n     * The callback function called when discard is clicked\n     */\n    onDiscard?: () => void;\n\n    /**\n     * The callback function when the form is dirty, so the values are different\n     * from the original ones\n     */\n    onModified?: (dirty: boolean) => void;\n\n    /**\n     * The callback function when the form original values have been modified\n     */\n    onValuesChanged?: (values?: EntityValues<M>) => void;\n\n    /**\n     *\n     * @param id\n     */\n    onIdChange?: (id: string) => void;\n\n    currentEntityId?: string;\n\n    onFormContextChange?: (formContext: FormContext<M>) => void;\n\n    hideId?: boolean;\n\n    autoSave?: boolean;\n\n    onIdUpdateError?: (error: any) => void;\n\n}\n\nexport type EntityFormSaveParams<M extends Record<string, any>> = {\n    collection: ResolvedEntityCollection<M>,\n    path: string,\n    entityId: string | undefined,\n    values: EntityValues<M>,\n    previousValues?: EntityValues<M>,\n    closeAfterSave: boolean,\n    autoSave: boolean\n};\n\n/**\n * This is the form used internally by the CMS\n * @param status\n * @param path\n * @param collection\n * @param entity\n * @param onEntitySave\n * @param onDiscard\n * @param onModified\n * @param onValuesChanged\n * @constructor\n * @group Components\n */\nexport const EntityForm = EntityFormInternal;\n// export const EntityForm = React.memo<EntityFormProps<any>>(EntityFormInternal,\n//     (a: EntityFormProps<any>, b: EntityFormProps<any>) => {\n//         return a.status === b.status &&\n//             a.path === b.path &&\n//             equal(a.entity?.values, b.entity?.values);\n//     }) as typeof EntityFormInternal;\n\nfunction getDataSourceEntityValues<M extends object>(initialResolvedCollection: ResolvedEntityCollection,\n                                                     status: \"new\" | \"existing\" | \"copy\",\n                                                     entity: Entity<M> | undefined): Partial<EntityValues<M>> {\n    const properties = initialResolvedCollection.properties;\n    if ((status === \"existing\" || status === \"copy\") && entity) {\n        return entity.values ?? getDefaultValuesFor(properties);\n    } else if (status === \"new\") {\n        return getDefaultValuesFor(properties);\n    } else {\n        console.error({\n            status,\n            entity\n        });\n        throw new Error(\"Form has not been initialised with the correct parameters\");\n    }\n}\n\nfunction EntityFormInternal<M extends Record<string, any>>({\n                                                               status,\n                                                               path,\n                                                               collection: inputCollection,\n                                                               entity,\n                                                               onEntitySaveRequested,\n                                                               onDiscard,\n                                                               onModified,\n                                                               onValuesChanged,\n                                                               onIdChange,\n                                                               onFormContextChange,\n                                                               hideId,\n                                                               autoSave,\n                                                               onIdUpdateError,\n                                                           }: EntityFormProps<M>) {\n\n    const analyticsController = useAnalyticsController();\n\n    const customizationController = useCustomizationController();\n\n    const context = useFireCMSContext();\n    const dataSource = useDataSource(inputCollection);\n    const plugins = customizationController.plugins;\n\n    const initialResolvedCollection = useMemo(() => resolveCollection({\n        collection: inputCollection,\n        path,\n        values: entity?.values,\n        fields: customizationController.propertyConfigs\n    }), [entity?.values, path, customizationController.propertyConfigs]);\n\n    const mustSetCustomId: boolean = (status === \"new\" || status === \"copy\") &&\n        (Boolean(initialResolvedCollection.customId) && initialResolvedCollection.customId !== \"optional\");\n\n    const initialEntityId = useMemo(() => {\n        if (status === \"new\" || status === \"copy\") {\n            if (mustSetCustomId) {\n                return undefined;\n            } else {\n                return dataSource.generateEntityId(path);\n            }\n        } else {\n            return entity?.id;\n        }\n    }, []);\n\n    const closeAfterSaveRef = useRef(false);\n\n    const baseDataSourceValuesRef = useRef<Partial<EntityValues<M>>>(getDataSourceEntityValues(initialResolvedCollection, status, entity));\n\n    const [entityId, setEntityId] = React.useState<string | undefined>(initialEntityId);\n    const [entityIdError, setEntityIdError] = React.useState<boolean>(false);\n    const [savingError, setSavingError] = React.useState<Error | undefined>();\n\n    const [customIdLoading, setCustomIdLoading] = React.useState<boolean>(false);\n\n    // const initialValuesRef = useRef<EntityValues<M>>(entity?.values ?? baseDataSourceValues as EntityValues<M>);\n    const [internalValues, setInternalValues] = useState<EntityValues<M> | undefined>(entity?.values ?? baseDataSourceValuesRef.current as EntityValues<M>);\n\n    const save = (values: EntityValues<M>): Promise<void> => {\n        return onEntitySaveRequested({\n            collection: resolvedCollection,\n            path,\n            entityId,\n            values,\n            previousValues: entity?.values,\n            closeAfterSave: closeAfterSaveRef.current,\n            autoSave: autoSave ?? false\n        }).then(_ => {\n            const eventName: CMSAnalyticsEvent = status === \"new\"\n                ? \"new_entity_saved\"\n                : (status === \"copy\" ? \"entity_copied\" : (status === \"existing\" ? \"entity_edited\" : \"unmapped_event\"));\n            analyticsController.onAnalyticsEvent?.(eventName, { path });\n        }).catch(e => {\n            console.error(e);\n            setSavingError(e);\n        }).finally(() => {\n            closeAfterSaveRef.current = false;\n        });\n    };\n\n    const onSubmit = (values: EntityValues<M>, formexController: FormexController<EntityValues<M>>) => {\n\n        if (mustSetCustomId && !entityId) {\n            console.error(\"Missing custom Id\");\n            setEntityIdError(true);\n            formexController.setSubmitting(false);\n            return;\n        }\n\n        setSavingError(undefined);\n        setEntityIdError(false);\n\n        if (status === \"existing\") {\n            if (!entity?.id) throw Error(\"Form misconfiguration when saving, no id for existing entity\");\n        } else if (status === \"new\" || status === \"copy\") {\n            if (inputCollection.customId) {\n                if (inputCollection.customId !== \"optional\" && !entityId) {\n                    throw Error(\"Form misconfiguration when saving, entityId should be set\");\n                }\n            }\n        } else {\n            throw Error(\"New FormType added, check EntityForm\");\n        }\n\n        return save(values)\n            ?.then(_ => {\n                formexController.resetForm({\n                    values,\n                    submitCount: 0,\n                    touched: {}\n                });\n            })\n            .finally(() => {\n                formexController.setSubmitting(false);\n            });\n\n    };\n\n    const formex: FormexController<M> = useCreateFormex<M>({\n        initialValues: baseDataSourceValuesRef.current as M,\n        onSubmit,\n        validation: (values) => {\n            return validationSchema?.validate(values, { abortEarly: false })\n                .then(() => {\n                    return {};\n                })\n                .catch((e) => {\n\n                    const errors: Record<string, string> = {};\n                    e.inner.forEach((error: any) => {\n                        errors[error.path] = error.message;\n                    });\n                    return yupToFormErrors(e);\n                });\n        }\n    });\n\n    useEffect(() => {\n        baseDataSourceValuesRef.current = getDataSourceEntityValues(initialResolvedCollection, status, entity);\n        const initialValues = formex.initialValues;\n        if (!formex.isSubmitting && initialValues && status === \"existing\") {\n            setUnderlyingChanges(\n                Object.entries(resolvedCollection.properties)\n                    .map(([key, property]) => {\n                        if (isHidden(property)) {\n                            return {};\n                        }\n                        const initialValue = initialValues[key];\n                        const latestValue = baseDataSourceValuesRef.current[key];\n                        if (!equal(initialValue, latestValue)) {\n                            return { [key]: latestValue };\n                        }\n                        return {};\n                    })\n                    .reduce((a, b) => ({ ...a, ...b }), {}) as Partial<EntityValues<M>>\n            );\n        } else {\n            setUnderlyingChanges({});\n        }\n    }, [entity, initialResolvedCollection, status]);\n\n    const doOnValuesChanges = (values?: EntityValues<M>) => {\n        const initialValues = formex.initialValues;\n        setInternalValues(values);\n        if (onValuesChanged)\n            onValuesChanged(values);\n        if (autoSave && values && !equal(values, initialValues)) {\n            save(values);\n        }\n    };\n\n    useEffect(() => {\n        if (entityId && onIdChange)\n            onIdChange(entityId);\n    }, [entityId, onIdChange]);\n\n    const resolvedCollection = resolveCollection<M>({\n        collection: inputCollection,\n        path,\n        entityId,\n        values: internalValues,\n        previousValues: formex.initialValues,\n        fields: customizationController.propertyConfigs\n    });\n\n    const titlePropertyKey = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);\n    const title = internalValues && titlePropertyKey ? getValueInPath(internalValues, titlePropertyKey) : undefined;\n\n    const onIdUpdate = inputCollection.callbacks?.onIdUpdate;\n\n    const doOnIdUpdate = useCallback(async () => {\n        if (onIdUpdate && internalValues && (status === \"new\" || status === \"copy\")) {\n            setCustomIdLoading(true);\n            try {\n                const updatedId = await onIdUpdate({\n                    collection: resolvedCollection,\n                    path,\n                    entityId,\n                    values: internalValues,\n                    context\n                });\n                setEntityId(updatedId);\n            } catch (e) {\n                onIdUpdateError && onIdUpdateError(e);\n                console.error(e);\n            }\n            setCustomIdLoading(false);\n        }\n    }, [entityId, internalValues, status]);\n\n    useEffect(() => {\n        doOnIdUpdate();\n    }, [doOnIdUpdate]);\n\n    const [underlyingChanges, setUnderlyingChanges] = useState<Partial<EntityValues<M>>>({});\n\n    const uniqueFieldValidator: CustomFieldValidator = useCallback(({\n                                                                        name,\n                                                                        value,\n                                                                        property\n                                                                    }) => dataSource.checkUniqueField(path, name, value, entityId),\n        [dataSource, path, entityId]);\n\n    const validationSchema = useMemo(() => entityId\n            ? getYupEntitySchema(\n                entityId,\n                resolvedCollection.properties,\n                uniqueFieldValidator)\n            : undefined,\n        [entityId, resolvedCollection.properties, uniqueFieldValidator]);\n\n    const authController = useAuthController();\n\n    const getActionsForEntity = useCallback(({\n                                                 entity,\n                                                 customEntityActions\n                                             }: {\n        entity?: Entity<M>,\n        customEntityActions?: EntityAction[]\n    }): EntityAction[] => {\n        const createEnabled = canCreateEntity(inputCollection, authController, path, null);\n        const deleteEnabled = entity ? canDeleteEntity(inputCollection, authController, path, entity) : true;\n        const actions: EntityAction[] = [];\n        if (createEnabled)\n            actions.push(copyEntityAction);\n        if (deleteEnabled)\n            actions.push(deleteEntityAction);\n        if (customEntityActions)\n            actions.push(...customEntityActions);\n        return actions;\n    }, [authController, inputCollection, path]);\n\n    const pluginActions: React.ReactNode[] = [];\n\n    const formContext: FormContext<M> = {\n        // @ts-ignore\n        setFieldValue: useCallback(formex.setFieldValue, []),\n        values: formex.values,\n        collection: resolvedCollection,\n        entityId,\n        path,\n        save\n    };\n\n    const submittedFormContext = useRef<FormContext<M> | null>(null);\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useEffect(() => {\n        if (onFormContextChange && !formContextsEqual(submittedFormContext.current ?? undefined, formContext)) {\n            onFormContextChange(formContext);\n            submittedFormContext.current = formContext;\n        }\n    }, [formContext, onFormContextChange]);\n\n    if (plugins && inputCollection) {\n        const actionProps: PluginFormActionProps = {\n            entityId,\n            path,\n            status,\n            collection: inputCollection,\n            context,\n            currentEntityId: entityId,\n            formContext\n        };\n        pluginActions.push(...plugins.map((plugin, i) => (\n            plugin.form?.Actions\n                ? <plugin.form.Actions\n                    key={`actions_${plugin.key}`} {...actionProps}/>\n                : null\n        )).filter(Boolean));\n    }\n\n    return <Formex value={formex}>\n        <div className=\"h-full overflow-auto\">\n\n            {pluginActions.length > 0 && <div\n                className={cn(\"w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-slate-200 dark:bg-opacity-60 dark:bg-slate-800 backdrop-blur-md\")}>\n                {pluginActions}\n            </div>}\n\n            <div className=\"pt-12 pb-16 pl-8 pr-8 md:pl-10 md:pr-10\">\n                <div\n                    className={`w-full py-2 flex flex-col items-start mt-${4 + (pluginActions ? 8 : 0)} lg:mt-${8 + (pluginActions ? 8 : 0)} mb-8`}>\n\n                    <Typography\n                        className={\"mt-4 flex-grow line-clamp-1 \" + inputCollection.hideIdFromForm ? \"mb-2\" : \"mb-0\"}\n                        variant={\"h4\"}>{title ?? inputCollection.singularName ?? inputCollection.name}\n                    </Typography>\n                    <Alert color={\"base\"} className={\"w-full\"} size={\"small\"}>\n                        <code className={\"text-xs select-all\"}>{path}/{entityId}</code>\n                    </Alert>\n                </div>\n\n                {!hideId &&\n                    <CustomIdField customId={inputCollection.customId}\n                                   entityId={entityId}\n                                   status={status}\n                                   onChange={setEntityId}\n                                   error={entityIdError}\n                                   loading={customIdLoading}\n                                   entity={entity}/>}\n\n                {entityId && <InnerForm\n                    {...formex}\n                    initialValues={formex.initialValues}\n                    onModified={onModified}\n                    onDiscard={onDiscard}\n                    onValuesChanged={doOnValuesChanges}\n                    underlyingChanges={underlyingChanges}\n                    entity={entity}\n                    resolvedCollection={resolvedCollection}\n                    formContext={formContext}\n                    status={status}\n                    savingError={savingError}\n                    closeAfterSaveRef={closeAfterSaveRef}\n                    autoSave={autoSave}\n                    entityActions={getActionsForEntity({\n                        entity,\n                        customEntityActions: inputCollection.entityActions\n                    })}/>}\n\n            </div>\n        </div>\n    </Formex>\n}\n\nfunction InnerForm<M extends Record<string, any>>(props: FormexController<M> & {\n    initialValues: EntityValues<M>,\n    onModified: ((modified: boolean) => void) | undefined,\n    onValuesChanged?: (changedValues?: EntityValues<M>) => void,\n    underlyingChanges: Partial<M>,\n    entity: Entity<M> | undefined,\n    resolvedCollection: ResolvedEntityCollection<M>,\n    formContext: FormContext<M>,\n    onDiscard?: () => void,\n    status: \"new\" | \"existing\" | \"copy\",\n    savingError?: Error,\n    closeAfterSaveRef: MutableRefObject<boolean>,\n    autoSave?: boolean,\n    entityActions: EntityAction[],\n}) {\n\n    const {\n        values,\n        onDiscard,\n        onModified,\n        onValuesChanged,\n        underlyingChanges,\n        formContext,\n        entity,\n        touched,\n        setFieldValue,\n        resolvedCollection,\n        isSubmitting,\n        status,\n        handleSubmit,\n        resetForm,\n        savingError,\n        dirty,\n        closeAfterSaveRef,\n        autoSave,\n        entityActions,\n    } = props;\n\n    const context = useFireCMSContext();\n    const formActions = entityActions.filter(a => a.includeInForm === undefined || a.includeInForm);\n    const sideEntityController = useSideEntityController();\n\n    const modified = dirty;\n    useEffect(() => {\n        if (onModified)\n            onModified(modified);\n        if (onValuesChanged)\n            onValuesChanged(values);\n    }, [modified, values]);\n\n    useEffect(() => {\n        if (!autoSave && !isSubmitting && underlyingChanges && entity) {\n            // we update the form fields from the Firestore data\n            // if they were not touched\n            Object.entries(underlyingChanges).forEach(([key, value]) => {\n                const formValue = values[key];\n                if (!equal(value, formValue) && !touched[key]) {\n                    console.debug(\"Updated value from the datasource:\", key, value);\n                    setFieldValue(key, value !== undefined ? value : null);\n                }\n            });\n        }\n    }, [isSubmitting, autoSave, underlyingChanges, entity, values, touched, setFieldValue]);\n\n    const formFields = (\n        <div className={\"flex flex-col gap-8\"}>\n            {(resolvedCollection.propertiesOrder ?? Object.keys(resolvedCollection.properties))\n                .map((key) => {\n\n                    const property = resolvedCollection.properties[key];\n                    if (!property) {\n                        console.warn(`Property ${key} not found in collection ${resolvedCollection.name}`);\n                        return null;\n                    }\n\n                    const underlyingValueHasChanged: boolean =\n                        !!underlyingChanges &&\n                        Object.keys(underlyingChanges).includes(key) &&\n                        !!touched[key];\n\n                    const disabled = (!autoSave && isSubmitting) || isReadOnly(property) || Boolean(property.disabled);\n                    const hidden = isHidden(property);\n                    if (hidden) return null;\n                    const cmsFormFieldProps: PropertyFieldBindingProps<any, M> = {\n                        propertyKey: key,\n                        disabled,\n                        property,\n                        includeDescription: property.description || property.longDescription,\n                        underlyingValueHasChanged: underlyingValueHasChanged && !autoSave,\n                        context: formContext,\n                        tableMode: false,\n                        partOfArray: false,\n                        partOfBlock: false,\n                        autoFocus: false\n                    };\n\n                    return (\n                        <div id={`form_field_${key}`}\n                             key={`field_${resolvedCollection.name}_${key}`}>\n                            <ErrorBoundary>\n                                <Tooltip title={<PropertyIdCopyTooltipContent propertyId={key}/>}\n                                         delayDuration={800}\n                                         side={\"left\"}\n                                         align={\"start\"}\n                                         sideOffset={16}>\n                                    <PropertyFieldBinding {...cmsFormFieldProps}/>\n                                </Tooltip>\n                            </ErrorBoundary>\n                        </div>\n                    );\n                })\n                .filter(Boolean)}\n\n        </div>\n    );\n\n    const disabled = isSubmitting || (!modified && status === \"existing\");\n    const formRef = React.useRef<HTMLDivElement>(null);\n\n    return (\n\n        <form onSubmit={handleSubmit}\n              onReset={() => {\n                  console.debug(\"Resetting form\")\n                  resetForm();\n                  return onDiscard && onDiscard();\n              }}\n              noValidate>\n            <div className=\"mt-12\"\n                 ref={formRef}>\n\n                {formFields}\n\n                <ErrorFocus containerRef={formRef}/>\n\n            </div>\n\n            <div className=\"h-14\"/>\n\n            {!autoSave && <DialogActions position={\"absolute\"}>\n\n                {savingError &&\n                    <div className=\"text-right\">\n                        <Typography color={\"error\"}>\n                            {savingError.message}\n                        </Typography>\n                    </div>}\n\n                {entity && formActions.length > 0 && <div className=\"flex-grow flex overflow-auto no-scrollbar\">\n                    {formActions.map(action => (\n                        <IconButton\n                            key={action.name}\n                            color=\"primary\"\n                            onClick={(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n                                event.stopPropagation();\n                                if (entity)\n                                    action.onClick({\n                                        entity,\n                                        fullPath: resolvedCollection.path,\n                                        collection: resolvedCollection,\n                                        context,\n                                        sideEntityController,\n                                    });\n                            }}>\n                            {action.icon}\n                        </IconButton>\n                    ))}\n                </div>}\n\n                <Button\n                    variant=\"text\"\n                    disabled={disabled}\n                    type=\"reset\"\n                >\n                    {status === \"existing\" ? \"Discard\" : \"Clear\"}\n                </Button>\n\n                <Button\n                    variant=\"text\"\n                    color=\"primary\"\n                    type=\"submit\"\n                    disabled={disabled}\n                    onClick={() => {\n                        closeAfterSaveRef.current = false;\n                    }}\n                >\n                    {status === \"existing\" && \"Save\"}\n                    {status === \"copy\" && \"Create copy\"}\n                    {status === \"new\" && \"Create\"}\n                </Button>\n\n                <Button\n                    variant=\"filled\"\n                    color=\"primary\"\n                    type=\"submit\"\n                    disabled={disabled}\n                    onClick={() => {\n                        closeAfterSaveRef.current = true;\n                    }}\n                >\n                    {status === \"existing\" && \"Save and close\"}\n                    {status === \"copy\" && \"Create copy and close\"}\n                    {status === \"new\" && \"Create and close\"}\n                </Button>\n\n            </DialogActions>}\n        </form>\n    );\n}\n\nexport function yupToFormErrors(yupError: ValidationError): Record<string, any> {\n    let errors: Record<string, any> = {};\n    if (yupError.inner) {\n        if (yupError.inner.length === 0) {\n            return setIn(errors, yupError.path!, yupError.message);\n        }\n        for (const err of yupError.inner) {\n            if (!getIn(errors, err.path!)) {\n                errors = setIn(errors, err.path!, err.message);\n            }\n        }\n    }\n    return errors;\n}\n\nfunction formContextsEqual(a: FormContext<any> | undefined, b: FormContext<any> | undefined): boolean {\n    return a?.path === b?.path &&\n        a?.entityId === b?.entityId &&\n        equal(a?.values, b?.values) &&\n        equal(a?.collection, b?.collection);\n}\n","import React from \"react\";\n\nimport { ArrayProperty, FieldProps, Property, PropertyConfig, ResolvedProperty } from \"../types\";\nimport {\n    ArrayCustomShapedFieldBinding,\n    ArrayOfReferencesFieldBinding,\n    BlockFieldBinding,\n    DateTimeFieldBinding,\n    KeyValueFieldBinding,\n    MapFieldBinding,\n    MarkdownFieldBinding,\n    MultiSelectBinding,\n    ReferenceFieldBinding,\n    RepeatFieldBinding,\n    SelectFieldBinding,\n    StorageUploadFieldBinding,\n    SwitchFieldBinding,\n    TextFieldBinding\n} from \"../form\";\nimport { isPropertyBuilder, mergeDeep } from \"../util\";\n\nimport {\n    AddLinkIcon,\n    BallotIcon,\n    DriveFolderUploadIcon,\n    EmailIcon,\n    FlagIcon,\n    FormatListNumberedIcon,\n    FormatQuoteIcon,\n    HttpIcon,\n    LinkIcon,\n    ListAltIcon,\n    ListIcon,\n    NumbersIcon,\n    RepeatIcon,\n    ScheduleIcon,\n    ShortTextIcon,\n    SubjectIcon,\n    UploadFileIcon,\n    ViewStreamIcon\n} from \"@firecms/ui\";\n\nexport function isDefaultFieldConfigId(id: string) {\n    return Object.keys(DEFAULT_FIELD_CONFIGS).includes(id);\n}\n\nexport const DEFAULT_FIELD_CONFIGS: Record<string, PropertyConfig<any>> = {\n    text_field: {\n        key: \"text_field\",\n        name: \"Text field\",\n        description: \"Simple short text\",\n        Icon: ShortTextIcon,\n        color: \"#2d7ff9\",\n        property: {\n            dataType: \"string\",\n            Field: TextFieldBinding\n        }\n    },\n    multiline: {\n        key: \"multiline\",\n        name: \"Multiline\",\n        description: \"Text with multiple lines\",\n        Icon: SubjectIcon,\n        color: \"#2d7ff9\",\n        property: {\n            dataType: \"string\",\n            multiline: true,\n            Field: TextFieldBinding\n        }\n    },\n    markdown: {\n        key: \"markdown\",\n        name: \"Markdown\",\n        description: \"Text with advanced markdown syntax\",\n        Icon: FormatQuoteIcon,\n        color: \"#2d7ff9\",\n        property: {\n            dataType: \"string\",\n            markdown: true,\n            Field: MarkdownFieldBinding\n        }\n    },\n    url: {\n        key: \"url\",\n        name: \"Url\",\n        description: \"Text with URL validation\",\n        Icon: HttpIcon,\n        color: \"#154fb3\",\n        property: {\n            dataType: \"string\",\n            url: true,\n            Field: TextFieldBinding\n        }\n    },\n    email: {\n        key: \"email\",\n        name: \"Email\",\n        description: \"Text with email validation\",\n        Icon: EmailIcon,\n        color: \"#154fb3\",\n        property: {\n            dataType: \"string\",\n            email: true,\n            Field: TextFieldBinding\n        }\n    },\n    switch: {\n        key: \"switch\",\n        name: \"Switch\",\n        description: \"Boolean true or false field (or yes or no, 0 or 1...)\",\n        Icon: FlagIcon,\n        color: \"#20d9d2\",\n        property: {\n            dataType: \"boolean\",\n            Field: SwitchFieldBinding\n        }\n    },\n    select: {\n        key: \"select\",\n        name: \"Select/enum\",\n        description: \"Select one text value from within an enumeration\",\n        Icon: ListIcon,\n        color: \"#4223c9\",\n        property: {\n            dataType: \"string\",\n            enumValues: [],\n            Field: SelectFieldBinding\n        }\n    },\n    multi_select: {\n        key: \"multi_select\",\n        name: \"Multi select\",\n        description: \"Select multiple text values from within an enumeration\",\n        Icon: ListAltIcon,\n        color: \"#4223c9\",\n        property: {\n            dataType: \"array\",\n            of: {\n                dataType: \"string\",\n                enumValues: [],\n            },\n            Field: MultiSelectBinding\n        }\n    },\n    number_input: {\n        key: \"number_input\",\n        name: \"Number input\",\n        description: \"Simple number field with validation\",\n        Icon: NumbersIcon,\n        color: \"#bec920\",\n        property: {\n            dataType: \"number\",\n            Field: TextFieldBinding\n        }\n    },\n    number_select: {\n        key: \"number_select\",\n        name: \"Number select\",\n        description: \"Select a number value from within an enumeration\",\n        Icon: FormatListNumberedIcon,\n        color: \"#bec920\",\n        property: {\n            dataType: \"number\",\n            enumValues: [],\n            Field: SelectFieldBinding\n        }\n    },\n    multi_number_select: {\n        key: \"multi_number_select\",\n        name: \"Multiple number select\",\n        description: \"Select multiple number values from within an enumeration\",\n        Icon: FormatListNumberedIcon,\n        color: \"#bec920\",\n        property: {\n            dataType: \"array\",\n            of: {\n                dataType: \"number\",\n                enumValues: [],\n            },\n            Field: MultiSelectBinding\n        }\n    },\n    file_upload: {\n        key: \"file_upload\",\n        name: \"File upload\",\n        description: \"Input for uploading single files\",\n        Icon: UploadFileIcon,\n        color: \"#f92d9a\",\n        property: {\n            dataType: \"string\",\n            storage: {\n                storagePath: \"{path}\"\n            },\n            Field: StorageUploadFieldBinding as React.ComponentType<FieldProps<string>>\n        }\n    },\n    multi_file_upload: {\n        key: \"multi_file_upload\",\n        name: \"Multiple file upload\",\n        description: \"Input for uploading multiple files\",\n        Icon: DriveFolderUploadIcon,\n        color: \"#f92d9a\",\n        property: {\n            dataType: \"array\",\n            of: {\n                dataType: \"string\",\n                storage: {\n                    storagePath: \"{path}\"\n                }\n            },\n            Field: StorageUploadFieldBinding\n        }\n    },\n    reference: {\n        key: \"reference\",\n        name: \"Reference\",\n        description: \"The value refers to a different collection\",\n        Icon: LinkIcon,\n        color: \"#ff0042\",\n        property: {\n            dataType: \"reference\",\n            Field: ReferenceFieldBinding\n        }\n    },\n    multi_references: {\n        key: \"multi_references\",\n        name: \"Multiple references\",\n        description: \"Multiple values that refer to a different collection\",\n        Icon: AddLinkIcon,\n        color: \"#ff0042\",\n        property: {\n            dataType: \"array\",\n            of: {\n                dataType: \"reference\",\n            },\n            Field: ArrayOfReferencesFieldBinding\n        }\n    },\n    date_time: {\n        key: \"date_time\",\n        name: \"Date/time\",\n        description: \"A date time select field\",\n        Icon: ScheduleIcon,\n        color: \"#8b46ff\",\n        property: {\n            dataType: \"date\",\n            Field: DateTimeFieldBinding\n        }\n    },\n    group: {\n        key: \"group\",\n        name: \"Group\",\n        description: \"Group of multiple fields\",\n        Icon: BallotIcon,\n        color: \"#ff9408\",\n        property: {\n            dataType: \"map\",\n            properties: {},\n            Field: MapFieldBinding\n        }\n    },\n    key_value: {\n        key: \"key_value\",\n        name: \"Key-value\",\n        description: \"Flexible field that allows the user to add multiple key-value pairs\",\n        Icon: BallotIcon,\n        color: \"#ff9408\",\n        property: {\n            dataType: \"map\",\n            keyValue: true,\n            Field: KeyValueFieldBinding\n        }\n    },\n    repeat: {\n        key: \"repeat\",\n        name: \"Repeat/list\",\n        description: \"A field that gets repeated multiple times (e.g. multiple text fields)\",\n        Icon: RepeatIcon,\n        color: \"#ff9408\",\n        property: {\n            dataType: \"array\",\n            of: {\n                dataType: \"string\",\n            },\n            Field: RepeatFieldBinding\n        }\n    },\n    custom_array: {\n        key: \"custom_array\",\n        name: \"Custom array\",\n        description: \"A field that saved its value as an array of custom objects\",\n        Icon: RepeatIcon,\n        color: \"#ff9408\",\n        property: {\n            dataType: \"array\",\n            of: [],\n            Field: ArrayCustomShapedFieldBinding\n        }\n    },\n    block: {\n        key: \"block\",\n        name: \"Block\",\n        description: \"A complex field that allows the user to compose different fields together, with a key->value format\",\n        Icon: ViewStreamIcon,\n        color: \"#ff9408\",\n        property: {\n            dataType: \"array\",\n            oneOf: {\n                properties: {},\n            },\n            Field: BlockFieldBinding\n        }\n    }\n};\n\nexport function getDefaultFieldConfig(property: Property | ResolvedProperty): PropertyConfig | undefined {\n    const fieldId = getDefaultFieldId(property);\n    if (!fieldId) {\n        console.error(\"No field id found for property\", property);\n        return undefined;\n    }\n    return DEFAULT_FIELD_CONFIGS[fieldId];\n}\n\nexport function getFieldConfig(property: Property | ResolvedProperty, propertyConfigs: Record<string, PropertyConfig<any>>): PropertyConfig | undefined {\n    const fieldId = getFieldId(property);\n    const defaultFieldId = getDefaultFieldId(property);\n    if (!defaultFieldId) {\n        console.error(\"No field id found for property\", property);\n        return undefined;\n    }\n    const defaultFieldConfig = DEFAULT_FIELD_CONFIGS[defaultFieldId];\n    const customField = fieldId ? propertyConfigs[fieldId] : undefined;\n    return mergeDeep(defaultFieldConfig ?? {}, customField ?? {});\n}\n\nexport function getDefaultFieldId(property: Property | ResolvedProperty) {\n    if (property.dataType === \"string\") {\n        if (property.multiline) {\n            return \"multiline\";\n        } else if (property.markdown) {\n            return \"markdown\";\n        } else if (property.storage) {\n            return \"file_upload\";\n        } else if (property.url) {\n            return \"url\";\n        } else if (property.email) {\n            return \"email\";\n        } else if (property.enumValues) {\n            return \"select\";\n        } else {\n            return \"text_field\";\n        }\n    } else if (property.dataType === \"number\") {\n        if (property.enumValues) {\n            return \"number_select\";\n        }\n        return \"number_input\";\n    } else if (property.dataType === \"map\") {\n        if (property.keyValue)\n            return \"key_value\";\n        return \"group\";\n    } else if (property.dataType === \"array\") {\n        const of = (property as ArrayProperty).of;\n        const oneOf = (property as ArrayProperty).oneOf;\n        if (oneOf) {\n            return \"block\";\n        } else if (Array.isArray(of)) {\n            return \"custom_array\";\n        } else if (isPropertyBuilder(of)) {\n            return \"repeat\";\n        } else if (of?.dataType === \"string\" && of.enumValues) {\n            return \"multi_select\";\n        } else if (of?.dataType === \"number\" && of.enumValues) {\n            return \"multi_number_select\";\n        } else if (of?.dataType === \"string\" && of.storage) {\n            return \"multi_file_upload\";\n        } else if (of?.dataType === \"reference\") {\n            return \"multi_references\";\n        } else {\n            return \"repeat\";\n        }\n    } else if (property.dataType === \"boolean\") {\n        return \"switch\";\n    } else if (property.dataType === \"date\") {\n        return \"date_time\";\n    } else if (property.dataType === \"reference\") {\n        return \"reference\";\n    }\n\n    console.error(\"Unsupported field config mapping\", property);\n    return undefined;\n}\n\nexport function getFieldId(property: Property | ResolvedProperty): string | undefined {\n    if (property.propertyConfig)\n        return property.propertyConfig;\n    return getDefaultFieldId(property);\n}\n","import {\n    ArrayProperty,\n    CMSType,\n    EntityCollection,\n    EntityCustomView,\n    EntityValues,\n    EnumValueConfig,\n    EnumValues,\n    NumberProperty,\n    Properties,\n    PropertiesOrBuilders,\n    Property,\n    PropertyConfig,\n    PropertyOrBuilder,\n    ResolvedArrayProperty,\n    ResolvedEntityCollection,\n    ResolvedNumberProperty,\n    ResolvedProperties,\n    ResolvedProperty,\n    ResolvedStringProperty,\n    StringProperty,\n    UserConfigurationPersistence\n} from \"../types\";\nimport { getValueInPath, mergeDeep } from \"./objects\";\nimport { getDefaultValuesFor, isPropertyBuilder } from \"./entities\";\nimport { DEFAULT_ONE_OF_TYPE } from \"./common\";\nimport { getIn } from \"@firecms/formex\";\nimport { enumToObjectEntries } from \"./enums\";\nimport { isDefaultFieldConfigId } from \"../core/field_configs\";\n\n// import util from \"util\";\n\nexport const resolveCollection = <M extends Record<string, any>, >\n({\n     collection,\n     path,\n     entityId,\n     values,\n     previousValues,\n     userConfigPersistence,\n     fields,\n     ignoreMissingFields = false\n }: {\n    collection: EntityCollection<M> | ResolvedEntityCollection<M>;\n    path: string,\n    entityId?: string,\n    values?: Partial<EntityValues<M>>,\n    previousValues?: Partial<EntityValues<M>>,\n    userConfigPersistence?: UserConfigurationPersistence;\n    fields?: Record<string, PropertyConfig>;\n    ignoreMissingFields?: boolean;\n}): ResolvedEntityCollection<M> => {\n\n    const collectionOverride = userConfigPersistence?.getCollectionConfig<M>(path);\n    const storedProperties = getValueInPath(collectionOverride, \"properties\");\n\n    const defaultValues = getDefaultValuesFor(collection.properties);\n    const usedValues = values ?? defaultValues;\n    const usedPreviousValues = previousValues ?? values ?? defaultValues;\n\n    const resolvedProperties = Object.entries(collection.properties)\n        .map(([key, propertyOrBuilder]) => {\n            const childResolvedProperty = resolveProperty({\n                propertyKey: key,\n                propertyOrBuilder: propertyOrBuilder as PropertyOrBuilder | ResolvedProperty,\n                values: usedValues,\n                previousValues: usedPreviousValues,\n                path,\n                entityId,\n                fields,\n                ignoreMissingFields\n            });\n            if (!childResolvedProperty) return {};\n            return ({\n                [key]: childResolvedProperty\n            });\n        })\n        .filter((a) => a !== null)\n        .reduce((a, b) => ({ ...a, ...b }), {}) as ResolvedProperties<M>;\n\n    const properties: Properties = mergeDeep(resolvedProperties, storedProperties);\n    const cleanedProperties = Object.entries(properties)\n        .filter(([_, property]) => Boolean(property?.dataType))\n        .map(([id, property]) => ({ [id]: property }))\n        .reduce((a, b) => ({ ...a, ...b }), {});\n\n    return {\n        ...collection,\n        properties: cleanedProperties,\n        originalCollection: collection\n    } as ResolvedEntityCollection<M>;\n\n};\n\n/**\n * Resolve property builders, enums and arrays.\n * @param propertyOrBuilder\n * @param propertyValue\n */\nexport function resolveProperty<T extends CMSType = CMSType, M extends Record<string, any> = any>({\n                                                                                                      propertyOrBuilder,\n                                                                                                      fromBuilder = false,\n                                                                                                      ignoreMissingFields = false,\n                                                                                                      ...props\n                                                                                                  }: {\n    propertyKey?: string,\n    propertyOrBuilder: PropertyOrBuilder<T, M> | ResolvedProperty<T>,\n    values?: Partial<M>,\n    previousValues?: Partial<M>,\n    path?: string,\n    entityId?: string,\n    index?: number,\n    fromBuilder?: boolean;\n    fields?: Record<string, PropertyConfig<any>>;\n    ignoreMissingFields?: boolean;\n}): ResolvedProperty<T> | null {\n\n    if (typeof propertyOrBuilder === \"object\" && \"resolved\" in propertyOrBuilder) {\n        return propertyOrBuilder as ResolvedProperty<T>;\n    }\n\n    let resolvedProperty: ResolvedProperty<T> | null = null;\n\n    if (!propertyOrBuilder) {\n        return null;\n    } else if (isPropertyBuilder(propertyOrBuilder)) {\n        const path = props.path;\n        if (!path)\n            throw Error(\"Trying to resolve a property builder without specifying the entity path\");\n\n        const usedPropertyValue = props.propertyKey ? getIn(props.values, props.propertyKey) : undefined;\n        const result: Property<T> | null = propertyOrBuilder({\n            ...props,\n            path,\n            propertyValue: usedPropertyValue,\n            values: props.values ?? {},\n            previousValues: props.previousValues ?? props.values ?? {}\n        });\n\n        if (!result) {\n            return null;\n        }\n\n        resolvedProperty = resolveProperty({\n            ...props,\n            propertyOrBuilder: result,\n            fromBuilder: true,\n            ignoreMissingFields\n        });\n    } else {\n        const property = propertyOrBuilder as Property<T>;\n        if (property.dataType === \"map\" && property.properties) {\n            const properties = resolveProperties({\n                ignoreMissingFields,\n                ...props,\n                properties: property.properties,\n            });\n            resolvedProperty = {\n                ...property,\n                resolved: true,\n                fromBuilder,\n                properties\n            } as ResolvedProperty<T>;\n        } else if (property.dataType === \"array\") {\n            resolvedProperty = resolveArrayProperty({\n                property,\n                fromBuilder,\n                ignoreMissingFields,\n                ...props\n            }) as ResolvedProperty<any>;\n        } else if ((property.dataType === \"string\" || property.dataType === \"number\") && property.enumValues) {\n            resolvedProperty = resolvePropertyEnum(property, fromBuilder) as ResolvedProperty<any>;\n        }\n    }\n\n    if (!resolvedProperty) {\n        resolvedProperty = {\n            ...propertyOrBuilder,\n            resolved: true,\n            fromBuilder\n        } as ResolvedProperty<T>;\n    }\n\n    if (resolvedProperty.propertyConfig && !isDefaultFieldConfigId(resolvedProperty.propertyConfig)) {\n        const cmsFields = props.fields;\n        if (!cmsFields && !ignoreMissingFields) {\n            throw Error(`Trying to resolve a property with key '${resolvedProperty.propertyConfig}' that inherits from a custom property config but no custom property configs were provided. Use the property 'propertyConfigs' in your app config to provide them`);\n        }\n        const customField: PropertyConfig | undefined = cmsFields?.[resolvedProperty.propertyConfig];\n        if (!customField) {\n            console.warn(`Trying to resolve a property with key '${resolvedProperty.propertyConfig}' that inherits from a custom property config but no custom property config with that key was found. Check the 'propertyConfigs' in your app config`)\n            console.warn(\"Available property configs\", cmsFields);\n            return null;\n        }\n        if (customField.property) {\n            const configPropertyOrBuilder = customField.property;\n            if (\"propertyConfig\" in configPropertyOrBuilder) {\n                delete configPropertyOrBuilder.propertyConfig;\n            }\n            const customFieldProperty = resolveProperty<any>({\n                propertyOrBuilder: configPropertyOrBuilder,\n                ignoreMissingFields,\n                ...props\n            });\n            if (customFieldProperty) {\n                resolvedProperty = mergeDeep(customFieldProperty, resolvedProperty);\n            }\n        }\n\n    }\n\n    return resolvedProperty\n        ? {\n            ...resolvedProperty,\n            resolved: true\n        }\n        : null;\n}\n\nexport function resolveArrayProperty<T extends any[], M>({\n                                                             propertyKey,\n                                                             property,\n                                                             ignoreMissingFields = false,\n                                                             ...props\n                                                         }: {\n    propertyKey?: string,\n    property: ArrayProperty<T> | ResolvedArrayProperty<T>,\n    values?: Partial<M>,\n    previousValues?: Partial<M>,\n    path?: string,\n    entityId?: string,\n    index?: number,\n    fromBuilder?: boolean;\n    fields?: Record<string, PropertyConfig>;\n    ignoreMissingFields?: boolean;\n}): ResolvedArrayProperty {\n    const propertyValue = propertyKey ? getIn(props.values, propertyKey) : undefined;\n\n    if (property.of) {\n        if (Array.isArray(property.of)) {\n            return {\n                ...property,\n                resolved: true,\n                fromBuilder: props.fromBuilder,\n                resolvedProperties: property.of.map((p, index) => {\n                    return resolveProperty({\n                        propertyKey: `${propertyKey}.${index}`,\n                        propertyOrBuilder: p as Property<any>,\n                        ignoreMissingFields,\n                        ...props,\n                        index\n                    });\n                })\n            } as ResolvedArrayProperty;\n        } else {\n            const of = property.of;\n            const resolvedProperties: ResolvedProperty[] = Array.isArray(propertyValue)\n                ? propertyValue.map((v: any, index: number) => resolveProperty({\n                    propertyKey: `${propertyKey}.${index}`,\n                    propertyOrBuilder: of,\n                    ignoreMissingFields,\n                    ...props,\n                    index\n                })).filter(e => Boolean(e)) as ResolvedProperty[]\n                : [];\n            const ofProperty = resolveProperty({\n                propertyKey: `${propertyKey}`,\n                propertyOrBuilder: of,\n                ignoreMissingFields,\n                ...props\n            });\n            if (!ofProperty && !ignoreMissingFields)\n                throw Error(\"When using a property builder as the 'of' prop of an ArrayProperty, you must return a valid child property\")\n            return {\n                ...property,\n                resolved: true,\n                fromBuilder: props.fromBuilder,\n                of: ofProperty,\n                resolvedProperties\n            } as ResolvedArrayProperty;\n        }\n    } else if (property.oneOf) {\n        const typeField = property.oneOf?.typeField ?? DEFAULT_ONE_OF_TYPE;\n        const resolvedProperties: ResolvedProperty[] = Array.isArray(propertyValue)\n            ? propertyValue.map((v, index) => {\n                const type = v && v[typeField];\n                const childProperty = property.oneOf?.properties[type];\n                if (!type || !childProperty) return null;\n                return resolveProperty({\n                    propertyKey: `${propertyKey}.${index}`,\n                    propertyOrBuilder: childProperty,\n                    ignoreMissingFields,\n                    ...props\n                });\n            }).filter(e => Boolean(e)) as ResolvedProperty[]\n            : [];\n        const properties = resolveProperties<any>({\n            properties: property.oneOf.properties,\n            ignoreMissingFields,\n            ...props\n        });\n        return {\n            ...property,\n            resolved: true,\n            oneOf: {\n                ...property.oneOf,\n                properties\n            },\n            fromBuilder: props.fromBuilder,\n            resolvedProperties\n        } as ResolvedArrayProperty;\n    } else if (!property.Field) {\n        throw Error(\"The array property needs to declare an 'of' or a 'oneOf' property, or provide a custom `Field`\")\n    } else {\n        return {\n            ...property,\n            resolved: true,\n            fromBuilder: props.fromBuilder\n        } as ResolvedArrayProperty;\n    }\n\n}\n\n/**\n * Resolve enums and arrays for properties\n * @param properties\n * @param value\n */\nexport function resolveProperties<M extends Record<string, any>>({\n                                                                     properties,\n                                                                     ignoreMissingFields,\n                                                                     ...props\n                                                                 }: {\n    properties: PropertiesOrBuilders<M>,\n    values?: Partial<M>,\n    previousValues?: Partial<M>,\n    path?: string,\n    entityId?: string,\n    index?: number,\n    fromBuilder?: boolean;\n    fields?: Record<string, PropertyConfig>;\n    ignoreMissingFields?: boolean;\n}): ResolvedProperties<M> {\n    return Object.entries<PropertyOrBuilder>(properties as Record<string, PropertyOrBuilder>)\n        .map(([key, property]) => {\n            const childResolvedProperty = resolveProperty({\n                propertyKey: key,\n                propertyOrBuilder: property,\n                ignoreMissingFields,\n                ...props\n            });\n            if (!childResolvedProperty) return {};\n            return {\n                [key]: childResolvedProperty\n            };\n        })\n        .filter((a) => a !== null)\n        .reduce((a, b) => ({ ...a, ...b }), {}) as ResolvedProperties<M>;\n}\n\n/**\n * Resolve enum aliases for a string or number property\n * @param property\n * @param fromBuilder\n */\nexport function resolvePropertyEnum(property: StringProperty | NumberProperty, fromBuilder?: boolean): ResolvedStringProperty | ResolvedNumberProperty {\n    if (typeof property.enumValues === \"object\") {\n        return {\n            ...property,\n            resolved: true,\n            enumValues: enumToObjectEntries(property.enumValues)?.filter((value) => value && (value.id || value.id === 0) && value.label) ?? [],\n            fromBuilder: fromBuilder ?? false\n        }\n    }\n    return property as ResolvedStringProperty | ResolvedNumberProperty;\n}\n\nexport function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n    if (typeof input === \"object\") {\n        return Object.entries(input).map(([id, value]) =>\n            (typeof value === \"string\"\n                ? {\n                    id,\n                    label: value\n                }\n                : value));\n    } else if (Array.isArray(input)) {\n        return input as EnumValueConfig[];\n    } else {\n        return undefined;\n    }\n}\n\nexport function resolveEntityView(entityView: string | EntityCustomView<any>, contextEntityViews?: EntityCustomView<any>[]): EntityCustomView<any> | undefined {\n    if (typeof entityView === \"string\") {\n        return contextEntityViews?.find((entry) => entry.key === entityView);\n    } else {\n        return entityView;\n    }\n}\n","import { EntityCollection, EntityCustomView } from \"../types\";\nimport { getCollectionPathsCombinations, removeInitialAndTrailingSlashes } from \"./navigation_utils\";\nimport { resolveEntityView } from \"./resolutions\";\n\nexport type NavigationViewInternal<M extends Record<string, any> = any> =\n    | NavigationViewEntityInternal<M>\n    | NavigationViewCollectionInternal<M>\n    | NavigationViewEntityCustomInternal<M>;\n\nexport interface NavigationViewEntityInternal<M extends Record<string, any>> {\n    type: \"entity\";\n    entityId: string;\n    path: string;\n    parentCollection: EntityCollection<M>;\n}\n\nexport interface NavigationViewCollectionInternal<M extends Record<string, any>> {\n    type: \"collection\";\n    path: string;\n    collection: EntityCollection<M>;\n}\n\nexport interface NavigationViewEntityCustomInternal<M extends Record<string, any>> {\n    type: \"custom_view\";\n    path: string;\n    view: EntityCustomView<M>;\n}\n\nexport function getNavigationEntriesFromPathInternal(props: {\n    path: string,\n    collections: EntityCollection[] | undefined,\n    currentFullPath?: string,\n    contextEntityViews?: EntityCustomView<any>[]\n}): NavigationViewInternal [] {\n\n    const {\n        path,\n        collections = [],\n        currentFullPath\n    } = props;\n\n    const subpaths = removeInitialAndTrailingSlashes(path).split(\"/\");\n    const subpathCombinations = getCollectionPathsCombinations(subpaths);\n\n    const result: NavigationViewInternal[] = [];\n    for (let i = 0; i < subpathCombinations.length; i++) {\n        const subpathCombination = subpathCombinations[i];\n\n        const collection: EntityCollection<any> | undefined = collections && collections.find((entry) => entry.id === subpathCombination || entry.path === subpathCombination);\n\n        if (collection) {\n            const pathOrAlias = collection.id ?? collection.path;\n            const collectionPath = currentFullPath && currentFullPath.length > 0\n                ? (currentFullPath + \"/\" + pathOrAlias)\n                : pathOrAlias;\n\n            result.push({\n                type: \"collection\",\n                path: collectionPath,\n                collection\n            });\n            const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, \"\"));\n            const nextSegments = restOfThePath.length > 0 ? restOfThePath.split(\"/\") : [];\n            if (nextSegments.length > 0) {\n                const entityId = nextSegments[0];\n                const fullPath = collectionPath + \"/\" + entityId;\n                result.push({\n                    type: \"entity\",\n                    entityId,\n                    path: collectionPath,\n                    parentCollection: collection\n                });\n                if (nextSegments.length > 1) {\n                    const newPath = nextSegments.slice(1).join(\"/\");\n                    if (!collection) {\n                        throw Error(\"collection not found resolving path: \" + collection);\n                    }\n                    const entityViews = collection.entityViews;\n                    const customView = entityViews && entityViews\n                        .map((entry) => resolveEntityView(entry, props.contextEntityViews))\n                        .filter(Boolean)\n                        .find((entry) => entry!.key === newPath);\n                    if (customView) {\n                        const path = currentFullPath && currentFullPath.length > 0\n                            ? (currentFullPath + \"/\" + customView.key)\n                            : customView.key;\n                        result.push({\n                            type: \"custom_view\",\n                            path,\n                            view: customView\n                        });\n                    } else if (collection.subcollections) {\n                        result.push(...getNavigationEntriesFromPathInternal({\n                            path: newPath,\n                            collections: collection.subcollections,\n                            currentFullPath: fullPath,\n                            contextEntityViews: props.contextEntityViews\n                        }));\n                    }\n                }\n            }\n            break;\n        }\n\n    }\n    return result;\n}\n","export const CONTAINER_FULL_WIDTH = \"100vw\";\n\nexport const ADDITIONAL_TAB_WIDTH = \"55vw\";\n\nexport const FORM_CONTAINER_WIDTH = \"768px\";\n","import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n    Entity,\n    EntityCollection,\n    EntityCustomView,\n    EntityStatus,\n    EntityValues,\n    FireCMSPlugin,\n    FormContext,\n    User\n} from \"../types\";\nimport { CircularProgressCenter, EntityCollectionView, EntityView, ErrorBoundary, } from \"../components\";\nimport {\n    canEditEntity,\n    removeInitialAndTrailingSlashes,\n    resolveDefaultSelectedView,\n    resolveEntityView,\n    useDebouncedCallback\n} from \"../util\";\n\nimport {\n    saveEntityWithCallbacks,\n    useAuthController,\n    useCustomizationController,\n    useDataSource,\n    useEntityFetch,\n    useFireCMSContext,\n    useSideEntityController,\n    useSnackbarController\n} from \"../hooks\";\nimport { EntityForm } from \"../form\";\nimport { CircularProgress, CloseIcon, cn, defaultBorderMixin, IconButton, Tab, Tabs, Typography } from \"@firecms/ui\";\nimport { EntityFormSaveParams } from \"../form/EntityForm\";\nimport { useSideDialogContext } from \"./index\";\n\nconst MAIN_TAB_VALUE = \"main_##Q$SC^#S6\";\n\nexport interface EntityEditViewProps<M extends Record<string, any>> {\n    path: string;\n    collection: EntityCollection<M>;\n    entityId?: string;\n    copy?: boolean;\n    selectedSubPath?: string;\n    parentCollectionIds: string[];\n    formWidth?: number | string;\n    onValuesAreModified: (modified: boolean) => void;\n    onUpdate?: (params: { entity: Entity<any> }) => void;\n    onClose?: () => void;\n}\n\n/**\n * This is the default view that is used as the content of a side panel when\n * an entity is opened.\n * You probably don't want to use this view directly since it is bound to the\n * side panel. Instead, you might want to use {@link EntityForm} or {@link EntityCollectionView}\n */\nexport function EntityEditView<M extends Record<string, any>, UserType extends User>({\n                                                                                         path,\n                                                                                         entityId,\n                                                                                         selectedSubPath,\n                                                                                         copy,\n                                                                                         collection,\n                                                                                         parentCollectionIds,\n                                                                                         onValuesAreModified,\n                                                                                         formWidth,\n                                                                                         onUpdate,\n                                                                                         onClose,\n                                                                                     }: EntityEditViewProps<M>) {\n\n    if (collection.customId && collection.formAutoSave) {\n        console.warn(`The collection ${collection.path} has customId and formAutoSave enabled. This is not supported and formAutoSave will be ignored`);\n    }\n\n    const [saving, setSaving] = useState(false);\n    /**\n     * These are the values that are being saved. They are debounced.\n     * We use this only when autoSave is enabled.\n     */\n    const [valuesToBeSaved, setValuesToBeSaved] = useState<EntityValues<M> | undefined>(undefined);\n    useDebouncedCallback(valuesToBeSaved, () => {\n        if (valuesToBeSaved)\n            saveEntity({\n                entityId: usedEntity?.id,\n                collection,\n                path,\n                values: valuesToBeSaved,\n                closeAfterSave: false\n            });\n    }, false, 2000);\n\n    // const largeLayout = useLargeLayout();\n    // const largeLayoutTabSelected = useRef(!largeLayout);\n    // const resolvedFormWidth: string = typeof formWidth === \"number\" ? `${formWidth}px` : formWidth ?? FORM_CONTAINER_WIDTH;\n\n    const dataSource = useDataSource(collection);\n    const sideDialogContext = useSideDialogContext();\n    const sideEntityController = useSideEntityController();\n    const snackbarController = useSnackbarController();\n    const customizationController = useCustomizationController();\n    const context = useFireCMSContext();\n    const authController = useAuthController<UserType>();\n\n    const [formContext, setFormContext] = useState<FormContext<M> | undefined>(undefined);\n\n    const [status, setStatus] = useState<EntityStatus>(copy ? \"copy\" : (entityId ? \"existing\" : \"new\"));\n\n    const modifiedValuesRef = useRef<EntityValues<M> | undefined>(undefined);\n    const modifiedValues = modifiedValuesRef.current;\n\n    const subcollections = (collection.subcollections ?? []).filter(c => !c.hideFromNavigation);\n    const subcollectionsCount = subcollections?.length ?? 0;\n    const customViews = collection.entityViews;\n    const customViewsCount = customViews?.length ?? 0;\n    const autoSave = collection.formAutoSave && !collection.customId;\n\n    const hasAdditionalViews = customViewsCount > 0 || subcollectionsCount > 0;\n\n    const defaultSelectedView = selectedSubPath ?? resolveDefaultSelectedView(\n        collection ? collection.defaultSelectedView : undefined,\n        {\n            status,\n            entityId\n        }\n    );\n\n    const selectedTabRef = useRef<string>(defaultSelectedView ?? MAIN_TAB_VALUE);\n\n    const mainViewVisible = selectedTabRef.current === MAIN_TAB_VALUE;\n\n    const {\n        entity,\n        dataLoading,\n        // eslint-disable-next-line no-unused-vars\n        dataLoadingError\n    } = useEntityFetch<M, UserType>({\n        path,\n        entityId,\n        collection,\n        useCache: false\n    });\n\n    const [usedEntity, setUsedEntity] = useState<Entity<M> | undefined>(entity);\n    const [readOnly, setReadOnly] = useState<boolean | undefined>(undefined);\n\n    useEffect(() => {\n        if (entity)\n            setUsedEntity(entity);\n    }, [entity]);\n\n    useEffect(() => {\n        if (status === \"new\") {\n            setReadOnly(false);\n        } else {\n            const editEnabled = usedEntity ? canEditEntity(collection, authController, path, usedEntity ?? null) : false;\n            if (usedEntity)\n                setReadOnly(!editEnabled);\n        }\n    }, [authController, usedEntity, status]);\n\n    const onPreSaveHookError = useCallback((e: Error) => {\n        setSaving(false);\n        snackbarController.open({\n            type: \"error\",\n            message: \"Error before saving: \" + e?.message\n        });\n        console.error(e);\n    }, [snackbarController]);\n\n    const onSaveSuccessHookError = useCallback((e: Error) => {\n        setSaving(false);\n        snackbarController.open({\n            type: \"error\",\n            message: \"Error after saving (entity is saved): \" + e?.message\n        });\n        console.error(e);\n    }, [snackbarController]);\n\n    const onSaveSuccess = (updatedEntity: Entity<M>, closeAfterSave: boolean) => {\n\n        setSaving(false);\n        if (!autoSave)\n            snackbarController.open({\n                type: \"success\",\n                message: `${collection.singularName ?? collection.name}: Saved correctly`\n            });\n\n        setUsedEntity(updatedEntity);\n        setStatus(\"existing\");\n\n        onValuesAreModified(false);\n\n        if (onUpdate)\n            onUpdate({ entity: updatedEntity });\n\n        if (closeAfterSave) {\n            sideDialogContext.setBlocked(false);\n            sideDialogContext.close(true);\n            onClose?.();\n        } else if (status !== \"existing\") {\n            sideEntityController.replace({\n                path,\n                entityId: updatedEntity.id,\n                selectedSubPath: selectedTabRef.current,\n                updateUrl: true,\n                collection,\n            });\n        }\n\n    };\n\n    const onSaveFailure = useCallback((e: Error) => {\n\n        setSaving(false);\n        snackbarController.open({\n            type: \"error\",\n            message: \"Error saving: \" + e?.message\n        });\n\n        console.error(\"Error saving entity\", path, entityId);\n        console.error(e);\n    }, [entityId, path, snackbarController]);\n\n    const saveEntity = ({\n                            values,\n                            previousValues,\n                            closeAfterSave,\n                            entityId,\n                            collection,\n                            path\n                        }: {\n        collection: EntityCollection<M>,\n        path: string,\n        entityId: string | undefined,\n        values: M,\n        previousValues?: M,\n        closeAfterSave: boolean,\n    }) => {\n        setSaving(true);\n        saveEntityWithCallbacks({\n            path,\n            entityId,\n            values,\n            previousValues,\n            collection,\n            status,\n            dataSource,\n            context,\n            onSaveSuccess: (updatedEntity: Entity<M>) => onSaveSuccess(updatedEntity, closeAfterSave),\n            onSaveFailure,\n            onPreSaveHookError,\n            onSaveSuccessHookError\n        }).then();\n    };\n\n    const onSaveEntityRequest = async ({\n                                           collection,\n                                           path,\n                                           entityId,\n                                           values,\n                                           previousValues,\n                                           closeAfterSave,\n                                           autoSave\n                                       }: EntityFormSaveParams<M>): Promise<void> => {\n        if (!status)\n            return;\n\n        if (autoSave) {\n            setValuesToBeSaved(values);\n        } else {\n            saveEntity({\n                collection,\n                path,\n                entityId,\n                values,\n                previousValues,\n                closeAfterSave\n            });\n        }\n    };\n\n    const resolvedEntityViews = customViews ? customViews\n            .map(e => resolveEntityView(e, customizationController.entityViews))\n            .filter(Boolean) as EntityCustomView[]\n        : [];\n\n    const customViewsView: React.ReactNode[] | undefined = customViews && resolvedEntityViews\n        .map(\n            (customView, colIndex) => {\n                if (!customView)\n                    return null;\n                if (selectedTabRef.current !== customView.key)\n                    return null;\n                const Builder = customView.Builder;\n                if (!Builder) {\n                    console.error(\"customView.Builder is not defined\");\n                    return null;\n                }\n                return <div\n                    className={cn(defaultBorderMixin,\n                        \"relative flex-grow w-full h-full overflow-auto \")}\n                    key={`custom_view_${customView.key}`}\n                    role=\"tabpanel\">\n                    <ErrorBoundary>\n                        {formContext && <Builder\n                            collection={collection}\n                            entity={usedEntity}\n                            modifiedValues={modifiedValues ?? usedEntity?.values}\n                            formContext={formContext}\n                        />}\n                    </ErrorBoundary>\n                </div>;\n            }\n        ).filter(Boolean);\n\n    const globalLoading = (dataLoading && !usedEntity) ||\n        ((!usedEntity || readOnly === undefined) && (status === \"existing\" || status === \"copy\"));\n\n    const loading = globalLoading || saving;\n\n    const subCollectionsViews = subcollections && subcollections.map(\n        (subcollection, colIndex) => {\n            const subcollectionId = subcollection.id ?? subcollection.path;\n            const fullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : undefined;\n            if (selectedTabRef.current !== subcollectionId)\n                return null;\n            return (\n                <div\n                    className={\"relative flex-grow h-full overflow-auto w-full\"}\n                    key={`subcol_${subcollectionId}`}\n                    role=\"tabpanel\">\n\n                    {loading && <CircularProgressCenter/>}\n\n                    {!globalLoading &&\n                        (usedEntity && fullPath\n                            ? <EntityCollectionView\n                                fullPath={fullPath}\n                                parentCollectionIds={[...parentCollectionIds, collection.id]}\n                                isSubCollection={true}\n                                {...subcollection}/>\n                            : <div\n                                className=\"flex items-center justify-center w-full h-full p-3\">\n                                <Typography variant={\"label\"}>\n                                    You need to save your entity before\n                                    adding additional collections\n                                </Typography>\n                            </div>)\n                    }\n\n                </div>\n            );\n        }\n    ).filter(Boolean);\n\n    const onDiscard = useCallback(() => {\n        onValuesAreModified(false);\n    }, []);\n\n    const onSideTabClick = (value: string) => {\n        selectedTabRef.current = value;\n        sideEntityController.replace({\n            path,\n            entityId,\n            selectedSubPath: value === MAIN_TAB_VALUE ? undefined : value,\n            updateUrl: true,\n            collection,\n        });\n    };\n\n    const onValuesChanged = useCallback((values?: EntityValues<M>) => {\n        modifiedValuesRef.current = values;\n    }, []);\n\n    // eslint-disable-next-line n/handle-callback-err\n    const onIdUpdateError = useCallback((error: any) => {\n        snackbarController.open({\n            type: \"error\",\n            message: \"Error updating id, check the console\"\n        });\n    }, []);\n\n    const onIdChange = useCallback((id: string) => {\n        setUsedEntity((prevEntity) => prevEntity\n            ? {\n                ...prevEntity,\n                id\n            }\n            : undefined);\n    }, []);\n\n    const onModified = (dirty: boolean) => {\n        if (!autoSave)\n            onValuesAreModified(dirty);\n    }\n\n    function buildForm() {\n        const plugins = customizationController.plugins;\n        let form = <EntityForm\n            status={status}\n            path={path}\n            collection={collection}\n            onEntitySaveRequested={onSaveEntityRequest}\n            onDiscard={onDiscard}\n            onValuesChanged={onValuesChanged}\n            onModified={onModified}\n            entity={usedEntity}\n            onIdChange={onIdChange}\n            onFormContextChange={setFormContext}\n            hideId={collection.hideIdFromForm}\n            autoSave={autoSave}\n            onIdUpdateError={onIdUpdateError}\n        />;\n        if (plugins) {\n            plugins.forEach((plugin: FireCMSPlugin) => {\n                if (plugin.form?.provider) {\n                    form = (\n                        <plugin.form.provider.Component\n                            status={status}\n                            path={path}\n                            collection={collection}\n                            onDiscard={onDiscard}\n                            onValuesChanged={onValuesChanged}\n                            onModified={onModified}\n                            entity={usedEntity}\n                            context={context}\n                            formContext={formContext}\n                            {...plugin.form.provider.props}>\n                            {form}\n                        </plugin.form.provider.Component>\n                    );\n                }\n            });\n        }\n        return <ErrorBoundary>{form}</ErrorBoundary>;\n    }\n\n    const form = (readOnly === undefined)\n        ? <></>\n        : (!readOnly\n            ? buildForm()\n            : (\n                <>\n                    <Typography\n                        className={\"mt-16 mb-8 mx-8\"}\n                        variant={\"h4\"}>{collection.singularName ?? collection.name}\n                    </Typography>\n                    <EntityView\n                        className={\"px-12\"}\n                        entity={usedEntity as Entity<M>}\n                        path={path}\n                        collection={collection}/>\n                </>\n            ));\n\n    const subcollectionTabs = subcollections && subcollections.map(\n        (subcollection) =>\n            <Tab\n                className=\"text-sm min-w-[140px]\"\n                value={subcollection.id}\n                key={`entity_detail_collection_tab_${subcollection.name}`}>\n                {subcollection.name}\n            </Tab>\n    );\n\n    const customViewTabs = resolvedEntityViews.map(\n        (view) =>\n\n            <Tab\n                className=\"text-sm min-w-[140px]\"\n                value={view.key}\n                key={`entity_detail_collection_tab_${view.name}`}>\n                {view.name}\n            </Tab>\n    );\n\n    return (\n        <div\n            className=\"flex flex-col h-full w-full transition-width duration-250 ease-in-out\">\n            {\n                <>\n\n                    <div\n                        className={cn(defaultBorderMixin, \"no-scrollbar border-b pl-2 pr-2 pt-1 flex items-end overflow-scroll bg-gray-50 dark:bg-gray-950\")}>\n\n                        <div\n                            className=\"pb-1 self-center\">\n                            <IconButton\n                                onClick={() => {\n                                    onClose?.();\n                                    return sideDialogContext.close(false);\n                                }}\n                                size=\"large\">\n                                <CloseIcon/>\n                            </IconButton>\n                        </div>\n\n                        <div className={\"flex-grow\"}/>\n\n                        {globalLoading && <div\n                            className=\"self-center\">\n                            <CircularProgress size={\"small\"}/>\n                        </div>}\n\n                        <Tabs\n                            value={selectedTabRef.current}\n                            onValueChange={(value) => {\n                                onSideTabClick(value);\n                            }}\n                            className=\"pl-4 pr-4 pt-0\">\n\n                            <Tab\n                                disabled={!hasAdditionalViews}\n                                value={MAIN_TAB_VALUE}\n                                className={`${\n                                    !hasAdditionalViews ? \"hidden\" : \"\"\n                                } text-sm min-w-[140px]`}\n                            >{collection.singularName ?? collection.name}</Tab>\n\n                            {customViewTabs}\n\n                            {subcollectionTabs}\n                        </Tabs>\n\n                    </div>\n\n                    <div\n                        className={\"flex-grow h-full flex overflow-auto flex-row w-full \"}\n                        style={{\n                            // width: `calc(${ADDITIONAL_TAB_WIDTH} + ${resolvedFormWidth})`,\n                            // maxWidth: \"100%\",\n                            // [`@media (max-width: ${resolvedFormWidth})`]: {\n                            //     width: resolvedFormWidth\n                            // }\n                        }}>\n\n                        <div\n                            role=\"tabpanel\"\n                            hidden={!mainViewVisible}\n                            id={`form_${path}`}\n                            className={\" w-full\"}>\n\n                            {globalLoading\n                                ? <CircularProgressCenter/>\n                                : form}\n\n                        </div>\n\n                        {customViewsView}\n\n                        {subCollectionsViews}\n\n                    </div>\n\n                </>\n            }\n\n        </div>\n    );\n}\n","import React, { useCallback } from \"react\";\nimport { Blocker, Transition } from \"history\";\nimport { UNSAFE_NavigationContext, useNavigate } from \"react-router-dom\";\nimport { Button, Dialog, DialogActions, DialogContent, Typography } from \"@firecms/ui\";\n\nexport function useNavigationUnsavedChangesDialog(when: boolean, onSuccess: () => void):\n    {\n        navigationWasBlocked: boolean,\n        handleCancel: () => void,\n        handleOk: () => void\n    } {\n\n    const [nextLocation, setNextLocation] = React.useState<any | undefined>();\n    const { navigator } = React.useContext(UNSAFE_NavigationContext);\n\n    const navigate = useNavigate();\n\n    const handleCancel = () => {\n        setNextLocation(undefined);\n    };\n\n    const handleOk = () => {\n        onSuccess();\n        setNextLocation(undefined);\n        navigate(-1);\n    };\n\n    const blocker: Blocker = useCallback(({\n                                              action,\n                                              location: nextLocation,\n                                              retry\n                                          }) => {\n        switch (action) {\n            case \"REPLACE\": {\n                retry();\n                return;\n            }\n            case \"POP\": {\n                setNextLocation(nextLocation);\n            }\n        }\n    }, []);\n\n    React.useEffect(() => {\n        if (!when) return;\n        if (nextLocation) return;\n        if (!(\"block\" in navigator)) return;\n        const unblock = (navigator as any).block((tx: Transition) => {\n            const autoUnblockingTx = {\n                ...tx,\n                retry() {\n                    unblock();\n                    tx.retry();\n                }\n            };\n            blocker(autoUnblockingTx);\n        });\n\n        return unblock;\n    }, [navigator, blocker, when, nextLocation]);\n\n    return {\n        navigationWasBlocked: Boolean(nextLocation),\n        handleCancel,\n        handleOk\n    };\n}\n\nexport interface UnsavedChangesDialogProps {\n    open: boolean;\n    body?: React.ReactNode;\n    title?: string;\n    handleOk: () => void;\n    handleCancel: () => void;\n}\n\nexport function UnsavedChangesDialog({\n                                         open,\n                                         handleOk,\n                                         handleCancel,\n                                         body,\n                                         title\n                                     }: UnsavedChangesDialogProps) {\n\n    return (\n        <Dialog\n            open={open}\n            onOpenChange={(open) => open ? handleCancel() : handleOk()}\n        >\n            <DialogContent>\n                <Typography variant={\"h6\"}>{title}</Typography>\n\n                {body}\n\n                <Typography>\n                    Are you sure you want to leave this page?\n                </Typography>\n\n            </DialogContent>\n            <DialogActions>\n                <Button variant=\"text\" onClick={handleCancel} autoFocus> Cancel </Button>\n                <Button onClick={handleOk}> Ok </Button>\n            </DialogActions>\n        </Dialog>\n    );\n}\n","import React, { useContext, useEffect, useState } from \"react\";\nimport { useSideDialogsController } from \"../hooks\";\nimport { SideDialogPanelProps } from \"../types\";\nimport { Sheet } from \"@firecms/ui\";\nimport { UnsavedChangesDialog, useNavigationUnsavedChangesDialog } from \"../internal/useUnsavedChangesDialog\";\nimport { ErrorBoundary } from \"../components\";\n\nexport type SideDialogContextProps = {\n    blocked: boolean,\n    setBlocked: (blocked: boolean) => void,\n    setBlockedNavigationMessage: (message?: React.ReactNode) => void,\n    width?: string,\n    close: (force?: boolean) => void\n}\n\nconst SideDialogContext = React.createContext<SideDialogContextProps>({\n    width: \"\",\n    blocked: false,\n    setBlocked: (blocked: boolean) => {\n    },\n    setBlockedNavigationMessage: (message?: React.ReactNode) => {\n    },\n    close: () => {\n    }\n});\n\n/**\n * This hook is used to access the properties of a particular side dialog,\n * in contrast with {@link useSideDialogsController} which handles the\n * state of all the dialogs.\n */\nexport const useSideDialogContext = () => useContext<SideDialogContextProps>(SideDialogContext);\n\n/**\n * This is the component in charge of rendering the side dialogs used\n * for editing entities. Use the {@link useSideEntityController} to open\n * and control the dialogs.\n * This component needs a parent {@link FireCMS}\n * {@link useSideDialogsController}\n * @group Components\n */\nexport function SideDialogs() {\n\n    const sideDialogsController = useSideDialogsController();\n\n    const sidePanels = sideDialogsController.sidePanels;\n\n    const panels: (SideDialogPanelProps | undefined)[] = [...sidePanels];\n    panels.push(undefined);\n\n    return <>\n        {\n            panels.map((panel, index) =>\n                <SideDialogView\n                    key={`side_dialog_${index}`}\n                    panel={panel}\n                    offsetPosition={sidePanels.length - index - 1}/>)\n        }\n    </>;\n}\n\nfunction SideDialogView({\n                            offsetPosition,\n                            panel\n                        }: {\n    offsetPosition: number,\n    panel?: SideDialogPanelProps\n}) {\n\n    // was the closing of the dialog requested by the drawer\n    const [drawerCloseRequested, setDrawerCloseRequested] = useState<boolean>(false);\n    const [blocked, setBlocked] = useState(false);\n    const [blockedNavigationMessage, setBlockedNavigationMessage] = useState<React.ReactNode | undefined>();\n\n    const widthRef = React.useRef<string | undefined>(panel?.width);\n    const width = widthRef.current;\n\n    const sideDialogsController = useSideDialogsController();\n\n    const {\n        navigationWasBlocked,\n        handleOk: handleNavigationOk,\n        handleCancel: handleNavigationCancel\n    } = useNavigationUnsavedChangesDialog(\n        blocked && !drawerCloseRequested,\n        () => setBlocked(false)\n    );\n\n    useEffect(() => {\n        if (panel)\n            widthRef.current = panel.width;\n    }, [panel])\n\n    const handleDrawerCloseOk = () => {\n        setBlocked(false);\n        setDrawerCloseRequested(false);\n        sideDialogsController.close();\n        panel?.onClose?.();\n    };\n\n    const handleDrawerCloseCancel = () => {\n        setDrawerCloseRequested(false);\n    };\n\n    const onCloseRequest = (force?: boolean) => {\n        if (blocked && !force) {\n            setDrawerCloseRequested(true);\n        } else {\n            sideDialogsController.close();\n            panel?.onClose?.();\n        }\n    };\n\n    // const offsetClass = offsetPosition > 0 ? `transform translate-x-${offsetPosition}` : \"\";\n\n    return (\n        <SideDialogContext.Provider\n            value={{\n                blocked,\n                setBlocked,\n                setBlockedNavigationMessage,\n                width,\n                close: onCloseRequest\n            }}>\n\n            <Sheet\n                open={Boolean(panel)}\n                onOpenChange={(open) => !open && onCloseRequest()}\n            >\n                {panel &&\n                    <div\n                        className={\"transform max-w-[100vw] lg:max-w-[95vw] flex flex-col h-full transition-all duration-250 ease-in-out bg-white dark:bg-gray-900 \"}\n                        style={{\n                            width: panel.width,\n                            transform: `translateX(-${offsetPosition * 200}px)`\n                        }}\n                    >\n                        <ErrorBoundary>\n                            {panel.component}\n                        </ErrorBoundary>\n                    </div>}\n\n                {!panel && <div style={{ width }}/>}\n\n            </Sheet>\n\n            <UnsavedChangesDialog\n                open={navigationWasBlocked || drawerCloseRequested}\n                handleOk={drawerCloseRequested ? handleDrawerCloseOk : handleNavigationOk}\n                handleCancel={drawerCloseRequested ? handleDrawerCloseCancel : handleNavigationCancel}\n                body={blockedNavigationMessage}/>\n\n        </SideDialogContext.Provider>\n\n    );\n}\n","import React, { useCallback, useEffect, useMemo } from \"react\";\n\nimport { EntitySidePanelProps } from \"../types\";\nimport { useNavigationController } from \"../hooks\";\n\nimport { ErrorBoundary } from \"../components\";\nimport { EntityEditView } from \"./EntityEditView\";\nimport { useSideDialogContext } from \"./SideDialogs\";\n\n/**\n * This is the component in charge of rendering the side dialog used\n * for editing entities. Use the {@link useSideEntityController} to open\n * and control the dialogs.\n * This component needs a parent {@link FireCMS}\n * {@link useSideEntityController}\n * @group Components\n */\nexport function EntitySidePanel(props: EntitySidePanelProps) {\n\n    const {\n        blocked,\n        setBlocked,\n        setBlockedNavigationMessage\n    } = useSideDialogContext();\n\n    const navigationController = useNavigationController();\n\n    const parentCollectionIds = useMemo(() => {\n        return navigationController.getParentCollectionIds(props.path);\n    }, [navigationController, props.path]);\n\n    const collection = useMemo(() => {\n        if (!props) return undefined;\n        let usedCollection = props.collection;\n\n        const registryCollection = navigationController.getCollection(props.path);\n        if (registryCollection) {\n            usedCollection = registryCollection;\n        }\n        if (!usedCollection) {\n            console.error(\"ERROR: No collection found in path `\", props.path, \"`. Entity id: \", props.entityId);\n            throw Error(\"ERROR: No collection found in path `\" + props.path + \"`. Make sure you have defined a collection for this path in the root navigation.\");\n        }\n\n        return usedCollection;\n    }, [navigationController, props]);\n\n    useEffect(() => {\n        function beforeunload(e: any) {\n            if (blocked && collection) {\n                e.preventDefault();\n                e.returnValue = `You have unsaved changes in this ${collection.name}. Are you sure you want to leave this page?`;\n            }\n        }\n\n        if (typeof window !== \"undefined\")\n            window.addEventListener(\"beforeunload\", beforeunload);\n\n        return () => {\n            if (typeof window !== \"undefined\")\n                window.removeEventListener(\"beforeunload\", beforeunload);\n        };\n\n    }, [blocked, collection]);\n\n    const onValuesAreModified = useCallback((modified: boolean) => {\n        setBlocked(modified);\n        setBlockedNavigationMessage(modified\n            ? <> You have unsaved changes in this <b>{collection?.singularName ?? collection?.name}</b>.</>\n            : undefined)\n    }, [collection?.name, setBlocked, setBlockedNavigationMessage]);\n\n    if (!props || !collection) {\n        return <div className={\"w-full\"}/>;\n    }\n\n    return (\n        <>\n            <ErrorBoundary>\n                <EntityEditView\n                    {...props}\n                    formWidth={props.width}\n                    collection={collection}\n                    parentCollectionIds={parentCollectionIds}\n                    onValuesAreModified={onValuesAreModified}\n                />\n            </ErrorBoundary>\n\n        </>\n    );\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport {\n    EntityCollection,\n    EntitySidePanelProps,\n    NavigationController, PropertyConfig,\n    ResolvedProperty,\n    SideDialogPanelProps,\n    SideDialogsController,\n    SideEntityController\n} from \"../types\";\nimport { getNavigationEntriesFromPathInternal, NavigationViewInternal } from \"../util/navigation_from_path\";\nimport { useLocation } from \"react-router-dom\";\nimport { removeInitialAndTrailingSlashes, resolveCollection, resolveDefaultSelectedView } from \"../util\";\nimport { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, FORM_CONTAINER_WIDTH } from \"./common\";\nimport { useLargeLayout } from \"../hooks\";\nimport { EntitySidePanel } from \"../core/EntitySidePanel\";\n\nconst NEW_URL_HASH = \"new\";\n\nexport function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string {\n    if (small) return CONTAINER_FULL_WIDTH;\n    const mainViewSelected = !props.selectedSubPath;\n    let resolvedWidth: string | undefined;\n    if (props.width) {\n        resolvedWidth = typeof props.width === \"number\" ? `${props.width}px` : props.width;\n    } else if (props.collection?.sideDialogWidth) {\n        resolvedWidth = typeof props.collection.sideDialogWidth === \"number\" ? `${props.collection.sideDialogWidth}px` : props.collection.sideDialogWidth;\n    }\n\n    if (!mainViewSelected) {\n        return `calc(${ADDITIONAL_TAB_WIDTH} + ${resolvedWidth ?? FORM_CONTAINER_WIDTH})`\n    } else {\n        if (resolvedWidth) {\n            return resolvedWidth\n        } else if (!props.collection) {\n            return FORM_CONTAINER_WIDTH;\n        } else {\n            return calculateCollectionDesiredWidth(props.collection);\n        }\n    }\n}\n\nconst collectionViewWidthCache: { [key: string]: string } = {};\n\nfunction calculateCollectionDesiredWidth(collection: EntityCollection<any>): string {\n    if (collectionViewWidthCache[collection.id]) {\n        return collectionViewWidthCache[collection.id];\n    }\n    const resolvedCollection = resolveCollection({\n        collection,\n        path: \"__ignored\",\n        ignoreMissingFields: true\n    });\n\n    let result = FORM_CONTAINER_WIDTH\n    if (resolvedCollection?.properties) {\n        const values = Object.values(resolvedCollection.properties).map((p: ResolvedProperty) => getNestedPropertiesDepth(p));\n        const maxDepth = Math.max(...values);\n        if (maxDepth < 3) {\n            result = FORM_CONTAINER_WIDTH;\n        } else {\n            result = 768 + 32 * (maxDepth - 2) + \"px\";\n        }\n    }\n    collectionViewWidthCache[collection.id] = result;\n    return result;\n}\n\nfunction getNestedPropertiesDepth(property: ResolvedProperty, accumulator: number = 0): number {\n    if (property.dataType === \"map\" && property.properties) {\n        const values = Object.values(property.properties).flatMap((property) => getNestedPropertiesDepth(property, accumulator + 1));\n        return Math.max(...values);\n    } else if (property.dataType === \"array\" && property.oneOf) {\n        return accumulator + 3;\n    } else if (property.dataType === \"array\" && property.of) {\n        if (Array.isArray(property.of)) {\n            return Math.max(...property.of.map((p) => getNestedPropertiesDepth(p, accumulator + 1)));\n        } else {\n            return getNestedPropertiesDepth(property.of, accumulator + 1);\n        }\n    } else {\n        return accumulator + 1;\n    }\n}\n\nexport const useBuildSideEntityController = (navigation: NavigationController,\n                                             sideDialogsController: SideDialogsController): SideEntityController => {\n\n    const location = useLocation();\n    const initialised = useRef<boolean>(false);\n\n    const smallLayout = !useLargeLayout();\n\n    // only on initialisation, create panels from URL\n    useEffect(() => {\n        if (!navigation.loading && !initialised.current) {\n            console.debug(\"Initialising side entity controller\");\n            if (navigation.isUrlCollectionPath(location.pathname)) {\n                const newFlag = location.hash === `#${NEW_URL_HASH}`;\n                const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);\n                const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], newFlag);\n                for (let i = 0; i < panelsFromUrl.length; i++) {\n                    const props = panelsFromUrl[i];\n                    setTimeout(() => {\n                        if (i === 0)\n                            sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));\n                        else\n                            sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout))\n                    }, 1);\n                }\n            } else {\n                // console.warn(\"Location path is not a collection path\");\n            }\n            initialised.current = true;\n        }\n    }, [location, navigation.loading, navigation.isUrlCollectionPath, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout, navigation]);\n\n    const close = useCallback(() => {\n        sideDialogsController.close();\n    }, [sideDialogsController]);\n\n    const open = useCallback((props: EntitySidePanelProps<any>) => {\n\n        if (props.copy && !props.entityId) {\n            throw Error(\"If you want to copy an entity you need to provide an entityId\");\n        }\n\n        const defaultSelectedView = resolveDefaultSelectedView(\n            props.collection ? props.collection.defaultSelectedView : undefined,\n            {\n                status: props.copy ? \"copy\" : (props.entityId ? \"existing\" : \"new\"),\n                entityId: props.entityId\n            }\n        );\n\n        sideDialogsController.open(propsToSidePanel({\n            selectedSubPath: defaultSelectedView,\n            ...props,\n        }, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));\n\n    }, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout]);\n\n    const replace = useCallback((props: EntitySidePanelProps<any>) => {\n\n        if (props.copy && !props.entityId) {\n            throw Error(\"If you want to copy an entity you need to provide an entityId\");\n        }\n\n        sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));\n\n    }, [navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout]);\n\n    return {\n        close,\n        open,\n        replace\n    };\n};\n\nexport function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[] {\n\n    const navigationViewsForPath: NavigationViewInternal<any>[] = getNavigationEntriesFromPathInternal({\n        path,\n        collections\n    });\n\n    const sidePanels: EntitySidePanelProps<any>[] = [];\n    let lastCollectionPath = \"\";\n    for (let i = 0; i < navigationViewsForPath.length; i++) {\n        const navigationEntry = navigationViewsForPath[i];\n\n        if (navigationEntry.type === \"collection\") {\n            lastCollectionPath = navigationEntry.path;\n        }\n\n        if (i > 0) { // the first collection is handled by the main navigation\n            const previousEntry = navigationViewsForPath[i - 1];\n            if (navigationEntry.type === \"entity\") {\n                sidePanels.push({\n                        path: navigationEntry.path,\n                        entityId: navigationEntry.entityId,\n                        copy: false,\n                        width: navigationEntry.parentCollection?.sideDialogWidth\n                    }\n                );\n            } else if (navigationEntry.type === \"custom_view\") {\n                if (previousEntry.type === \"entity\") {\n                    const lastSidePanel: EntitySidePanelProps<any> = sidePanels[sidePanels.length - 1];\n                    if (lastSidePanel)\n                        lastSidePanel.selectedSubPath = navigationEntry.view.key;\n                }\n            } else if (navigationEntry.type === \"collection\") {\n                if (previousEntry.type === \"entity\") {\n                    const lastSidePanel: EntitySidePanelProps<any> = sidePanels[sidePanels.length - 1];\n                    if (lastSidePanel)\n                        lastSidePanel.selectedSubPath = navigationEntry.collection.id ?? navigationEntry.collection.path;\n                }\n            }\n        }\n\n    }\n\n    if (newFlag) {\n        sidePanels.push({\n            path: lastCollectionPath,\n            copy: false\n        });\n    }\n\n    return sidePanels;\n}\n\nconst propsToSidePanel = (props: EntitySidePanelProps<any>,\n                          buildUrlCollectionPath: (path: string) => string,\n                          resolveAliasesFrom: (pathWithAliases: string) => string,\n                          smallLayout: boolean): SideDialogPanelProps => {\n\n        const collectionPath = removeInitialAndTrailingSlashes(props.path);\n\n        const newPath = props.entityId\n            ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}/${props.selectedSubPath || \"\"}`)\n            : buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);\n        const resolvedPath = resolveAliasesFrom(props.path);\n\n        const resolvedPanelProps: EntitySidePanelProps<any> = {\n            ...props,\n            path: resolvedPath,\n        };\n\n        return {\n            key: `${props.path}/${props.entityId}`,\n            component: <EntitySidePanel {...resolvedPanelProps}/>,\n            urlPath: newPath,\n            parentUrlPath: buildUrlCollectionPath(collectionPath),\n            width: getEntityViewWidth(props, smallLayout),\n            onClose: props.onClose\n        };\n    }\n;\n","import { useEffect, useRef, useState } from \"react\";\nimport { AuthController, FireCMSPlugin } from \"../types\";\n\nexport const DEFAULT_SERVER_DEV = \"https://api-kdoe6pj3qq-ey.a.run.app\";\nexport const DEFAULT_SERVER = \"https://api-drplyi3b6q-ey.a.run.app\";\n\nexport type AccessResponse = {\n    blocked?: boolean;\n    message?: string;\n}\n\nasync function makeRequest(authController: AuthController, pluginKeys: string[] | undefined) {\n    const firebaseToken = await authController.getAuthToken();\n    return fetch(DEFAULT_SERVER + \"/access_log\",\n        {\n            // mode: \"no-cors\",\n            method: \"POST\",\n            headers: {\n                \"Content-Type\": \"application/json\",\n                Authorization: `Basic ${firebaseToken}`,\n            },\n            body: JSON.stringify({ plugins: pluginKeys })\n        })\n        .then(async (res) => {\n            return res.json();\n        });\n}\n\nexport function useProjectLog(authController: AuthController,\n                              plugins?: FireCMSPlugin<any, any, any>[]): AccessResponse | null {\n    const [accessResponse, setAccessResponse] = useState<AccessResponse | null>(null);\n    const accessedUserRef = useRef<string | null>(null);\n    const pluginKeys = plugins?.map(plugin => plugin.key);\n    useEffect(() => {\n        if (authController.user && authController.user.uid !== accessedUserRef.current && !authController.initialLoading) {\n            makeRequest(authController, pluginKeys).then(setAccessResponse);\n            accessedUserRef.current = authController.user.uid;\n        }\n    }, [authController, pluginKeys]);\n    return accessResponse;\n}\n","import React, { useMemo } from \"react\";\n\nimport { CustomizationController, EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from \"../types\";\nimport { AuthControllerContext, ModeControllerContext } from \"../contexts\";\nimport { useBuildSideEntityController } from \"../internal/useBuildSideEntityController\";\nimport { useCustomizationController, useFireCMSContext, useModeController } from \"../hooks\";\nimport { useBuildSideDialogsController } from \"../internal/useBuildSideDialogsController\";\nimport { ErrorView } from \"../components\";\nimport { StorageSourceContext } from \"../contexts/StorageSourceContext\";\nimport { UserConfigurationPersistenceContext } from \"../contexts/UserConfigurationPersistenceContext\";\nimport { DataSourceContext } from \"../contexts/DataSourceContext\";\nimport { SideEntityControllerContext } from \"../contexts/SideEntityControllerContext\";\nimport { NavigationContext } from \"../contexts/NavigationContext\";\nimport { SideDialogsControllerContext } from \"../contexts/SideDialogsControllerContext\";\nimport { CenteredView, Typography, useLocaleConfig } from \"@firecms/ui\";\nimport { DialogsProvider } from \"../contexts/DialogsProvider\";\nimport { useBuildDataSource } from \"../internal/useBuildDataSource\";\nimport { CustomizationControllerContext } from \"../contexts/CustomizationControllerContext\";\nimport { AnalyticsContext } from \"../contexts/AnalyticsContext\";\nimport { useProjectLog } from \"../hooks/useProjectLog\";\n\n/**\n * If you are using independent components of the CMS\n * you need to wrap them with this main component, so the internal hooks work.\n *\n * This is the main component of FireCMS. It acts as the provider of all the\n * internal contexts and hooks.\n *\n * You only need to use this component if you are building a custom app.\n *\n * @constructor\n * @group Core\n */\nexport function FireCMS<UserType extends User, EC extends EntityCollection>(props: FireCMSProps<UserType, EC>) {\n\n    const modeController = useModeController();\n    const {\n        children,\n        entityLinkBuilder,\n        userConfigPersistence,\n        dateTimeFormat,\n        locale,\n        authController,\n        storageSource,\n        dataSourceDelegate,\n        plugins,\n        onAnalyticsEvent,\n        propertyConfigs,\n        entityViews,\n        components,\n        navigationController,\n    } = props;\n\n    useLocaleConfig(locale);\n\n    /**\n     * Controller in charge of fetching and persisting data\n     */\n    const dataSource = useBuildDataSource({\n        delegate: dataSourceDelegate,\n        propertyConfigs,\n        navigationController\n    });\n\n    const sideDialogsController = useBuildSideDialogsController();\n    const sideEntityController = useBuildSideEntityController(navigationController, sideDialogsController);\n\n    const pluginsLoading = plugins?.some(p => p.loading) ?? false;\n\n    const loading = authController.initialLoading || navigationController.loading || pluginsLoading;\n\n    const customizationController: CustomizationController = {\n        dateTimeFormat,\n        locale,\n        entityLinkBuilder,\n        plugins,\n        entityViews: entityViews ?? [],\n        propertyConfigs: propertyConfigs ?? {},\n        components\n    };\n\n    const analyticsController = useMemo(() => ({\n        onAnalyticsEvent\n    }), []);\n\n    const accessResponse = useProjectLog(authController, plugins);\n\n    if (navigationController.navigationLoadingError) {\n        return (\n            <CenteredView maxWidth={\"md\"}>\n                <ErrorView\n                    title={\"Error loading navigation\"}\n                    error={navigationController.navigationLoadingError}/>\n            </CenteredView>\n        );\n    }\n\n    if (authController.authError) {\n        return (\n            <CenteredView maxWidth={\"md\"}>\n                <ErrorView\n                    title={\"Error loading auth\"}\n                    error={authController.authError}/>\n            </CenteredView>\n        );\n    }\n\n    if (accessResponse?.blocked) {\n        return (\n            <CenteredView maxWidth={\"md\"} fullScreen={true}>\n                <Typography variant={\"h4\"}>\n                    Access blocked\n                </Typography>\n                <Typography>\n                    This app has been blocked. Please reach out at <a\n                    href={\"mailto:hello@firecms.co\"}>hello@firecms.co</a> for more information.\n                </Typography>\n                {accessResponse?.message &&\n                    <Typography>Response from the server: {accessResponse?.message}</Typography>}\n            </CenteredView>\n        );\n    }\n\n    return (\n        <ModeControllerContext.Provider value={modeController}>\n            <AnalyticsContext.Provider value={analyticsController}>\n                <CustomizationControllerContext.Provider value={customizationController}>\n                    <UserConfigurationPersistenceContext.Provider\n                        value={userConfigPersistence}>\n                        <StorageSourceContext.Provider\n                            value={storageSource}>\n                            <DataSourceContext.Provider\n                                value={dataSource}>\n                                <AuthControllerContext.Provider\n                                    value={authController}>\n                                    <SideDialogsControllerContext.Provider\n                                        value={sideDialogsController}>\n                                        <SideEntityControllerContext.Provider\n                                            value={sideEntityController}>\n                                            <NavigationContext.Provider\n                                                value={navigationController}>\n                                                <DialogsProvider>\n                                                    <FireCMSInternal\n                                                        loading={loading}>\n                                                        {children}\n                                                    </FireCMSInternal>\n                                                </DialogsProvider>\n                                            </NavigationContext.Provider>\n                                        </SideEntityControllerContext.Provider>\n                                    </SideDialogsControllerContext.Provider>\n                                </AuthControllerContext.Provider>\n                            </DataSourceContext.Provider>\n                        </StorageSourceContext.Provider>\n                    </UserConfigurationPersistenceContext.Provider>\n                </CustomizationControllerContext.Provider>\n            </AnalyticsContext.Provider>\n        </ModeControllerContext.Provider>\n    );\n\n}\n\nfunction FireCMSInternal({\n                             loading,\n                             children\n                         }: {\n    loading: boolean;\n    children: (props: {\n        context: FireCMSContext;\n        loading: boolean;\n    }) => React.ReactNode;\n}) {\n\n    const context = useFireCMSContext();\n    const customizationController = useCustomizationController();\n\n    let childrenResult = children({\n        context,\n        loading\n    });\n\n    const plugins = customizationController.plugins;\n    if (!loading && plugins) {\n        plugins.forEach((plugin: FireCMSPlugin) => {\n            if (plugin.provider) {\n                childrenResult = (\n                    <plugin.provider.Component {...plugin.provider.props}\n                                               context={context}>\n                        {childrenResult}\n                    </plugin.provider.Component>\n                );\n            }\n        });\n    }\n\n    return <>{childrenResult}</>;\n}\n","import React from \"react\";\n\nimport { NavLink } from \"react-router-dom\";\nimport { cn, Tooltip } from \"@firecms/ui\";\n\nexport function DrawerNavigationItem({\n                                         name,\n                                         icon,\n                                         drawerOpen,\n                                         tooltipsOpen,\n                                         url,\n                                         onClick\n                                     }: {\n    icon: React.ReactElement,\n    name: string,\n    tooltipsOpen: boolean,\n    drawerOpen: boolean,\n    url: string,\n    onClick?: () => void,\n}) {\n\n    const iconWrap = <div\n        className={\"text-gray-600 dark:text-gray-500\"}>\n        {icon}\n    </div>;\n\n    const listItem = <NavLink\n        onClick={onClick}\n        style={{\n            width: !drawerOpen ? \"72px\" : \"280px\",\n            transition: drawerOpen ? \"width 150ms ease-in\" : undefined\n        }}\n        className={({ isActive }: any) => cn(\"rounded-r-lg truncate\",\n            \"hover:bg-slate-300 hover:bg-opacity-75 dark:hover:bg-gray-700 dark:hover:bg-opacity-75 text-gray-800 dark:text-gray-200 hover:text-gray-900 hover:dark:text-white\",\n            \"flex flex-row items-center mr-8\",\n            // \"transition-all ease-in-out delay-100 duration-300\",\n            // drawerOpen ? \"w-full\" : \"w-18\",\n            drawerOpen ? \"pl-8 h-12\" : \"pl-6 h-11\",\n            \"font-medium text-sm\",\n            isActive ? \"bg-slate-200 bg-opacity-60 dark:bg-gray-800 dark:bg-opacity-30\" : \"\"\n        )}\n        to={url}\n    >\n\n        {iconWrap}\n\n        <div\n            className={cn(\n                drawerOpen ? \"opacity-100\" : \"opacity-0 hidden\",\n                \"ml-4 font-inherit text-inherit\"\n            )}>\n            {name.toUpperCase()}\n        </div>\n    </NavLink>;\n\n    return <Tooltip\n        open={drawerOpen ? false : tooltipsOpen}\n        side=\"right\"\n        title={name}>\n        {listItem}\n    </Tooltip>;\n}\n","import React, { useCallback } from \"react\";\n\nimport { useLargeLayout, useNavigationController } from \"../hooks\";\n\nimport { useNavigate } from \"react-router-dom\";\nimport { CMSAnalyticsEvent, TopNavigationEntry, TopNavigationResult } from \"../types\";\nimport { IconForView } from \"../util\";\nimport { cn, IconButton, Menu, MenuItem, MoreVertIcon, Tooltip, Typography } from \"@firecms/ui\";\nimport { useAnalyticsController } from \"../hooks/useAnalyticsController\";\nimport { useDrawer } from \"./Scaffold\";\nimport { DrawerNavigationItem } from \"./DrawerNavigationItem\";\n\n/**\n * Props used in case you need to override the default drawer\n * @group Core\n */\nexport type DrawerProps = {\n    hovered: boolean,\n    drawerOpen: boolean,\n    openDrawer: () => void,\n    closeDrawer: () => void,\n    autoOpenDrawer?: boolean\n}\n\n/**\n * Default drawer used in the CMS\n * @group Core\n */\nexport function Drawer() {\n\n    const {\n        hovered,\n        drawerOpen,\n        closeDrawer,\n    } = useDrawer();\n\n    const analyticsController = useAnalyticsController();\n    const navigation = useNavigationController();\n\n    const tooltipsOpen = hovered && !drawerOpen;\n    const largeLayout = useLargeLayout();\n    const navigate = useNavigate();\n\n    const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);\n\n    if (!navigation.topLevelNavigation)\n        throw Error(\"Navigation not ready in Drawer\");\n\n    const {\n        navigationEntries,\n        groups\n    }: TopNavigationResult = navigation.topLevelNavigation;\n\n    const adminViews = navigationEntries.filter(e => e.type === \"admin\") ?? [];\n    const groupsWithoutAdmin = groups.filter(g => g !== \"Admin\");\n\n    const buildGroupHeader = useCallback((group?: string) => {\n        if (!drawerOpen) return <div className=\"h-12 w-full\"/>;\n        return <div\n            className=\"pt-8 pl-6 pr-8 pb-2 flex flex-row items-center\">\n            <Typography variant={\"caption\"}\n                        color={\"secondary\"}\n                        className=\"font-medium flex-grow line-clamp-1\">\n                {group ? group.toUpperCase() : \"Views\".toUpperCase()}\n            </Typography>\n\n        </div>;\n    }, [drawerOpen]);\n\n    const onClick = (view: TopNavigationEntry) => {\n        const eventName: CMSAnalyticsEvent = view.type === \"collection\"\n            ? \"drawer_navigate_to_collection\"\n            : (view.type === \"view\" ? \"drawer_navigate_to_view\" : \"unmapped_event\");\n        analyticsController.onAnalyticsEvent?.(eventName, { url: view.url });\n        if (!largeLayout)\n            closeDrawer();\n    };\n\n    return (\n        <>\n\n            <div className={\"flex-grow overflow-scroll no-scrollbar\"}>\n\n                {groupsWithoutAdmin.map((group) => (\n                    <React.Fragment\n                        key={`drawer_group_${group}`}>\n                        {buildGroupHeader(group)}\n                        {Object.values(navigationEntries)\n                            .filter(e => e.group === group)\n                            .map((view, index) =>\n                                <DrawerNavigationItem\n                                    key={`navigation_${index}`}\n                                    icon={<IconForView collectionOrView={view.collection ?? view.view}/>}\n                                    tooltipsOpen={tooltipsOpen}\n                                    drawerOpen={drawerOpen}\n                                    onClick={() => onClick(view)}\n                                    url={view.url}\n                                    name={view.name}/>)}\n                    </React.Fragment>\n                ))}\n\n            </div>\n\n            {adminViews.length > 0 && <Menu\n                open={adminMenuOpen}\n                onOpenChange={setAdminMenuOpen}\n                trigger={\n                    <IconButton\n                        shape={\"square\"}\n                        className={\"m-4 text-gray-900 dark:text-white w-fit\"}>\n                        <Tooltip title={\"Admin\"}\n                                 open={tooltipsOpen}\n                                 side={\"right\"} sideOffset={28}>\n                            <MoreVertIcon/>\n                        </Tooltip>\n                        {drawerOpen && <div\n                            className={cn(\n                                drawerOpen ? \"opacity-100\" : \"opacity-0 hidden\",\n                                \"mx-4 font-inherit text-inherit\"\n                            )}>\n                            ADMIN\n                        </div>}\n                    </IconButton>}\n            >\n                {adminViews.map((entry, index) =>\n                    <MenuItem\n                        onClick={(event) => {\n                            event.preventDefault();\n                            navigate(entry.path);\n                        }}\n                        key={`navigation_${index}`}>\n                        {<IconForView collectionOrView={entry.view}/>}\n                        {entry.name}\n                    </MenuItem>)}\n\n            </Menu>}\n        </>\n    );\n}\n","import React, { PropsWithChildren, useCallback } from \"react\";\nimport equal from \"react-fast-compare\"\nimport { Link } from \"react-router-dom\";\n\nimport { Drawer as DefaultDrawer, DrawerProps } from \"./Drawer\";\nimport { useLargeLayout, useNavigationController } from \"../hooks\";\nimport { ErrorBoundary, FireCMSAppBar as DefaultFireCMSAppBar, FireCMSAppBarProps, FireCMSLogo } from \"../components\";\nimport { ChevronLeftIcon, cn, defaultBorderMixin, IconButton, MenuIcon, Sheet, Tooltip } from \"@firecms/ui\";\n\nexport const DRAWER_WIDTH = 280;\n\nconst DrawerContext = React.createContext<DrawerProps>({\n    hovered: false,\n    drawerOpen: false,\n    openDrawer: () => {\n        throw new Error(\"openDrawer not implemented\");\n    },\n    closeDrawer: () => {\n        throw new Error(\"closeDrawer not implemented\");\n    },\n    autoOpenDrawer: false\n});\n\nexport function useDrawer() {\n    return React.useContext(DrawerContext);\n}\n\n/**\n * @group Core\n */\nexport interface ScaffoldProps<ExtraAppbarProps = object> {\n\n    /**\n     * Name of the app, displayed as the main title and in the tab title\n     */\n    name: React.ReactNode;\n\n    /**\n     * Logo to be displayed in the drawer of the CMS\n     */\n    logo?: string;\n\n    /**\n     * Whether to include the drawer in the scaffold\n     */\n    includeDrawer?: boolean;\n\n    /**\n     * You can define a custom drawer to be displayed in the scaffold.\n     * Use the hook `useDrawer` to access the context values.\n     */\n    drawer?: React.ReactNode;\n\n    /**\n     * Open the drawer on hover\n     */\n    autoOpenDrawer?: boolean;\n\n    /**\n     * A component that gets rendered on the upper side of the main toolbar.\n     * `toolbarExtraWidget` has no effect if this is set.\n     */\n    FireCMSAppBar?: React.ComponentType<FireCMSAppBarProps<ExtraAppbarProps>>;\n\n    /**\n     * Additional props passed to the custom AppBar\n     */\n    fireCMSAppBarProps?: Partial<FireCMSAppBarProps> & ExtraAppbarProps;\n\n}\n\n/**\n * This view acts as a scaffold for FireCMS.\n *\n * It is in charge of displaying the navigation drawer, top bar and main\n * collection views.\n * This component needs a parent {@link FireCMS}\n *\n * @param props\n * @constructor\n * @group Core\n */\nexport const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(\n    function Scaffold(props: PropsWithChildren<ScaffoldProps>) {\n\n        const {\n            children,\n            name,\n            logo,\n            includeDrawer = true,\n            autoOpenDrawer,\n            drawer = <DefaultDrawer/>,\n            FireCMSAppBar = DefaultFireCMSAppBar,\n            fireCMSAppBarProps,\n        } = props;\n\n        const largeLayout = useLargeLayout();\n\n        const [drawerOpen, setDrawerOpen] = React.useState(false);\n        const [onHover, setOnHover] = React.useState(false);\n\n        const setOnHoverTrue = useCallback(() => setOnHover(true), []);\n        const setOnHoverFalse = useCallback(() => setOnHover(false), []);\n\n        const handleDrawerOpen = useCallback(() => {\n            setDrawerOpen(true);\n        }, []);\n\n        const handleDrawerClose = useCallback(() => {\n            setDrawerOpen(false);\n        }, []);\n\n        const computedDrawerOpen: boolean = drawerOpen || Boolean(largeLayout && autoOpenDrawer && onHover);\n\n        return (\n            <DrawerContext.Provider value={{\n                hovered: onHover,\n                drawerOpen: computedDrawerOpen,\n                closeDrawer: handleDrawerClose,\n                openDrawer: handleDrawerOpen,\n                autoOpenDrawer\n            }}>\n                <div\n                    className=\"flex h-screen w-screen bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white overflow-hidden\"\n                    style={{\n                        paddingTop: \"env(safe-area-inset-top)\",\n                        paddingLeft: \"env(safe-area-inset-left)\",\n                        paddingRight: \"env(safe-area-inset-right)\",\n                        paddingBottom: \"env(safe-area-inset-bottom)\",\n                        height: \"100dvh\"\n                    }}>\n\n                    <FireCMSAppBar title={name}\n                                   includeDrawer={includeDrawer}\n                                   logo={logo}\n                                   drawerOpen={computedDrawerOpen}\n                                   {...fireCMSAppBarProps}/>\n                    <DrawerWrapper\n                        displayed={includeDrawer}\n                        onMouseEnter={setOnHoverTrue}\n                        onMouseMove={setOnHoverTrue}\n                        onMouseLeave={setOnHoverFalse}\n                        open={computedDrawerOpen}\n                        logo={logo}\n                        hovered={onHover}\n                        setDrawerOpen={setDrawerOpen}>\n                        {includeDrawer && drawer}\n                    </DrawerWrapper>\n\n                    <main\n                        className=\"flex flex-col flex-grow overflow-auto\">\n                        <DrawerHeader/>\n                        <div\n                            className={cn(defaultBorderMixin, \"flex-grow overflow-auto lg:m-0 lg:mx-4 lg:mb-4 lg:rounded-lg lg:border lg:border-solid m-0 mt-1\")}>\n\n                            <ErrorBoundary>\n                                {children}\n                            </ErrorBoundary>\n\n                        </div>\n                    </main>\n                </div>\n            </DrawerContext.Provider>\n        );\n    },\n    equal\n)\n\nconst DrawerHeader = () => {\n    return (\n        <div className=\"flex flex-col min-h-[68px]\"></div>\n    );\n};\n\nfunction DrawerWrapper(props: {\n    children: React.ReactNode,\n    displayed: boolean,\n    open: boolean,\n    logo?: string,\n    hovered: boolean,\n    setDrawerOpen: (open: boolean) => void,\n    onMouseEnter: () => void,\n    onMouseMove: () => void,\n    onMouseLeave: () => void\n}) {\n\n    const navigation = useNavigationController();\n\n    const width = !props.displayed ? 0 : (props.open ? DRAWER_WIDTH : 72);\n    const innerDrawer = <div\n        className={\"relative h-full no-scrollbar overflow-y-auto overflow-x-hidden\"}\n        style={{\n            width,\n            transition: \"left 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, opacity 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, width 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms\"\n        }}\n    >\n\n        {!props.open && props.displayed && (\n            <Tooltip title=\"Open menu\"\n                     side=\"right\"\n                     sideOffset={12}\n                     className=\"fixed top-2 left-3 !bg-gray-50 dark:!bg-gray-900 rounded-full w-fit\"\n            >\n                <IconButton\n                    color=\"inherit\"\n                    aria-label=\"Open menu\"\n                    className=\"sticky top-2 left-3 \"\n                    onClick={() => props.setDrawerOpen(true)}\n                    size=\"large\"\n                >\n                    <MenuIcon/>\n                </IconButton>\n            </Tooltip>\n        )}\n\n        <div className={\"flex flex-col h-full\"}>\n            <div\n                style={{\n                    transition: \"padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms\",\n                    padding: props.open ? \"32px 144px 0px 24px\" : \"72px 16px 0px\"\n                }}\n                className={cn(\"cursor-pointer\")}>\n\n                <Tooltip title={\"Home\"}\n                         sideOffset={20}\n                         side=\"right\">\n                    <Link\n                        to={navigation.basePath}>\n                        {props.logo\n                            ? <img src={props.logo}\n                                   alt=\"Logo\"\n                                   className={cn(\"max-w-full max-h-full\",\n                                       props.open ?? \"w-[112px] h-[112px]\")}/>\n                            : <FireCMSLogo/>}\n\n                    </Link>\n                </Tooltip>\n            </div>\n\n            {props.children}\n        </div>\n\n    </div>;\n\n    const largeLayout = useLargeLayout();\n    if (!largeLayout) {\n        if (!props.displayed)\n            return null;\n        return <>\n            <IconButton\n                color=\"inherit\"\n                aria-label=\"Open drawer\"\n                onClick={() => props.setDrawerOpen(true)}\n                size=\"large\"\n                className=\"absolute top-2 left-6\"\n            >\n                <MenuIcon/>\n            </IconButton>\n            <Sheet side={\"left\"}\n                   transparent={true}\n                   open={props.open}\n                   onOpenChange={props.setDrawerOpen}\n            >\n                {innerDrawer}\n            </Sheet>\n        </>;\n    }\n\n    return (\n        <div\n            className=\"relative\"\n            onMouseEnter={props.onMouseEnter}\n            onMouseMove={props.onMouseMove}\n            onMouseLeave={props.onMouseLeave}\n            style={{\n                width,\n                transition: \"left 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, opacity 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, width 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms\"\n            }}>\n\n            {innerDrawer}\n\n            <div\n                className={`absolute right-0 top-4 ${\n                    props.open ? \"opacity-100\" : \"opacity-0 invisible\"\n                } transition-opacity duration-1000 ease-in-out`}>\n                <IconButton\n                    aria-label=\"Close drawer\"\n                    onClick={() => props.setDrawerOpen(false)}\n                >\n                    <ChevronLeftIcon/>\n                </IconButton>\n            </div>\n\n        </div>\n    );\n}\n","import React from \"react\";\n\nimport { Route, Routes, useLocation } from \"react-router-dom\";\nimport { CMSView } from \"../types\";\nimport { DefaultHomePage, EntityCollectionView, ErrorBoundary, NotFoundPage } from \"../components\";\nimport { useNavigationController } from \"../hooks\";\nimport { toArray } from \"../util/arrays\";\n\n/**\n * @group Components\n */\nexport type NavigationRoutesProps = {\n    /**\n     * In case you need to override the home page\n     */\n    homePage?: React.ReactNode;\n\n    customRoutes?: React.ReactNode[]\n\n};\n\n/**\n * This component is in charge of rendering\n * all the related routes (entity collection root views, custom views\n * or the home route) related to a {@link NavigationController}.\n * This component needs a parent {@link FireCMS}\n *\n * @constructor\n * @group Components\n */\nexport const NavigationRoutes = React.memo<NavigationRoutesProps>(\n    function NavigationRoutes({\n                                  homePage = <DefaultHomePage/>,\n                                  customRoutes\n                              }: NavigationRoutesProps) {\n\n        const location = useLocation();\n        const navigation = useNavigationController();\n\n        if (!navigation)\n            return <></>;\n\n        const state = location.state as any;\n\n        /**\n         * The location can be overridden if `base_location` is set in the\n         * state field of the current location. This can happen if you open\n         * a side entity, like `products`, from a different one, like `users`\n         */\n        const baseLocation = state && state.base_location ? state.base_location : location;\n\n        const cmsViews: React.ReactNode[] = [];\n        if (navigation.views) {\n            navigation.views.forEach((cmsView) => {\n                if (Array.isArray(cmsView.path))\n                    cmsViews.push(...cmsView.path.map(path => buildCMSViewRoute(path, cmsView)));\n                else\n                    cmsViews.push(buildCMSViewRoute(cmsView.path, cmsView));\n            });\n        }\n        if (navigation.adminViews) {\n            navigation.adminViews.forEach((cmsView) => {\n                if (Array.isArray(cmsView.path))\n                    cmsViews.push(...cmsView.path.map(path => buildCMSViewRoute(path, cmsView)));\n                else\n                    cmsViews.push(buildCMSViewRoute(cmsView.path, cmsView));\n            });\n        }\n\n        // we reorder collections so that nested paths are included first\n        const sortedCollections = [...(navigation.collections ?? [])]\n            .sort((a, b) => b.path.length - a.path.length);\n\n        const collectionRoutes = sortedCollections\n            .map((collection) => {\n                    const urlPath = navigation.buildUrlCollectionPath(collection.id ?? collection.path);\n                    return <Route path={urlPath + \"/*\"}\n                                  key={`navigation_${collection.id ?? collection.path}`}\n                                  element={\n                                      <ErrorBoundary>\n                                          <EntityCollectionView\n                                              key={`collection_view_${collection.id ?? collection.path}`}\n                                              isSubCollection={false}\n                                              parentCollectionIds={[]}\n                                              fullPath={collection.id ?? collection.path}\n                                              {...collection}\n                                              Actions={toArray(collection.Actions)}/>\n                                      </ErrorBoundary>\n                                  }/>;\n                }\n            );\n\n        const homeRoute = (\n            <Route path={\"/\"}\n                   element={homePage}/>\n        );\n\n        const notFoundRoute = <Route path={\"*\"}\n                                     element={\n                                         <NotFoundPage/>\n                                     }/>;\n\n        return (\n            <Routes location={baseLocation}>\n\n                {collectionRoutes}\n\n                {cmsViews}\n\n                {homeRoute}\n\n                {notFoundRoute}\n\n                {customRoutes}\n\n            </Routes>\n        );\n    });\n\nconst buildCMSViewRoute = (path: string, cmsView: CMSView) => {\n    return <Route\n        key={\"navigation_view_\" + path}\n        path={path}\n        element={cmsView.view}\n    />;\n};\n","import React from \"react\";\nimport { ErrorBoundary } from \"../../components\";\nimport { useCustomizationController } from \"../../hooks\";\nimport { PropertyPreviewProps } from \"../PropertyPreviewProps\";\nimport { PropertyPreview } from \"../PropertyPreview\";\nimport { resolveArrayProperty } from \"../../util\";\n\n/**\n * @group Preview components\n */\nexport function ArrayOfMapsPreview({\n                                       propertyKey,\n                                       value,\n                                       property: inputProperty,\n                                       size,\n                                       // entity\n                                   }: PropertyPreviewProps<Record<string, any>[]>) {\n\n    const customizationController = useCustomizationController();\n    const property = resolveArrayProperty({\n        propertyKey,\n        property: inputProperty,\n        fields: customizationController.propertyConfigs\n    });\n\n    if (Array.isArray(property?.of)) {\n        throw Error(\"Using array properties instead of single one in `of` in ArrayProperty\");\n    }\n\n    if (property?.dataType !== \"array\" || !property.of || property.of.dataType !== \"map\")\n        throw Error(\"Picked wrong preview component ArrayOfMapsPreview\");\n\n    const mapProperty = property.of;\n    const properties = mapProperty.properties;\n    if (!properties) {\n        throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${propertyKey}`);\n    }\n    const values = value;\n    const previewProperties: string[] | undefined = mapProperty.previewProperties;\n\n    if (!values) return null;\n\n    let mapProperties = previewProperties;\n    if (!mapProperties || !mapProperties.length) {\n        mapProperties = Object.keys(properties);\n        if (size)\n            mapProperties = mapProperties.slice(0, 3);\n    }\n\n    return (\n        <div className=\"table-auto text-xs\">\n            <div>\n                {values &&\n                    values.map((v, index) => {\n                        return (\n                            <div key={`table_${v}_${index}`}\n                                 className=\"border-b last:border-b-0\">\n                                {mapProperties && mapProperties.map(\n                                    (key) => (\n                                        <div\n                                            key={`table-cell-${key as string}`}\n                                            className=\"table-cell\"\n                                        >\n                                            <ErrorBoundary>\n                                                <PropertyPreview\n                                                    propertyKey={key as string}\n                                                    value={(v)[key]}\n                                                    property={properties[key as string]}\n                                                    // entity={entity}\n                                                    size={\"small\"}/>\n                                            </ErrorBoundary>\n                                        </div>\n                                    )\n                                )}\n                            </div>\n                        );\n                    })}\n            </div>\n        </div>\n    );\n}\n","import React from \"react\";\n\nimport { Button, Dialog, DialogActions, DialogContent, LoadingButton, Typography } from \"@firecms/ui\";\n\nexport function DeleteConfirmationDialog({\n                                             open,\n                                             onAccept,\n                                             onCancel,\n                                             title,\n                                             loading,\n                                             body\n                                         }: {\n    open: boolean,\n    onAccept: () => void,\n    onCancel: () => void,\n    loading?: boolean,\n    title: React.ReactNode,\n    body?: React.ReactNode,\n}) {\n    return (\n        <Dialog\n            open={open}\n            onOpenChange={(open) => !open ? onCancel() : undefined}\n        >\n            <DialogContent>\n                <Typography variant={\"h6\"} className={\"mb-2\"}>{title}</Typography>\n                {body}\n            </DialogContent>\n\n            <DialogActions>\n                <Button\n                    variant={\"text\"}\n                    onClick={onCancel}\n                    autoFocus>Cancel</Button>\n\n                <LoadingButton\n                    color=\"primary\"\n                    type=\"submit\"\n                    loading={loading}\n                    onClick={onAccept}\n                >\n                    Ok\n                </LoadingButton>\n            </DialogActions>\n        </Dialog>\n    );\n}\n","import React from \"react\";\nimport { Typography } from \"@firecms/ui\";\n\nexport function FieldCaption({\n                                    error,\n                                    children\n                                }: { error?: boolean, children?: React.ReactNode }) {\n    if (!children) return null;\n    return (\n        <Typography variant={\"caption\"} color={error ? \"error\" : \"secondary\"} className={\"ml-3.5 mt-0.5\"}>\n            {children}\n        </Typography>\n    );\n}\n","import { useCallback } from \"react\";\nimport {\n    DataSource,\n    DataSourceDelegate,\n    DeleteEntityProps,\n    Entity,\n    EntityCollection,\n    EntityValues,\n    FetchCollectionProps,\n    FetchEntityProps,\n    FilterValues,\n    ListenCollectionProps,\n    ListenEntityProps,\n    NavigationController,\n    PropertyConfig,\n    ResolvedProperties,\n    SaveEntityProps\n} from \"../types\";\nimport { resolveCollection, updateDateAutoValues } from \"../util\";\n\n/**\n * Use this hook to build a {@link DataSource} based on Firestore\n * @param firebaseApp\n * @group Firebase\n */\nexport function useBuildDataSource({\n                                       delegate,\n                                       propertyConfigs,\n                                       navigationController\n                                   }: {\n    delegate: DataSourceDelegate,\n    propertyConfigs?: Record<string, PropertyConfig>;\n    navigationController: NavigationController;\n}): DataSource {\n\n    return {\n\n        /**\n         * Fetch entities in a Firestore path\n         * @param path\n         * @param collection\n         * @param filter\n         * @param limit\n         * @param startAfter\n         * @param searchString\n         * @param orderBy\n         * @param order\n         * @return Function to cancel subscription\n         * @see useCollectionFetch if you need this functionality implemented as a hook\n         * @group Firestore\n         */\n        fetchCollection: useCallback(<M extends Record<string, any>>({\n                                                                         path,\n                                                                         collection: collectionProp,\n                                                                         filter,\n                                                                         limit,\n                                                                         startAfter,\n                                                                         searchString,\n                                                                         orderBy,\n                                                                         order\n                                                                     }: FetchCollectionProps<M>\n        ): Promise<Entity<M>[]> => {\n            return delegate.fetchCollection<M>({\n                path,\n                filter,\n                limit,\n                startAfter,\n                searchString,\n                orderBy,\n                order\n            });\n        }, [delegate]),\n\n        /**\n         * Listen to a entities in a given path\n         * @param path\n         * @param collection\n         * @param onError\n         * @param filter\n         * @param limit\n         * @param startAfter\n         * @param searchString\n         * @param orderBy\n         * @param order\n         * @param onUpdate\n         * @return Function to cancel subscription\n         * @see useCollectionFetch if you need this functionality implemented as a hook\n         * @group Firestore\n         */\n        listenCollection: delegate.listenCollection\n            // eslint-disable-next-line react-hooks/rules-of-hooks\n            ? useCallback(<M extends Record<string, any>>(\n                {\n                    path,\n                    collection: collectionProp,\n                    filter,\n                    limit,\n                    startAfter,\n                    searchString,\n                    orderBy,\n                    order,\n                    onUpdate,\n                    onError\n                }: ListenCollectionProps<M>\n            ): () => void => {\n\n                const collection = collectionProp ?? navigationController.getCollection(path);\n                const isCollectionGroup = Boolean(collection?.collectionGroup) ?? false;\n                if (!delegate.listenCollection)\n                    throw Error(\"useBuildDataSource delegate not initialised\");\n\n                return delegate.listenCollection<M>({\n                    path,\n                    filter,\n                    limit,\n                    startAfter,\n                    searchString,\n                    orderBy,\n                    order,\n                    onUpdate,\n                    onError,\n                    isCollectionGroup,\n                    collection\n                });\n            }, [delegate, navigationController.getCollection])\n            : undefined,\n\n        /**\n         * Retrieve an entity given a path and a collection\n         * @param path\n         * @param entityId\n         * @param collection\n         * @group Firestore\n         */\n        fetchEntity: useCallback(<M extends Record<string, any>>({\n                                                                     path,\n                                                                     entityId\n                                                                 }: FetchEntityProps<M>\n        ): Promise<Entity<M> | undefined> => delegate.fetchEntity({\n            path,\n            entityId\n        }), [delegate]),\n\n        /**\n         *\n         * @param path\n         * @param entityId\n         * @param collection\n         * @param onUpdate\n         * @param onError\n         * @return Function to cancel subscription\n         * @group Firestore\n         */\n        listenEntity: delegate.listenEntity\n            // eslint-disable-next-line react-hooks/rules-of-hooks\n            ? useCallback(<M extends Record<string, any>>(\n                {\n                    path,\n                    entityId,\n                    collection,\n                    onUpdate,\n                    onError\n                }: ListenEntityProps<M>): () => void => {\n                if (!delegate.listenEntity)\n                    throw Error(\"useBuildDataSource delegate not initialised\");\n\n                return delegate.listenEntity<M>({\n                    path,\n                    entityId,\n                    onUpdate,\n                    onError\n                })\n            }, [delegate.listenEntity]) : undefined,\n\n        /**\n         * Save entity to the specified path. Note that Firestore does not allow\n         * undefined values.\n         * @param path\n         * @param entityId\n         * @param values\n         * @param schemaId\n         * @param collection\n         * @param status\n         * @group Firestore\n         */\n        saveEntity: useCallback(<M extends Record<string, any>>(\n            {\n                path,\n                entityId,\n                values,\n                collection: collectionProp,\n                status\n            }: SaveEntityProps<M>): Promise<Entity<M>> => {\n\n            const collection = collectionProp ?? navigationController.getCollection(path);\n\n            const resolvedCollection = collection\n                ? resolveCollection<M>({\n                    collection,\n                    path,\n                    entityId,\n                    fields: propertyConfigs\n                })\n                : undefined;\n\n            const properties: ResolvedProperties<M> | undefined = resolvedCollection?.properties;\n\n            const firestoreValues = delegate.cmsToDelegateModel(\n                values,\n            );\n\n            const updatedFirestoreValues: EntityValues<M> = properties\n                ? updateDateAutoValues(\n                    {\n                        inputValues: firestoreValues,\n                        properties,\n                        status,\n                        timestampNowValue: delegate.currentTime(),\n                        setDateToMidnight: delegate.setDateToMidnight\n                    })\n                : firestoreValues;\n\n            return delegate.saveEntity({\n                path,\n                entityId,\n                values: updatedFirestoreValues,\n                status\n            }).then((res) => {\n                return {\n                    id: res.id,\n                    path: res.path,\n                    values: delegate.delegateToCMSModel(updatedFirestoreValues)\n                } as Entity<M>;\n            });\n        }, [delegate.saveEntity, navigationController.getCollection]),\n\n        /**\n         * Delete an entity\n         * @param entity\n         * @param collection\n         * @group Firestore\n         */\n        deleteEntity: useCallback(<M extends Record<string, any>>(\n            {\n                entity\n            }: DeleteEntityProps<M>\n        ): Promise<void> => {\n            return delegate.deleteEntity({ entity });\n        }, [delegate.deleteEntity]),\n\n        /**\n         * Check if the given property is unique in the given collection\n         * @param path Collection path\n         * @param name of the property\n         * @param value\n         * @param property\n         * @param entityId\n         * @return `true` if there are no other fields besides the given entity\n         * @group Firestore\n         */\n        checkUniqueField: useCallback((\n            path: string,\n            name: string,\n            value: any,\n            entityId?: string\n        ): Promise<boolean> => {\n            return delegate.checkUniqueField(path, name, value, entityId);\n        }, [delegate.checkUniqueField]),\n\n        generateEntityId: useCallback((path: string): string => {\n            return delegate.generateEntityId(path,);\n        }, [delegate.generateEntityId]),\n\n        countEntities: delegate.countEntities ? async ({\n                                                           path,\n                                                           collection,\n                                                           filter,\n                                                           order,\n                                                           orderBy\n                                                       }: {\n            path: string,\n            collection: EntityCollection<any>,\n            filter?: FilterValues<Extract<keyof any, string>>,\n            orderBy?: string,\n            order?: \"desc\" | \"asc\",\n        }): Promise<number> => {\n            return delegate.countEntities!({\n                path,\n                filter,\n                orderBy,\n                order,\n                isCollectionGroup: Boolean(collection.collectionGroup) ?? false\n            });\n        } : undefined,\n\n        isFilterCombinationValid: useCallback(({\n                                                   path,\n                                                   filterValues,\n                                                   sortBy\n                                               }: {\n            path: string,\n            filterValues: FilterValues<any>,\n            sortBy?: [string, \"asc\" | \"desc\"]\n        }): boolean => {\n            if (!delegate.isFilterCombinationValid)\n                return true;\n            return delegate.isFilterCombinationValid(\n                {\n                    path,\n                    filterValues,\n                    sortBy\n                }\n            )\n        }, [delegate.isFilterCombinationValid]),\n\n    };\n\n}\n\n// /**\n//  * Recursive function that converts Firestore data types into CMS or plain\n//  * JS types.\n//  * FireCMS uses Javascript dates internally instead of Firestore timestamps.\n//  * This makes it easier to interact with the rest of the libraries and\n//  * bindings.\n//  * Also, Firestore references are replaced with {@link EntityReference}\n//  * @param data\n//  * @param buildReference\n//  * @param buildGeoPoint\n//  * @param buildDate\n//  * @param buildDelete\n//  * @group Firestore\n//  */\n// export function cmsToDelegateModel(data: any,\n//                                    buildReference: (reference: EntityReference) => any,\n//                                    buildGeoPoint: (geoPoint: GeoPoint) => any,\n//                                    buildDate: (date: Date) => any,\n//                                    buildDelete: () => any\n// ): any {\n//     if (data === undefined) {\n//         return buildDelete();\n//     } else if (data === null) {\n//         return null;\n//     } else if (Array.isArray(data)) {\n//         return data.map(v => cmsToDelegateModel(v, buildReference, buildGeoPoint, buildDate, buildDelete));\n//     } else if (data.isEntityReference && data.isEntityReference()) {\n//         return buildReference(data);\n//     } else if (data instanceof GeoPoint) {\n//         return buildGeoPoint(data);\n//     } else if (data instanceof Date) {\n//         return buildDate(data);\n//     } else if (data && typeof data === \"object\") {\n//         return Object.entries(data)\n//             .map(([key, v]) => ({ [key]: cmsToDelegateModel(v, buildReference, buildGeoPoint, buildDate, buildDelete) }))\n//             .reduce((a, b) => ({ ...a, ...b }), {});\n//     }\n//     return data;\n// }\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useLocation, useNavigate } from \"react-router-dom\";\nimport { SideDialogPanelProps, SideDialogsController } from \"../types\";\nimport equal from \"react-fast-compare\"\n\nexport function useBuildSideDialogsController(): SideDialogsController {\n\n    const location = useLocation();\n    const navigate = useNavigate();\n\n    const [sidePanels, setSidePanels] = useState<SideDialogPanelProps[]>([]);\n    const sidePanelsRef = useRef<SideDialogPanelProps[]>(sidePanels);\n\n    const routesStore = useRef<Record<string, SideDialogPanelProps>>({});\n    const routesCount = useRef<number>(0);\n\n    const updateSidePanels = (newPanels: SideDialogPanelProps[]) => {\n        sidePanelsRef.current = newPanels;\n        setSidePanels(newPanels);\n    };\n\n    useEffect(() => {\n        const state = location.state as any;\n        const panelKeys: string[] = state?.panels ?? [];\n        const newPanels = panelKeys\n            .map(key => routesStore.current[key])\n            .filter(p => Boolean(p)) as SideDialogPanelProps[];\n        if (!equal(sidePanelsRef.current.map(p => p.key), newPanels.map(p => p.key)))\n            updateSidePanels(newPanels);\n    }, [location]);\n\n    const close = useCallback(() => {\n\n        if (sidePanels.length === 0)\n            return;\n\n        const lastSidePanel = sidePanels[sidePanels.length - 1];\n        const updatedPanels = [...sidePanels.slice(0, -1)];\n        updateSidePanels(updatedPanels);\n\n        if (routesCount.current > 0) {\n            if (lastSidePanel.urlPath)\n                navigate(-1);\n            routesCount.current--;\n        } else if (lastSidePanel.parentUrlPath) {\n            const baseLocation = (location.state as any)?.base_location ?? location;\n            navigate(\n                lastSidePanel.parentUrlPath,\n                {\n                    replace: true,\n                    state: {\n                        base_location: baseLocation,\n                        panels: updatedPanels.map(p => p.key)\n                    }\n                }\n            );\n        }\n    }, [sidePanels, navigate, location]);\n\n    const open = useCallback((panelProps: SideDialogPanelProps | SideDialogPanelProps[]) => {\n\n        const newPanels: SideDialogPanelProps[] = Array.isArray(panelProps) ? panelProps : [panelProps];\n\n        newPanels.forEach((panel) => {\n            routesStore.current[panel.key] = panel;\n        });\n        routesCount.current = routesCount.current + newPanels.length;\n\n        const baseLocation = (location.state as any)?.base_location ?? location;\n\n        const updatedPanels = [...sidePanels, ...newPanels];\n        updateSidePanels(updatedPanels);\n\n        newPanels.forEach((panel) => {\n            if (panel.urlPath) {\n                navigate(\n                    panel.urlPath,\n                    {\n                        state: {\n                            base_location: baseLocation,\n                            panels: updatedPanels.map(p => p.key)\n                        }\n                    }\n                );\n            }\n        });\n\n    }, [location, navigate, sidePanels]);\n\n    const replace = useCallback((panelProps: SideDialogPanelProps | SideDialogPanelProps[]) => {\n\n        const newPanels: SideDialogPanelProps[] = Array.isArray(panelProps) ? panelProps : [panelProps];\n        newPanels.forEach((panel) => {\n            routesStore.current[panel.key] = panel;\n        });\n\n        const baseLocation = (location.state as any)?.base_location ?? location;\n\n        const updatedPanels = [...sidePanels.slice(0, -newPanels.length), ...newPanels];\n        updateSidePanels(updatedPanels);\n\n        newPanels.forEach((panel) => {\n            if (panel.urlPath) {\n                navigate(\n                    panel.urlPath,\n                    {\n                        replace: true,\n                        state: {\n                            base_location: baseLocation,\n                            panels: updatedPanels.map(p => p.key)\n                        }\n                    }\n                );\n            }\n        });\n\n    }, [location, navigate, sidePanels]);\n\n    return {\n        sidePanels,\n        close,\n        open,\n        replace\n    };\n}\n","import { getIconForWidget } from \"../util\";\nimport { PropertyConfig } from \"../types\";\nimport { getDefaultFieldConfig } from \"../core\";\n\nexport function PropertyConfigBadge({ propertyConfig }: { propertyConfig: PropertyConfig | undefined }): React.ReactNode {\n    const classes = \"h-8 w-8 p-1 rounded-full shadow text-white\";\n\n    const defaultPropertyConfig = typeof propertyConfig?.property === \"object\" ? getDefaultFieldConfig(propertyConfig.property) : undefined;\n\n    return <div\n        className={classes}\n        style={{\n            background: propertyConfig?.color ?? defaultPropertyConfig?.color ?? \"#888\"\n        }}>\n        {propertyConfig?.Icon ? getIconForWidget(propertyConfig, \"medium\") : getIconForWidget(defaultPropertyConfig, \"medium\")}\n    </div>\n}\n","import React, { useCallback, useMemo } from \"react\";\n\nimport { Entity, EntityCollection, EntityReference, FilterValues } from \"../types\";\nimport { getReferenceFrom } from \"../util\";\nimport { PreviewSize, ReferencePreview } from \"../preview\";\nimport { useNavigationController, useReferenceDialog } from \"../hooks\";\nimport { Button, cn } from \"@firecms/ui\";\n\nexport type ReferenceWidgetProps<M extends Record<string, any>> = {\n    name?: string,\n    multiselect?: boolean,\n    value: EntityReference | EntityReference[] | null,\n    onReferenceSelected?: (params: {\n        reference: EntityReference | null,\n        entity: Entity<M> | null\n    }) => void,\n    onMultipleReferenceSelected?: (params: {\n        references: EntityReference[] | null,\n        entities: Entity<M>[] | null\n    }) => void,\n    path: string,\n    disabled?: boolean,\n    previewProperties?: string[];\n    /**\n     * Allow selection of entities that pass the given filter only.\n     */\n    forceFilter?: FilterValues<string>;\n    size: PreviewSize;\n    className?: string;\n};\n\n/**\n * This field allows selecting reference/s.\n */\nexport function ReferenceWidget<M extends Record<string, any>>({\n                                                                   name,\n                                                                   multiselect = false,\n                                                                   path,\n                                                                   disabled,\n                                                                   value,\n                                                                   onReferenceSelected,\n                                                                   onMultipleReferenceSelected,\n                                                                   previewProperties,\n                                                                   forceFilter,\n                                                                   size,\n                                                                   className\n                                                               }: ReferenceWidgetProps<M>) {\n\n    const navigationController = useNavigationController();\n\n    const collection: EntityCollection | undefined = useMemo(() => {\n        return navigationController.getCollection(path);\n    }, [path, navigationController.getCollection]);\n\n    // if (!collection) {\n    //     throw Error(`Couldn't find the corresponding collection for the path: ${path}`);\n    // }\n\n    const onSingleEntitySelected = useCallback((entity: Entity<M> | null) => {\n        if (disabled)\n            return;\n        if (onReferenceSelected) {\n            const reference = entity ? getReferenceFrom(entity) : null;\n            onReferenceSelected?.({ reference, entity });\n        }\n    }, [disabled, onReferenceSelected]);\n\n    const onMultipleEntitiesSelected = useCallback((entities: Entity<M>[]) => {\n        if (disabled)\n            return;\n        if (onMultipleReferenceSelected) {\n            const references = entities ? entities.map(e => getReferenceFrom(e)) : null;\n            onMultipleReferenceSelected({ references, entities });\n        }\n    }, [disabled, onReferenceSelected]);\n\n    const referenceDialogController = useReferenceDialog({\n            multiselect,\n            path,\n            collection,\n            onSingleEntitySelected,\n            onMultipleEntitiesSelected,\n            forceFilter\n        }\n    );\n\n    const clearValue = useCallback((e: React.MouseEvent) => {\n        e.stopPropagation();\n        if (multiselect) {\n            onMultipleEntitiesSelected([]);\n        } else {\n            onSingleEntitySelected(null);\n        }\n    }, [onReferenceSelected]);\n\n    let child: React.ReactNode;\n\n    const onEntryClick = () => {\n        if (disabled)\n            return;\n        referenceDialogController.open();\n    };\n\n    if (Array.isArray(value)) {\n        child = <div className={\"flex flex-col gap-4\"}>\n            {value.map((ref, index) => {\n                return <ReferencePreview\n                    key={`reference_preview_${index}`}\n                    onClick={onEntryClick}\n                    reference={ref}\n                    disabled={disabled}\n                    previewProperties={previewProperties}\n                    size={size}/>\n            })}\n        </div>\n    } else if (value?.isEntityReference && value?.isEntityReference()) {\n        child = <ReferencePreview\n            reference={value}\n            onClick={onEntryClick}\n            disabled={disabled}\n            previewProperties={previewProperties}\n            size={size}/>\n\n    }\n    return <div className={cn(\"text-sm font-medium\",\n        \"min-w-80 flex flex-col gap-4\",\n        \"relative transition-colors duration-200 ease-in rounded font-medium\",\n        disabled ? \"bg-opacity-50\" : \"hover:bg-opacity-75\",\n        \"text-opacity-50 dark:text-white dark:text-opacity-50\",\n        className\n    )}\n    >\n\n        {child}\n        {!value && <div className=\"justify-center text-left\">\n            <Button variant=\"outlined\"\n                    color=\"primary\"\n                    disabled={disabled}\n                    onClick={onEntryClick}>\n                Edit {name}\n            </Button>\n        </div>}\n\n    </div>;\n}\n","import React, { PropsWithChildren } from \"react\";\nimport { SnackbarProvider as NotistackSnackbarProvider } from \"notistack\";\n\nexport const SnackbarProvider: React.FC<PropsWithChildren<{}>> = ({ children }) => {\n\n    return (\n        <NotistackSnackbarProvider maxSnack={3}\n                                   autoHideDuration={3500}>\n            {children}\n        </NotistackSnackbarProvider>\n    );\n};\n","import {\n    AdditionalFieldDelegate,\n    ArrayProperty,\n    BooleanProperty,\n    CMSType,\n    DateProperty,\n    EntityCallbacks,\n    EntityCollection,\n    EnumValueConfig,\n    EnumValues,\n    GeopointProperty,\n    MapProperty,\n    NumberProperty,\n    PropertiesOrBuilders,\n    PropertyBuilder,\n    PropertyConfig,\n    PropertyOrBuilder,\n    ReferenceProperty,\n    StringProperty,\n    User\n} from \"../types\";\n\n/**\n * Identity function we use to defeat the type system of Typescript and build\n * collection views with all its properties\n * @param collection\n * @group Builder\n */\nexport function buildCollection<M extends Record<string, any> = any,\n    UserType extends User = User>(\n    collection: EntityCollection<M, UserType>\n): EntityCollection<M, UserType> {\n    return collection;\n}\n\n/**\n * Identity function we use to defeat the type system of Typescript and preserve\n * the property keys.\n * @param property\n * @group Builder\n */\nexport function buildProperty<T extends CMSType = CMSType, P extends PropertyOrBuilder<T> = PropertyOrBuilder<T>, M extends Record<string, any> = Record<string, any>>(\n    property: P\n):\n    P extends StringProperty ? StringProperty :\n        P extends NumberProperty ? NumberProperty :\n            P extends BooleanProperty ? BooleanProperty :\n                P extends DateProperty ? DateProperty :\n                    P extends GeopointProperty ? GeopointProperty :\n                        P extends ReferenceProperty ? ReferenceProperty :\n                            P extends ArrayProperty ? ArrayProperty :\n                                P extends MapProperty ? MapProperty :\n                                    P extends PropertyBuilder<T, M> ? PropertyBuilder<T, M> : never {\n    return property as any;\n}\n\n/**\n * Identity function we use to defeat the type system of Typescript and preserve\n * the properties keys.\n * @param properties\n * @group Builder\n */\nexport function buildProperties<M extends Record<string, any>>(\n    properties: PropertiesOrBuilders<M>\n): PropertiesOrBuilders<M> {\n    return properties;\n}\n\n/**\n * Identity function we use to defeat the type system of Typescript and preserve\n * the properties keys.\n * @param propertiesOrBuilder\n * @group Builder\n */\nexport function buildPropertiesOrBuilder<M extends Record<string, any>>(\n    propertiesOrBuilder: PropertiesOrBuilders<M>\n): PropertiesOrBuilders<M> {\n    return propertiesOrBuilder;\n}\n\n/**\n * Identity function we use to defeat the type system of Typescript and preserve\n * the properties keys.\n * @param enumValues\n * @group Builder\n */\nexport function buildEnumValues(\n    enumValues: EnumValues\n): EnumValues {\n    return enumValues;\n}\n\n/**\n * Identity function we use to defeat the type system of Typescript and preserve\n * the properties keys.\n * @param enumValueConfig\n * @group Builder\n */\nexport function buildEnumValueConfig(\n    enumValueConfig: EnumValueConfig\n): EnumValueConfig {\n    return enumValueConfig;\n}\n\n/**\n * Identity function we use to defeat the type system of Typescript and preserve\n * the properties keys.\n * @param callbacks\n * @group Builder\n */\nexport function buildEntityCallbacks<M extends Record<string, any> = any>(\n    callbacks: EntityCallbacks<M>\n): EntityCallbacks<M> {\n    return callbacks;\n}\n\n/**\n * Identity function we use to defeat the type system of Typescript and build\n * additional field delegates views with all its properties\n * @param additionalFieldDelegate\n * @group Builder\n */\nexport function buildAdditionalFieldDelegate<M extends Record<string, any>, UserType extends User = User>(\n    additionalFieldDelegate: AdditionalFieldDelegate<M, UserType>\n): AdditionalFieldDelegate<M, UserType> {\n    return additionalFieldDelegate;\n}\n\n/**\n * Identity function we use to defeat the type system of Typescript and build\n * additional field delegates views with all its properties\n * @param propertyConfig\n * @group Builder\n */\nexport function buildFieldConfig<T extends CMSType = CMSType>(\n    propertyConfig: PropertyConfig<T>\n): PropertyConfig<T> {\n    return propertyConfig;\n}\n","export function flattenObject(obj: any, parentKey = \"\") {\n    if (!obj) return obj;\n    return Object.keys(obj).reduce((flatObj, key) => {\n        const newKey = parentKey ? `${parentKey}.${key}` : key;\n\n        if (typeof obj[key] === \"object\" && obj[key] !== null) {\n            if (Array.isArray(obj[key])) {\n                obj[key].forEach((item: any, index: number) => {\n                    Object.assign(flatObj, flattenObject(item, `${newKey}[${index}]`));\n                });\n            } else {\n                Object.assign(flatObj, flattenObject(obj[key], newKey));\n            }\n        } else {\n            flatObj[newKey] = obj[key];\n        }\n\n        return flatObj;\n    }, {} as { [key: string]: any });\n}\n\n\n// map from nested property key like \"a.b.c\" to the maximum array count found in a list of objects for that array\nexport type ArrayValuesCount = Record<string, number>;\n\nexport function getArrayValuesCount(array: any[]): ArrayValuesCount {\n    return array.reduce((acc: ArrayValuesCount, obj: any) => {\n        Object.entries(obj).forEach(([key, value]) => {\n            // proceed only if value is an array\n            if (Array.isArray(value)) {\n                acc[key] = Math.max(acc[key] || 0, value.length);\n            }\n\n            // handle nested object\n            if (typeof value === \"object\" && value !== null) {\n                const nested = getArrayValuesCount([value]);\n                Object.entries(nested).forEach(([nestedKey, nestedCount]) => {\n                    const compoundKey = `${key}.${nestedKey}`;\n                    acc[compoundKey] = Math.max(acc[compoundKey] || 0, nestedCount);\n                });\n            }\n        });\n        return acc;\n    }, {});\n}\n","import { Properties, PropertiesOrBuilders } from \"../types\";\nimport { isPropertyBuilder } from \"./entities\";\n\nexport function makePropertiesEditable(properties: Properties) {\n    Object.keys(properties).forEach((key) => {\n        const property = properties[key];\n        property.editable = true;\n        if (property.dataType === \"map\" && property.properties) {\n            makePropertiesEditable(property.properties as Properties);\n        }\n    });\n    return properties;\n}\n\nexport function makePropertiesNonEditable(properties: PropertiesOrBuilders): PropertiesOrBuilders {\n    return Object.entries(properties).reduce((acc, [key, property]) => {\n        if (!isPropertyBuilder(property) && property.dataType === \"map\" && property.properties) {\n            const updated = { ...property, properties: makePropertiesNonEditable(property.properties as PropertiesOrBuilders) };\n            acc[key] = updated;\n        }\n        if (isPropertyBuilder(property)) {\n            acc[key] = property;\n        } else {\n            acc[key] = { ...property, editable: false };\n        }\n        return acc;\n    }, {} as PropertiesOrBuilders);\n\n}\n","/**\n * Returns the plural of an English word.\n *\n * @export\n * @param {string} word\n * @param {number} [amount]\n * @returns {string}\n */\nexport function plural(word: string, amount?: number): string {\n    if (amount !== undefined && amount === 1) {\n        return word\n    }\n    const plurals: { [key: string]: string } = {\n        \"(quiz)$\": \"$1zes\",\n        \"^(ox)$\": \"$1en\",\n        \"([m|l])ouse$\": \"$1ice\",\n        \"(matr|vert|ind)ix|ex$\": \"$1ices\",\n        \"(x|ch|ss|sh)$\": \"$1es\",\n        \"([^aeiouy]|qu)y$\": \"$1ies\",\n        \"(hive)$\": \"$1s\",\n        \"(?:([^f])fe|([lr])f)$\": \"$1$2ves\",\n        \"(shea|lea|loa|thie)f$\": \"$1ves\",\n        sis$: \"ses\",\n        \"([ti])um$\": \"$1a\",\n        \"(tomat|potat|ech|her|vet)o$\": \"$1oes\",\n        \"(bu)s$\": \"$1ses\",\n        \"(alias)$\": \"$1es\",\n        \"(octop)us$\": \"$1i\",\n        \"(ax|test)is$\": \"$1es\",\n        \"(us)$\": \"$1es\",\n        \"([^s]+)$\": \"$1s\"\n    }\n    const irregular: { [key: string]: string } = {\n        move: \"moves\",\n        foot: \"feet\",\n        goose: \"geese\",\n        sex: \"sexes\",\n        child: \"children\",\n        man: \"men\",\n        tooth: \"teeth\",\n        person: \"people\"\n    }\n    const uncountable: string[] = [\n        \"sheep\",\n        \"fish\",\n        \"deer\",\n        \"moose\",\n        \"series\",\n        \"species\",\n        \"money\",\n        \"rice\",\n        \"information\",\n        \"equipment\",\n        \"bison\",\n        \"cod\",\n        \"offspring\",\n        \"pike\",\n        \"salmon\",\n        \"shrimp\",\n        \"swine\",\n        \"trout\",\n        \"aircraft\",\n        \"hovercraft\",\n        \"spacecraft\",\n        \"sugar\",\n        \"tuna\",\n        \"you\",\n        \"wood\"\n    ]\n    // save some time in the case that singular and plural are the same\n    if (uncountable.indexOf(word.toLowerCase()) >= 0) {\n        return word;\n    }\n    // check for irregular forms\n    for (const w in irregular) {\n        const pattern = new RegExp(`${w}$`, \"i\")\n        const replace = irregular[w]\n        if (pattern.test(word)) {\n            return word.replace(pattern, replace);\n        }\n    }\n    // check for matches using regular expressions\n    for (const reg in plurals) {\n        const pattern = new RegExp(reg, \"i\")\n        if (pattern.test(word)) {\n            return word.replace(pattern, plurals[reg])\n        }\n    }\n    return word;\n}\n\n/**\n * Returns the singular of an English word.\n *\n * @export\n * @param {string} word\n * @param {number} [amount]\n * @returns {string}\n */\nexport function singular(word: string, amount?: number): string {\n    if (amount !== undefined && amount !== 1) {\n        return word;\n    }\n    const singulars: { [key: string]: string } = {\n        \"(quiz)zes$\": \"$1\",\n        \"(matr)ices$\": \"$1ix\",\n        \"(vert|ind)ices$\": \"$1ex\",\n        \"^(ox)en$\": \"$1\",\n        \"(alias)es$\": \"$1\",\n        \"(octop|vir)i$\": \"$1us\",\n        \"(cris|ax|test)es$\": \"$1is\",\n        \"(shoe)s$\": \"$1\",\n        \"(o)es$\": \"$1\",\n        \"(bus)es$\": \"$1\",\n        \"([m|l])ice$\": \"$1ouse\",\n        \"(x|ch|ss|sh)es$\": \"$1\",\n        \"(m)ovies$\": \"$1ovie\",\n        \"(s)eries$\": \"$1eries\",\n        \"([^aeiouy]|qu)ies$\": \"$1y\",\n        \"([lr])ves$\": \"$1f\",\n        \"(tive)s$\": \"$1\",\n        \"(hive)s$\": \"$1\",\n        \"(li|wi|kni)ves$\": \"$1fe\",\n        \"(shea|loa|lea|thie)ves$\": \"$1f\",\n        \"(^analy)ses$\": \"$1sis\",\n        \"((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$\": \"$1$2sis\",\n        \"([ti])a$\": \"$1um\",\n        \"(n)ews$\": \"$1ews\",\n        \"(h|bl)ouses$\": \"$1ouse\",\n        \"(corpse)s$\": \"$1\",\n        \"(us)es$\": \"$1\",\n        s$: \"\"\n    }\n    const irregular: { [key: string]: string } = {\n        move: \"moves\",\n        foot: \"feet\",\n        goose: \"geese\",\n        sex: \"sexes\",\n        child: \"children\",\n        man: \"men\",\n        tooth: \"teeth\",\n        person: \"people\"\n    }\n    const uncountable: string[] = [\n        \"sheep\",\n        \"fish\",\n        \"deer\",\n        \"moose\",\n        \"series\",\n        \"species\",\n        \"money\",\n        \"rice\",\n        \"information\",\n        \"equipment\",\n        \"bison\",\n        \"cod\",\n        \"offspring\",\n        \"pike\",\n        \"salmon\",\n        \"shrimp\",\n        \"swine\",\n        \"trout\",\n        \"aircraft\",\n        \"hovercraft\",\n        \"spacecraft\",\n        \"sugar\",\n        \"tuna\",\n        \"you\",\n        \"wood\"\n    ]\n    // save some time in the case that singular and plural are the same\n    if (uncountable.indexOf(word.toLowerCase()) >= 0) {\n        return word;\n    }\n    // check for irregular forms\n    for (const w in irregular) {\n        const pattern = new RegExp(`${irregular[w]}$`, \"i\");\n        if (pattern.test(word)) {\n            return word.replace(pattern, w);\n        }\n    }\n    // check for matches using regular expressions\n    for (const reg in singulars) {\n        const pattern = new RegExp(reg, \"i\");\n        if (pattern.test(word)) {\n            return word.replace(pattern, singulars[reg]);\n        }\n    }\n    return word;\n}\n","import { useEffect } from \"react\";\n\nconst fireCMSLogo = \"data:image/png;base64,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\\n\";\n\n/**\n * Internal hook to handle the browser title and icon\n * @param name\n * @param logo\n */\nexport function useBrowserTitleAndIcon(name: string, logo?: string) {\n    useEffect(() => {\n        if (document) {\n            document.title = `${name} - FireCMS`;\n            let link = document.querySelector(\"link[rel~='icon']\");\n            if (!link) {\n                link = document.createElement(\"link\");\n                // @ts-ignore\n                link.rel = \"icon\";\n                document.getElementsByTagName(\"head\")[0].appendChild(link);\n            }\n            // @ts-ignore\n            link.href = logo ?? fireCMSLogo;\n        }\n    }, [name, logo]);\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { PartialEntityCollection, UserConfigurationPersistence } from \"../types\";\nimport { mergeDeep, stripCollectionPath } from \"../util\";\n\nexport function useBuildLocalConfigurationPersistence(): UserConfigurationPersistence {\n\n    const configCache = useRef<Record<string, PartialEntityCollection>>({});\n\n    const getCollectionFromStorage = useCallback((storageKey: string) => {\n        const item = localStorage.getItem(storageKey);\n        return item ? JSON.parse(item) : {};\n    }, []);\n\n    const getCollectionConfig = useCallback(<M extends Record<string, any>>(path: string): PartialEntityCollection<M> => {\n        const storageKey = `collection_config::${stripCollectionPath(path)}`;\n        if (configCache.current[storageKey]) {\n            return configCache.current[storageKey] as PartialEntityCollection<M>;\n        }\n        return getCollectionFromStorage(storageKey);\n    }, [getCollectionFromStorage]);\n\n    const onCollectionModified = useCallback(<M extends Record<string, any>>(path: string, data: PartialEntityCollection<M>) => {\n        const storageKey = `collection_config::${stripCollectionPath(path)}`;\n        localStorage.setItem(storageKey, JSON.stringify(data));\n        const currentCache = configCache.current;\n        const cachedConfig = currentCache[storageKey];\n        const newConfig = mergeDeep(cachedConfig ?? getCollectionFromStorage(path), data);\n        configCache.current = mergeDeep(currentCache, newConfig);\n    }, [getCollectionFromStorage]);\n\n    const [recentlyVisitedPaths, _setRecentlyVisitedPaths] = useState<string[]>([]);\n    const [favouritePaths, _setFavouritePaths] = useState<string[]>([]);\n    const [collapsedGroups, _setCollapsedGroups] = useState<string[]>([]);\n\n    useEffect(() => {\n        _setRecentlyVisitedPaths(localStorage.getItem(\"recently_visited_paths\") ? JSON.parse(localStorage.getItem(\"recently_visited_paths\")!) : []);\n        _setFavouritePaths(localStorage.getItem(\"favourite_paths\") ? JSON.parse(localStorage.getItem(\"favourite_paths\")!) : []);\n        _setCollapsedGroups(localStorage.getItem(\"collapsed_groups\") ? JSON.parse(localStorage.getItem(\"collapsed_groups\")!) : []);\n    }, []);\n\n    const setRecentlyVisitedPaths = useCallback((paths: string[]) => {\n        localStorage.setItem(\"recently_visited_paths\", JSON.stringify(paths));\n        _setRecentlyVisitedPaths(paths);\n    }, []);\n\n    const setFavouritePaths = useCallback((paths: string[]) => {\n        localStorage.setItem(\"favourite_paths\", JSON.stringify(paths));\n        _setFavouritePaths(paths);\n    }, []);\n\n    const setCollapsedGroups = useCallback((paths: string[]) => {\n        localStorage.setItem(\"collapsed_groups\", JSON.stringify(paths));\n        _setCollapsedGroups(paths);\n    }, []);\n\n    return {\n        onCollectionModified,\n        getCollectionConfig,\n        recentlyVisitedPaths,\n        setRecentlyVisitedPaths,\n        favouritePaths,\n        setFavouritePaths,\n        collapsedGroups,\n        setCollapsedGroups\n    }\n}\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { ModeController } from \"./index\";\n\n/**\n * Use this hook to build a color mode controller that determines\n * the theme of the CMS\n */\nexport function useBuildModeController(): ModeController {\n\n    const prefersDarkModeQuery = useCallback((): boolean => {\n        if (typeof window === \"undefined\")\n            return false;\n        const mediaQueryList = window.matchMedia(\"(prefers-color-scheme: dark)\");\n        return mediaQueryList.matches;\n    }, []);\n\n    const prefersDarkModeStorage: boolean | null = localStorage.getItem(\"prefers-dark-mode\") != null ? localStorage.getItem(\"prefers-dark-mode\") === \"true\" : null;\n    const prefersDarkMode = prefersDarkModeStorage ?? prefersDarkModeQuery;\n    const [mode, setMode] = useState<\"light\" | \"dark\">(prefersDarkMode ? \"dark\" : \"light\");\n\n    useEffect(() => {\n        setMode(prefersDarkMode ? \"dark\" : \"light\");\n        setDocumentMode(prefersDarkMode ? \"dark\" : \"light\");\n    }, [prefersDarkMode]);\n\n    // color-scheme: dark;\n    const setDarkMode = useCallback(() => {\n        setMode(\"dark\");\n        setDocumentMode(\"dark\");\n    }, []);\n\n    const setLightMode = useCallback(() => {\n        setMode(\"light\");\n        setDocumentMode(\"light\");\n    }, []);\n\n    const setDocumentMode = (mode: \"light\" | \"dark\") => {\n        document.body.style.setProperty(\"color-scheme\", mode);\n        document.documentElement.dataset.theme = mode;\n    };\n\n    const toggleMode = useCallback(() => {\n\n        const prefersDarkModeQueryResult = prefersDarkModeQuery();\n        if (mode === \"light\") {\n            if (!prefersDarkModeQueryResult)\n                localStorage.setItem(\"prefers-dark-mode\", \"true\");\n            else\n                localStorage.removeItem(\"prefers-dark-mode\");\n            setDarkMode();\n        } else {\n            if (prefersDarkModeQueryResult)\n                localStorage.setItem(\"prefers-dark-mode\", \"false\");\n            else\n                localStorage.removeItem(\"prefers-dark-mode\");\n            setLightMode();\n        }\n    }, [mode, prefersDarkModeQuery]);\n\n    return {\n        mode,\n        setMode,\n        toggleMode\n    };\n}\n","import { useEffect, useState } from \"react\";\nimport { Entity, EntityCollection, FilterValues, FireCMSContext, User } from \"../../types\";\nimport { useDataSource } from \"./useDataSource\";\nimport { useNavigationController } from \"../useNavigationController\";\nimport { useFireCMSContext } from \"../useFireCMSContext\";\n\n/**\n * @group Hooks and utilities\n */\nexport interface CollectionFetchProps<M extends Record<string, any>> {\n\n    /**\n     * Absolute collection path\n     */\n    path: string;\n\n    /**\n     * collection of the entity displayed by this collection\n     */\n    collection: EntityCollection<M>\n\n    /**\n     * Number of entities to fetch\n     */\n    itemCount?: number;\n\n    /**\n     * Filter the fetched data by the property\n     */\n    filterValues?: FilterValues<Extract<keyof M, string>>;\n\n    /**\n     * Sort the results by\n     */\n    sortBy?: [Extract<keyof M, string>, \"asc\" | \"desc\"];\n\n    /**\n     * Search string\n     */\n    searchString?: string;\n}\n\n/**\n * @group Hooks and utilities\n */\nexport interface CollectionFetchResult<M extends Record<string, any>> {\n    data: Entity<M>[];\n    dataLoading: boolean;\n    noMoreToLoad: boolean;\n    dataLoadingError?: Error;\n}\n\n/**\n * This hook is used to fetch collections using a given collection\n * @param path\n * @param collection\n * @param filterValues\n * @param sortBy\n * @param itemCount\n * @param searchString\n * @group Hooks and utilities\n */\nexport function useCollectionFetch<M extends Record<string, any>, UserType extends User>(\n    {\n        path: inputPath,\n        collection,\n        filterValues,\n        sortBy,\n        itemCount,\n        searchString\n    }: CollectionFetchProps<M>): CollectionFetchResult<M> {\n\n    const dataSource = useDataSource(collection);\n    const navigationController = useNavigationController();\n\n    const path = navigationController.resolveAliasesFrom(inputPath);\n\n    const sortByProperty = sortBy ? sortBy[0] : undefined;\n    const currentSort = sortBy ? sortBy[1] : undefined;\n\n    const context: FireCMSContext<UserType> = useFireCMSContext();\n\n    const [data, setData] = useState<Entity<M>[]>([]);\n\n    const [dataLoading, setDataLoading] = useState<boolean>(false);\n    const [dataLoadingError, setDataLoadingError] = useState<Error | undefined>();\n    const [noMoreToLoad, setNoMoreToLoad] = useState<boolean>(false);\n\n    useEffect(() => {\n\n        setDataLoading(true);\n\n        const onEntitiesUpdate = async (entities: Entity<M>[]) => {\n            if (collection.callbacks?.onFetch) {\n                try {\n                    entities = await Promise.all(\n                        entities.map((entity) =>\n                            collection.callbacks!.onFetch!({\n                                collection,\n                                path,\n                                entity,\n                                context\n                            })));\n                } catch (e: any) {\n                    console.error(e);\n                }\n            }\n            setDataLoading(false);\n            setDataLoadingError(undefined);\n            setData(entities.map(e => ({\n                ...e,\n                // values: sanitizeData(e.values, resolvedCollection.properties)\n            })));\n            setNoMoreToLoad(!itemCount || entities.length < itemCount);\n        };\n\n        const onError = (error: Error) => {\n            console.error(\"ERROR\", error);\n            setDataLoading(false);\n            setData([]);\n            setDataLoadingError(error);\n        };\n\n        if (dataSource.listenCollection) {\n            return dataSource.listenCollection<M>({\n                path,\n                collection,\n                onUpdate: onEntitiesUpdate,\n                onError,\n                searchString,\n                filter: filterValues,\n                limit: itemCount,\n                startAfter: undefined,\n                orderBy: sortByProperty,\n                order: currentSort\n            });\n        } else {\n            dataSource.fetchCollection<M>({\n                path,\n                collection,\n                searchString,\n                filter: filterValues,\n                limit: itemCount,\n                startAfter: undefined,\n                orderBy: sortByProperty,\n                order: currentSort\n            })\n                .then(onEntitiesUpdate)\n                .catch(onError);\n            return () => {\n            };\n        }\n    }, [path, itemCount, currentSort, sortByProperty, filterValues, searchString]);\n\n    return {\n        data,\n        dataLoading,\n        dataLoadingError,\n        noMoreToLoad\n    };\n\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport equal from \"react-fast-compare\";\n\nimport { AuthController, Authenticator, DataSourceDelegate, StorageSource, User } from \"../index\";\n\n/**\n * This hook is used internally for validating an authenticator.\n *\n * @param authController\n * @param authentication\n * @param storageSource\n * @param dataSourceDelegate\n */\nexport function useValidateAuthenticator<UserType extends User = User, Controller extends AuthController<UserType> = AuthController<UserType>>({\n                                                                                                                                                   disabled,\n                                                                                                                                                   authController,\n                                                                                                                                                   authenticator,\n                                                                                                                                                   storageSource,\n                                                                                                                                                   dataSourceDelegate\n                                                                                                                                               }:\n                                                                                                                                                   {\n                                                                                                                                                       disabled?: boolean,\n                                                                                                                                                       authController: Controller,\n                                                                                                                                                       authenticator?: boolean | Authenticator<UserType, Controller>,\n                                                                                                                                                       dataSourceDelegate: DataSourceDelegate;\n                                                                                                                                                       storageSource: StorageSource;\n                                                                                                                                                   }): {\n    canAccessMainView: boolean,\n    authLoading: boolean,\n    notAllowedError: any,\n    authVerified: boolean,\n} {\n\n    const authenticationEnabled = Boolean(authenticator);\n\n    const [authLoading, setAuthLoading] = useState<boolean>(authenticationEnabled);\n    const [notAllowedError, setNotAllowedError] = useState<any>(false);\n    const [authVerified, setAuthVerified] = useState<boolean>(!authenticationEnabled || Boolean(authController.loginSkipped));\n\n    const canAccessMainView = (authVerified) &&\n        (!authenticationEnabled || Boolean(authController.user) || Boolean(authController.loginSkipped)) &&\n        !notAllowedError;\n\n    useEffect(() => {\n        if (authController.loginSkipped)\n            setAuthVerified(true);\n    }, [authController.loginSkipped]);\n\n    /**\n     * We use this ref to check the authentication only if the user has\n     * changed.\n     */\n    const checkedUserRef = useRef<User | undefined>();\n\n    const checkAuthentication = useCallback(async () => {\n\n        if (disabled) {\n            return;\n        }\n\n        if (authController.initialLoading) {\n            return;\n        }\n\n        if (!authController.user && !authController.loginSkipped) {\n            checkedUserRef.current = undefined;\n            setAuthLoading(false);\n            setAuthVerified(false);\n            return;\n        }\n\n        const delegateUser = authController.user;\n        console.debug(\"Checking authentication for user\", delegateUser);\n\n        if (authenticator instanceof Function && delegateUser && !equal(checkedUserRef.current?.uid, delegateUser.uid)) {\n            setAuthLoading(true);\n            try {\n                const allowed = await authenticator({\n                    user: delegateUser,\n                    authController,\n                    dataSourceDelegate,\n                    storageSource\n                });\n                if (!allowed) {\n                    authController.signOut();\n                    setNotAllowedError(true);\n                }\n            } catch (e) {\n                setNotAllowedError(e);\n                authController.signOut();\n            }\n            setAuthLoading(false);\n            setAuthVerified(true);\n            checkedUserRef.current = delegateUser;\n        } else {\n            setAuthLoading(false);\n        }\n\n        if (!authController.initialLoading && !delegateUser) {\n            setAuthVerified(true);\n        }\n\n    }, [disabled, authController, authenticator, dataSourceDelegate, storageSource]);\n\n    useEffect(() => {\n        checkAuthentication();\n    }, [checkAuthentication]);\n\n    return {\n        canAccessMainView,\n        authLoading: authenticationEnabled && authLoading,\n        notAllowedError,\n        authVerified\n    }\n}\n"]}