This is an automated email from the ASF dual-hosted git repository. beto pushed a commit to branch semantic-layer-ui-semantic-view in repository https://gitbox.apache.org/repos/asf/superset.git
commit 8358d9beaeaa8ffb23e3f7f303eea6ba2b2a8a86 Author: Beto Dealmeida <[email protected]> AuthorDate: Wed Feb 11 11:19:50 2026 -0500 feat: UI for semantic views --- docker/pythonpath_dev/superset_config.py | 1 + docs/static/feature-flags.json | 6 + .../components/Label/reusable/DatasetTypeLabel.tsx | 20 +- .../superset-ui-core/src/utils/featureFlags.ts | 1 + .../semanticViews/SemanticViewEditModal.tsx | 120 ++ superset-frontend/src/pages/DatasetList/index.tsx | 223 ++- superset/config.py | 3 + superset/datasource/api.py | 267 +++- superset/semantic_layers/models.py | 8 + superset/static/service-worker.js | 1492 +++++++++++++++++++- 10 files changed, 2089 insertions(+), 52 deletions(-) diff --git a/docker/pythonpath_dev/superset_config.py b/docker/pythonpath_dev/superset_config.py index cdf33c2bb9c..ce7f1998708 100644 --- a/docker/pythonpath_dev/superset_config.py +++ b/docker/pythonpath_dev/superset_config.py @@ -109,6 +109,7 @@ FEATURE_FLAGS = { "ALERT_REPORTS": True, "DATASET_FOLDERS": True, "ENABLE_EXTENSIONS": True, + "SEMANTIC_LAYERS": True, } EXTENSIONS_PATH = "/app/docker/extensions" ALERT_REPORTS_NOTIFICATION_DRY_RUN = True diff --git a/docs/static/feature-flags.json b/docs/static/feature-flags.json index 6ca4c2ea818..f87df2d96cd 100644 --- a/docs/static/feature-flags.json +++ b/docs/static/feature-flags.json @@ -69,6 +69,12 @@ "lifecycle": "development", "description": "Expand nested types in Presto into extra columns/arrays. Experimental, doesn't work with all nested types." }, + { + "name": "SEMANTIC_LAYERS", + "default": false, + "lifecycle": "development", + "description": "Enable semantic layers and show semantic views alongside datasets" + }, { "name": "TABLE_V2_TIME_COMPARISON_ENABLED", "default": false, diff --git a/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx b/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx index d8567d93b2a..f3d19617742 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx @@ -23,7 +23,7 @@ import { Label } from '..'; // Define the prop types for DatasetTypeLabel interface DatasetTypeLabelProps { - datasetType: 'physical' | 'virtual'; // Accepts only 'physical' or 'virtual' + datasetType: 'physical' | 'virtual' | 'semantic_view'; } const SIZE = 's'; // Define the size as a constant @@ -32,6 +32,24 @@ export const DatasetTypeLabel: React.FC<DatasetTypeLabelProps> = ({ datasetType, }) => { const theme = useTheme(); + + if (datasetType === 'semantic_view') { + return ( + <Label + icon={ + <Icons.ApartmentOutlined + iconSize={SIZE} + iconColor={theme.colorInfo} + /> + } + type="info" + style={{ color: theme.colorInfo }} + > + {t('Semantic')} + </Label> + ); + } + const label: string = datasetType === 'physical' ? t('Physical') : t('Virtual'); const icon = diff --git a/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts b/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts index 46f832cc094..dbfd146914a 100644 --- a/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts +++ b/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts @@ -57,6 +57,7 @@ export enum FeatureFlag { ListviewsDefaultCardView = 'LISTVIEWS_DEFAULT_CARD_VIEW', Matrixify = 'MATRIXIFY', ScheduledQueries = 'SCHEDULED_QUERIES', + SemanticLayers = 'SEMANTIC_LAYERS', SqllabBackendPersistence = 'SQLLAB_BACKEND_PERSISTENCE', SqlValidatorsByEngine = 'SQL_VALIDATORS_BY_ENGINE', SshTunneling = 'SSH_TUNNELING', diff --git a/superset-frontend/src/features/semanticViews/SemanticViewEditModal.tsx b/superset-frontend/src/features/semanticViews/SemanticViewEditModal.tsx new file mode 100644 index 00000000000..ed90d165b9c --- /dev/null +++ b/superset-frontend/src/features/semanticViews/SemanticViewEditModal.tsx @@ -0,0 +1,120 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { useState, useEffect } from 'react'; +import { t } from '@apache-superset/core'; +import { styled } from '@apache-superset/core/ui'; +import { SupersetClient } from '@superset-ui/core'; +import { Input, InputNumber } from '@superset-ui/core/components'; +import { Icons } from '@superset-ui/core/components/Icons'; +import { + StandardModal, + ModalFormField, + MODAL_STANDARD_WIDTH, +} from 'src/components/Modal'; + +const ModalContent = styled.div` + padding: ${({ theme }) => theme.sizeUnit * 4}px; +`; + +interface SemanticViewEditModalProps { + show: boolean; + onHide: () => void; + onSave: () => void; + addDangerToast: (msg: string) => void; + addSuccessToast: (msg: string) => void; + semanticView: { + id: number; + table_name: string; + description?: string | null; + cache_timeout?: number | null; + } | null; +} + +export default function SemanticViewEditModal({ + show, + onHide, + onSave, + addDangerToast, + addSuccessToast, + semanticView, +}: SemanticViewEditModalProps) { + const [description, setDescription] = useState<string>(''); + const [cacheTimeout, setCacheTimeout] = useState<number | null>(null); + const [saving, setSaving] = useState(false); + + useEffect(() => { + if (semanticView) { + setDescription(semanticView.description || ''); + setCacheTimeout(semanticView.cache_timeout ?? null); + } + }, [semanticView]); + + const handleSave = async () => { + if (!semanticView) return; + setSaving(true); + try { + await SupersetClient.put({ + endpoint: `/api/v1/semantic_view/${semanticView.id}`, + jsonPayload: { + description: description || null, + cache_timeout: cacheTimeout, + }, + }); + addSuccessToast(t('Semantic view updated')); + onSave(); + onHide(); + } catch { + addDangerToast(t('An error occurred while saving the semantic view')); + } finally { + setSaving(false); + } + }; + + return ( + <StandardModal + show={show} + onHide={onHide} + onSave={handleSave} + title={t('Edit %s', semanticView?.table_name || '')} + icon={<Icons.EditOutlined />} + isEditMode + width={MODAL_STANDARD_WIDTH} + saveLoading={saving} + > + <ModalContent> + <ModalFormField label={t('Description')}> + <Input.TextArea + value={description} + onChange={e => setDescription(e.target.value)} + rows={4} + /> + </ModalFormField> + <ModalFormField label={t('Cache timeout')}> + <InputNumber + value={cacheTimeout} + onChange={value => setCacheTimeout(value as number | null)} + min={0} + placeholder={t('Duration in seconds')} + style={{ width: '100%' }} + /> + </ModalFormField> + </ModalContent> + </StandardModal> + ); +} diff --git a/superset-frontend/src/pages/DatasetList/index.tsx b/superset-frontend/src/pages/DatasetList/index.tsx index 7822e15a9e5..ceafdd03a42 100644 --- a/superset-frontend/src/pages/DatasetList/index.tsx +++ b/superset-frontend/src/pages/DatasetList/index.tsx @@ -17,7 +17,12 @@ * under the License. */ import { t } from '@apache-superset/core'; -import { getExtensionsRegistry, SupersetClient } from '@superset-ui/core'; +import { + getExtensionsRegistry, + SupersetClient, + isFeatureEnabled, + FeatureFlag, +} from '@superset-ui/core'; import { styled, useTheme, css } from '@apache-superset/core/ui'; import { FunctionComponent, useState, useMemo, useCallback, Key } from 'react'; import { Link, useHistory } from 'react-router-dom'; @@ -48,6 +53,7 @@ import { ListViewFilterOperator as FilterOperator, type ListViewProps, type ListViewFilters, + type ListViewFetchDataConfig, } from 'src/components'; import { Typography } from '@superset-ui/core/components/Typography'; import handleResourceExport from 'src/utils/export'; @@ -65,6 +71,7 @@ import { CONFIRM_OVERWRITE_MESSAGE, } from 'src/features/datasets/constants'; import DuplicateDatasetModal from 'src/features/datasets/DuplicateDatasetModal'; +import SemanticViewEditModal from 'src/features/semanticViews/SemanticViewEditModal'; import { useSelector } from 'react-redux'; import { QueryObjectColumns } from 'src/views/CRUD/types'; import { WIDER_DROPDOWN_WIDTH } from 'src/components/ListView/utils'; @@ -118,13 +125,16 @@ type Dataset = { database: { id: string; database_name: string; - }; + } | null; kind: string; + source_type?: 'database' | 'semantic_layer'; explore_url: string; id: number; owners: Array<Owner>; schema: string; table_name: string; + description?: string | null; + cache_timeout?: number | null; }; interface VirtualDataset extends Dataset { @@ -150,18 +160,90 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({ const history = useHistory(); const theme = useTheme(); const { - state: { - loading, - resourceCount: datasetCount, - resourceCollection: datasets, - bulkSelectEnabled, - }, + state: { bulkSelectEnabled }, hasPerm, - fetchData, toggleBulkSelect, - refreshData, } = useListViewResource<Dataset>('dataset', t('dataset'), addDangerToast); + // Combined endpoint state + const [datasets, setDatasets] = useState<Dataset[]>([]); + const [datasetCount, setDatasetCount] = useState(0); + const [loading, setLoading] = useState(true); + const [lastFetchConfig, setLastFetchConfig] = + useState<ListViewFetchDataConfig | null>(null); + const [currentSourceFilter, setCurrentSourceFilter] = useState<string>(''); + + const fetchData = useCallback((config: ListViewFetchDataConfig) => { + setLastFetchConfig(config); + setLoading(true); + const { pageIndex, pageSize, sortBy, filters: filterValues } = config; + + // Separate source_type filter from other filters + const sourceTypeFilter = filterValues.find(f => f.id === 'source_type'); + + // Track source filter for conditional Type filter visibility + const sourceVal = + sourceTypeFilter?.value && typeof sourceTypeFilter.value === 'object' + ? (sourceTypeFilter.value as { value: string }).value + : ((sourceTypeFilter?.value as string) ?? ''); + setCurrentSourceFilter(sourceVal); + const otherFilters = filterValues + .filter(f => f.id !== 'source_type') + .filter( + ({ value }) => value !== '' && value !== null && value !== undefined, + ) + .map(({ id, operator: opr, value }) => ({ + col: id, + opr, + value: + value && typeof value === 'object' && 'value' in value + ? value.value + : value, + })); + + // Add source_type filter for the combined endpoint + const sourceTypeValue = + sourceTypeFilter?.value && typeof sourceTypeFilter.value === 'object' + ? (sourceTypeFilter.value as { value: string }).value + : sourceTypeFilter?.value; + if (sourceTypeValue) { + otherFilters.push({ + col: 'source_type', + opr: 'eq', + value: sourceTypeValue, + }); + } + + const queryParams = rison.encode_uri({ + order_column: sortBy[0].id, + order_direction: sortBy[0].desc ? 'desc' : 'asc', + page: pageIndex, + page_size: pageSize, + ...(otherFilters.length ? { filters: otherFilters } : {}), + }); + + return SupersetClient.get({ + endpoint: `/api/v1/datasource/?q=${queryParams}`, + }) + .then(({ json = {} }) => { + setDatasets(json.result); + setDatasetCount(json.count); + }) + .catch(() => { + addDangerToast(t('An error occurred while fetching datasets')); + }) + .finally(() => { + setLoading(false); + }); + }, []); + + const refreshData = useCallback(() => { + if (lastFetchConfig) { + return fetchData(lastFetchConfig); + } + return undefined; + }, [lastFetchConfig, fetchData]); + const [datasetCurrentlyDeleting, setDatasetCurrentlyDeleting] = useState< | (Dataset & { charts: any; @@ -176,6 +258,10 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({ const [datasetCurrentlyDuplicating, setDatasetCurrentlyDuplicating] = useState<VirtualDataset | null>(null); + const [svCurrentlyEditing, setSvCurrentlyEditing] = useState<Dataset | null>( + null, + ); + const [importingDataset, showImportModal] = useState<boolean>(false); const [passwordFields, setPasswordFields] = useState<string[]>([]); const [preparingExport, setPreparingExport] = useState<boolean>(false); @@ -366,12 +452,22 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({ id: 'kind', }, { + Cell: ({ + row: { + original: { database }, + }, + }: any) => database?.database_name || '-', Header: t('Database'), accessor: 'database.database_name', size: 'xl', id: 'database.database_name', }, { + Cell: ({ + row: { + original: { schema }, + }, + }: any) => schema || '-', Header: t('Schema'), accessor: 'schema', size: 'lg', @@ -414,9 +510,40 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({ disableSortBy: true, id: 'sql', }, + { + accessor: 'source_type', + hidden: true, + disableSortBy: true, + id: 'source_type', + }, { Cell: ({ row: { original } }: any) => { - // Verify owner or isAdmin + const isSemanticView = original.source_type === 'semantic_layer'; + + // Semantic view: only show edit button + if (isSemanticView) { + if (!canEdit) return null; + return ( + <Actions className="actions"> + <Tooltip + id="edit-action-tooltip" + title={t('Edit')} + placement="bottom" + > + <span + role="button" + tabIndex={0} + className="action-button" + onClick={() => setSvCurrentlyEditing(original)} + > + <Icons.EditOutlined iconSize="l" /> + </span> + </Tooltip> + </Actions> + ); + } + + // Dataset: full set of actions const allowEdit = original.owners.map((o: Owner) => o.id).includes(user.userId) || isUserAdmin(user); @@ -519,6 +646,22 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({ const filterTypes: ListViewFilters = useMemo( () => [ + ...(isFeatureEnabled(FeatureFlag.SemanticLayers) + ? [ + { + Header: t('Source'), + key: 'source_type', + id: 'source_type', + input: 'select' as const, + operator: FilterOperator.Equals, + unfilteredLabel: t('All'), + selects: [ + { label: t('Database'), value: 'database' }, + { label: t('Semantic Layer'), value: 'semantic_layer' }, + ], + }, + ] + : []), { Header: t('Name'), key: 'search', @@ -526,18 +669,42 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({ input: 'search', operator: FilterOperator.Contains, }, - { - Header: t('Type'), - key: 'sql', - id: 'sql', - input: 'select', - operator: FilterOperator.DatasetIsNullOrEmpty, - unfilteredLabel: 'All', - selects: [ - { label: t('Virtual'), value: false }, - { label: t('Physical'), value: true }, - ], - }, + ...(isFeatureEnabled(FeatureFlag.SemanticLayers) + ? [ + { + Header: t('Type'), + key: 'sql', + id: 'sql', + input: 'select' as const, + operator: FilterOperator.DatasetIsNullOrEmpty, + unfilteredLabel: 'All', + selects: [ + ...(currentSourceFilter !== 'semantic_layer' + ? [ + { label: t('Physical'), value: true }, + { label: t('Virtual'), value: false }, + ] + : []), + ...(currentSourceFilter !== 'database' + ? [{ label: t('Semantic View'), value: 'semantic_view' }] + : []), + ], + }, + ] + : [ + { + Header: t('Type'), + key: 'sql', + id: 'sql', + input: 'select' as const, + operator: FilterOperator.DatasetIsNullOrEmpty, + unfilteredLabel: 'All', + selects: [ + { label: t('Physical'), value: true }, + { label: t('Virtual'), value: false }, + ], + }, + ]), { Header: t('Database'), key: 'database', @@ -628,7 +795,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({ dropdownStyle: { minWidth: WIDER_DROPDOWN_WIDTH }, }, ], - [user], + [user, currentSourceFilter], ); const menuData: SubMenuProps = { @@ -880,6 +1047,14 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({ onHide={closeDatasetDuplicateModal} onDuplicate={handleDatasetDuplicate} /> + <SemanticViewEditModal + show={!!svCurrentlyEditing} + onHide={() => setSvCurrentlyEditing(null)} + onSave={refreshData} + addDangerToast={addDangerToast} + addSuccessToast={addSuccessToast} + semanticView={svCurrentlyEditing} + /> <ConfirmStatusChange title={t('Please confirm')} description={t( diff --git a/superset/config.py b/superset/config.py index 9731d80bd58..b46ce0ca373 100644 --- a/superset/config.py +++ b/superset/config.py @@ -562,6 +562,9 @@ DEFAULT_FEATURE_FLAGS: dict[str, bool] = { # in addition to relative timeshifts (e.g., "1 day ago") # @lifecycle: development "DATE_RANGE_TIMESHIFTS_ENABLED": False, + # Enable semantic layers and show semantic views alongside datasets + # @lifecycle: development + "SEMANTIC_LAYERS": False, # Enables advanced data type support # @lifecycle: development "ENABLE_ADVANCED_DATA_TYPES": False, diff --git a/superset/datasource/api.py b/superset/datasource/api.py index da5f7e3ded8..ca8a235192b 100644 --- a/superset/datasource/api.py +++ b/superset/datasource/api.py @@ -15,17 +15,23 @@ # specific language governing permissions and limitations # under the License. import logging +from typing import Any from flask import current_app as app, request -from flask_appbuilder.api import expose, protect, safe +from flask_appbuilder.api import expose, protect, rison, safe +from flask_appbuilder.api.schemas import get_list_schema +from sqlalchemy import and_, func, literal, or_, select, union_all -from superset import event_logger -from superset.connectors.sqla.models import BaseDatasource +from superset import db, event_logger, is_feature_enabled, security_manager +from superset.connectors.sqla import models as sqla_models +from superset.connectors.sqla.models import BaseDatasource, SqlaTable from superset.daos.datasource import DatasourceDAO from superset.daos.exceptions import DatasourceNotFound, DatasourceTypeNotSupportedError from superset.exceptions import SupersetSecurityException +from superset.semantic_layers.models import SemanticView from superset.superset_typing import FlaskResponse from superset.utils.core import apply_max_row_limit, DatasourceType, SqlExpressionType +from superset.utils.filters import get_dataset_access_filters from superset.views.base_api import BaseSupersetApi, statsd_metrics logger = logging.getLogger(__name__) @@ -303,3 +309,258 @@ class DatasourceRestApi(BaseSupersetApi): f"Invalid expression type: {expression_type}. " f"Valid types are: column, metric, where, having" ) from None + + @expose("/", methods=("GET",)) + @safe + @statsd_metrics + @rison(get_list_schema) + @event_logger.log_this_with_context( + action=lambda self, *args, **kwargs: f"{self.__class__.__name__}" + ".combined_list", + log_to_statsd=False, + ) + def combined_list(self, **kwargs: Any) -> FlaskResponse: + """List datasets and semantic views combined. + --- + get: + summary: List datasets and semantic views combined + parameters: + - in: query + name: q + content: + application/json: + schema: + $ref: '#/components/schemas/get_list_schema' + responses: + 200: + description: Combined list of datasets and semantic views + 401: + $ref: '#/components/responses/401' + 403: + $ref: '#/components/responses/403' + 500: + $ref: '#/components/responses/500' + """ + if not security_manager.can_access("can_read", "Dataset"): + return self.response(403, message="Access denied") + + args = kwargs.get("rison", {}) + page = args.get("page", 0) + page_size = args.get("page_size", 25) + order_column = args.get("order_column", "changed_on") + order_direction = args.get("order_direction", "desc") + filters = args.get("filters", []) + + # Extract source_type, name search, sql (type), and type_filter + source_type = "all" + name_filter = None + sql_filter = None # None = no filter, True = physical, False = virtual + type_filter = None # None = no filter, "semantic_view" / True / False + for f in filters: + if f.get("col") == "source_type": + source_type = f.get("value", "all") + elif f.get("col") == "table_name" and f.get("opr") == "ct": + name_filter = f.get("value") + elif f.get("col") == "sql": + val = f.get("value") + if val == "semantic_view": + type_filter = "semantic_view" + else: + sql_filter = val + + # If semantic layers feature flag is off, only show datasets + if not is_feature_enabled("SEMANTIC_LAYERS"): + source_type = "database" + + # Map sort columns + sort_col_map = { + "changed_on_delta_humanized": "changed_on", + "table_name": "table_name", + } + sort_col_name = sort_col_map.get(order_column, "changed_on") + + # Build dataset subquery + ds_q = select( + SqlaTable.id.label("item_id"), + literal("database").label("source_type"), + SqlaTable.changed_on, + SqlaTable.table_name, + ).select_from(SqlaTable.__table__) + + # Apply security filters for datasets + if not security_manager.can_access_all_datasources(): + ds_q = ds_q.join( + sqla_models.Database, + sqla_models.Database.id == SqlaTable.database_id, + ) + ds_q = ds_q.where(get_dataset_access_filters(SqlaTable)) + + # Apply name filter to datasets + if name_filter: + ds_q = ds_q.where(SqlaTable.table_name.ilike(f"%{name_filter}%")) + + # Apply sql (type) filter to datasets + if sql_filter is not None: + if sql_filter: + # Physical: sql is null or empty + ds_q = ds_q.where( + or_(SqlaTable.sql.is_(None), SqlaTable.sql == "") + ) + else: + # Virtual: sql is not null and not empty + ds_q = ds_q.where( + and_(SqlaTable.sql.isnot(None), SqlaTable.sql != "") + ) + # Selecting Physical/Virtual implicitly means "database only" + if source_type == "all": + source_type = "database" + + # Handle type_filter = "semantic_view" + if type_filter == "semantic_view": + source_type = "semantic_layer" + + # Build semantic view subquery + sv_q = select( + SemanticView.id.label("item_id"), + literal("semantic_layer").label("source_type"), + SemanticView.changed_on, + SemanticView.name.label("table_name"), + ).select_from(SemanticView.__table__) + + # Apply name filter to semantic views + if name_filter: + sv_q = sv_q.where(SemanticView.name.ilike(f"%{name_filter}%")) + + # Build combined query based on source_type + if source_type == "database": + combined = ds_q.subquery() + elif source_type == "semantic_layer": + combined = sv_q.subquery() + else: + combined = union_all(ds_q, sv_q).subquery() + + # Count total + count_q = select(func.count()).select_from(combined) + total_count = db.session.execute(count_q).scalar() or 0 + + # Sort and paginate + sort_col = combined.c[sort_col_name] + if order_direction == "desc": + sort_col = sort_col.desc() + else: + sort_col = sort_col.asc() + + paginated_q = ( + select( + combined.c.item_id, + combined.c.source_type, + ) + .order_by(sort_col) + .offset(page * page_size) + .limit(page_size) + ) + rows = db.session.execute(paginated_q).fetchall() + + # Collect IDs by type + dataset_ids = [r.item_id for r in rows if r.source_type == "database"] + sv_ids = [r.item_id for r in rows if r.source_type == "semantic_layer"] + + # Fetch full ORM objects + datasets_map: dict[int, SqlaTable] = {} + if dataset_ids: + ds_objs = ( + db.session.query(SqlaTable) + .filter(SqlaTable.id.in_(dataset_ids)) + .all() + ) + datasets_map = {obj.id: obj for obj in ds_objs} + + sv_map: dict[int, SemanticView] = {} + if sv_ids: + sv_objs = ( + db.session.query(SemanticView) + .filter(SemanticView.id.in_(sv_ids)) + .all() + ) + sv_map = {obj.id: obj for obj in sv_objs} + + # Serialize in UNION order + result = [] + for row in rows: + if row.source_type == "database": + obj = datasets_map.get(row.item_id) + if obj: + result.append(self._serialize_dataset(obj)) + else: + obj = sv_map.get(row.item_id) + if obj: + result.append(self._serialize_semantic_view(obj)) + + return self.response(200, count=total_count, result=result) + + @staticmethod + def _serialize_dataset(obj: SqlaTable) -> dict[str, Any]: + changed_by = obj.changed_by + return { + "id": obj.id, + "uuid": str(obj.uuid), + "table_name": obj.table_name, + "kind": obj.kind, + "source_type": "database", + "description": obj.description, + "explore_url": obj.explore_url, + "database": { + "id": obj.database_id, + "database_name": obj.database.database_name, + } + if obj.database + else None, + "schema": obj.schema, + "sql": obj.sql, + "extra": obj.extra, + "owners": [ + { + "id": o.id, + "first_name": o.first_name, + "last_name": o.last_name, + } + for o in obj.owners + ], + "changed_by_name": obj.changed_by_name, + "changed_by": { + "first_name": changed_by.first_name, + "last_name": changed_by.last_name, + } + if changed_by + else None, + "changed_on_delta_humanized": obj.changed_on_delta_humanized(), + "changed_on_utc": obj.changed_on_utc(), + } + + @staticmethod + def _serialize_semantic_view(obj: SemanticView) -> dict[str, Any]: + changed_by = obj.changed_by + return { + "id": obj.id, + "uuid": str(obj.uuid), + "table_name": obj.name, + "kind": "semantic_view", + "source_type": "semantic_layer", + "description": obj.description, + "cache_timeout": obj.cache_timeout, + "explore_url": obj.explore_url, + "database": None, + "schema": None, + "sql": None, + "extra": None, + "owners": [], + "changed_by_name": obj.changed_by_name, + "changed_by": { + "first_name": changed_by.first_name, + "last_name": changed_by.last_name, + } + if changed_by + else None, + "changed_on_delta_humanized": obj.changed_on_delta_humanized(), + "changed_on_utc": obj.changed_on_utc(), + } diff --git a/superset/semantic_layers/models.py b/superset/semantic_layers/models.py index 6bcc48c6871..7a229485412 100644 --- a/superset/semantic_layers/models.py +++ b/superset/semantic_layers/models.py @@ -205,6 +205,14 @@ class SemanticView(AuditMixinNullable, Model): def get_query_str(self, query_obj: QueryObjectDict) -> str: return "Not implemented for semantic layers" + @property + def table_name(self) -> str: + return self.name + + @property + def kind(self) -> str: + return "semantic_view" + @property def uid(self) -> str: return self.implementation.uid() diff --git a/superset/static/service-worker.js b/superset/static/service-worker.js index 43cb14a4894..85638a05975 100644 --- a/superset/static/service-worker.js +++ b/superset/static/service-worker.js @@ -1,27 +1,1471 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. +/* + * ATTENTION: An "eval-source-map" devtool has been used. + * This devtool is neither made for production nor for readable output files. + * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. + * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) + * or disable the default devtool with "devtool: false". + * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ -// Minimal service worker for PWA file handling support -self.addEventListener('install', event => { - event.waitUntil(self.skipWaiting()); -}); +/***/ "./src/service-worker.ts" +/*!*******************************!*\ + !*** ./src/service-worker.ts ***! + \*******************************/ +() { -self.addEventListener('activate', event => { - event.waitUntil(self.clients.claim()); -}); +eval("{/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements. See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership. The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2 [...] + +/***/ } + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Check if module exists (development only) +/******/ if (__webpack_modules__[moduleId] === undefined) { +/******/ var e = new Error("Cannot find module '" + moduleId + "'"); +/******/ e.code = 'MODULE_NOT_FOUND'; +/******/ throw e; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ id: moduleId, +/******/ loaded: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ }; +/******/ __webpack_require__.i.forEach(function(handler) { handler(execOptions); }); +/******/ module = execOptions.module; +/******/ execOptions.factory.call(module.exports, module, module.exports, execOptions.require); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = __webpack_module_cache__; +/******/ +/******/ // expose the module execution interceptor +/******/ __webpack_require__.i = []; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ (() => { +/******/ var deferred = []; +/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var [chunkIds, fn, priority] = deferred[i]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/compat get default export */ +/******/ (() => { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = (module) => { +/******/ var getter = module && module.__esModule ? +/******/ () => (module['default']) : +/******/ () => (module); +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/create fake namespace object */ +/******/ (() => { +/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); +/******/ var leafPrototypes; +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 16: return value when it's Promise-like +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = this(value); +/******/ if(mode & 8) return value; +/******/ if(typeof value === 'object' && value) { +/******/ if((mode & 4) && value.__esModule) return value; +/******/ if((mode & 16) && typeof value.then === 'function') return value; +/******/ } +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ var def = {}; +/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; +/******/ for(var current = mode & 2 && value; (typeof current == 'object' || typeof current == 'function') && !~leafPrototypes.indexOf(current); current = getProto(current)) { +/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); +/******/ } +/******/ def['default'] = () => (value); +/******/ __webpack_require__.d(ns, def); +/******/ return ns; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get javascript update chunk filename */ +/******/ (() => { +/******/ // This function allow to reference all chunks +/******/ __webpack_require__.hu = (chunkId) => { +/******/ // return url for filenames based on template +/******/ return "" + chunkId + "." + __webpack_require__.h() + ".hot-update.js"; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get update manifest filename */ +/******/ (() => { +/******/ __webpack_require__.hmrF = () => ("service-worker." + __webpack_require__.h() + ".hot-update.json"); +/******/ })(); +/******/ +/******/ /* webpack/runtime/getFullHash */ +/******/ (() => { +/******/ __webpack_require__.h = () => ("87e83073d75b3c4295d1") +/******/ })(); +/******/ +/******/ /* webpack/runtime/harmony module decorator */ +/******/ (() => { +/******/ __webpack_require__.hmd = (module) => { +/******/ module = Object.create(module); +/******/ if (!module.children) module.children = []; +/******/ Object.defineProperty(module, 'exports', { +/******/ enumerable: true, +/******/ set: () => { +/******/ throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id); +/******/ } +/******/ }); +/******/ return module; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/load script */ +/******/ (() => { +/******/ var inProgress = {}; +/******/ var dataWebpackPrefix = "superset:"; +/******/ // loadScript function to load a script via script tag +/******/ __webpack_require__.l = (url, done, key, chunkId) => { +/******/ if(inProgress[url]) { inProgress[url].push(done); return; } +/******/ var script, needAttach; +/******/ if(key !== undefined) { +/******/ var scripts = document.getElementsByTagName("script"); +/******/ for(var i = 0; i < scripts.length; i++) { +/******/ var s = scripts[i]; +/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; } +/******/ } +/******/ } +/******/ if(!script) { +/******/ needAttach = true; +/******/ script = document.createElement('script'); +/******/ +/******/ script.charset = 'utf-8'; +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key); +/******/ +/******/ script.src = url; +/******/ } +/******/ inProgress[url] = [done]; +/******/ var onScriptComplete = (prev, event) => { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var doneFns = inProgress[url]; +/******/ delete inProgress[url]; +/******/ script.parentNode && script.parentNode.removeChild(script); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); +/******/ if(prev) return prev(event); +/******/ } +/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); +/******/ script.onerror = onScriptComplete.bind(null, script.onerror); +/******/ script.onload = onScriptComplete.bind(null, script.onload); +/******/ needAttach && document.head.appendChild(script); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/node module decorator */ +/******/ (() => { +/******/ __webpack_require__.nmd = (module) => { +/******/ module.paths = []; +/******/ if (!module.children) module.children = []; +/******/ return module; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/sharing */ +/******/ (() => { +/******/ __webpack_require__.S = {}; +/******/ var initPromises = {}; +/******/ var initTokens = {}; +/******/ __webpack_require__.I = (name, initScope) => { +/******/ if(!initScope) initScope = []; +/******/ // handling circular init calls +/******/ var initToken = initTokens[name]; +/******/ if(!initToken) initToken = initTokens[name] = {}; +/******/ if(initScope.indexOf(initToken) >= 0) return; +/******/ initScope.push(initToken); +/******/ // only runs once +/******/ if(initPromises[name]) return initPromises[name]; +/******/ // creates a new share scope if needed +/******/ if(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {}; +/******/ // runs all init snippets from all modules reachable +/******/ var scope = __webpack_require__.S[name]; +/******/ var warn = (msg) => { +/******/ if (typeof console !== "undefined" && console.warn) console.warn(msg); +/******/ }; +/******/ var uniqueName = "superset"; +/******/ var register = (name, version, factory, eager) => { +/******/ var versions = scope[name] = scope[name] || {}; +/******/ var activeVersion = versions[version]; +/******/ if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager }; +/******/ }; +/******/ var initExternal = (id) => { +/******/ var handleError = (err) => (warn("Initialization of sharing external failed: " + err)); +/******/ try { +/******/ var module = __webpack_require__(id); +/******/ if(!module) return; +/******/ var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope)) +/******/ if(module.then) return promises.push(module.then(initFn, handleError)); +/******/ var initResult = initFn(module); +/******/ if(initResult && initResult.then) return promises.push(initResult['catch'](handleError)); +/******/ } catch(err) { handleError(err); } +/******/ } +/******/ var promises = []; +/******/ switch(name) { +/******/ case "default": { +/******/ register("antd", "5.27.6", () => (() => (__webpack_require__(/*! ./node_modules/antd/es/index.js */ "./node_modules/antd/es/index.js"))), 1); +/******/ register("react-dom", "17.0.2", () => (() => (__webpack_require__(/*! ./node_modules/react-dom/index.js */ "./node_modules/react-dom/index.js"))), 1); +/******/ register("react", "17.0.2", () => (() => (__webpack_require__(/*! ./node_modules/react/index.js */ "./node_modules/react/index.js"))), 1); +/******/ } +/******/ break; +/******/ } +/******/ if(!promises.length) return initPromises[name] = 1; +/******/ return initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1)); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hot module replacement */ +/******/ (() => { +/******/ var currentModuleData = {}; +/******/ var installedModules = __webpack_require__.c; +/******/ +/******/ // module and require creation +/******/ var currentChildModule; +/******/ var currentParents = []; +/******/ +/******/ // status +/******/ var registeredStatusHandlers = []; +/******/ var currentStatus = "idle"; +/******/ +/******/ // while downloading +/******/ var blockingPromises = 0; +/******/ var blockingPromisesWaiting = []; +/******/ +/******/ // The update info +/******/ var currentUpdateApplyHandlers; +/******/ var queuedInvalidatedModules; +/******/ +/******/ __webpack_require__.hmrD = currentModuleData; +/******/ +/******/ __webpack_require__.i.push(function (options) { +/******/ var module = options.module; +/******/ var require = createRequire(options.require, options.id); +/******/ module.hot = createModuleHotObject(options.id, module); +/******/ module.parents = currentParents; +/******/ module.children = []; +/******/ currentParents = []; +/******/ options.require = require; +/******/ }); +/******/ +/******/ __webpack_require__.hmrC = {}; +/******/ __webpack_require__.hmrI = {}; +/******/ +/******/ function createRequire(require, moduleId) { +/******/ var me = installedModules[moduleId]; +/******/ if (!me) return require; +/******/ var fn = function (request) { +/******/ if (me.hot.active) { +/******/ if (installedModules[request]) { +/******/ var parents = installedModules[request].parents; +/******/ if (parents.indexOf(moduleId) === -1) { +/******/ parents.push(moduleId); +/******/ } +/******/ } else { +/******/ currentParents = [moduleId]; +/******/ currentChildModule = request; +/******/ } +/******/ if (me.children.indexOf(request) === -1) { +/******/ me.children.push(request); +/******/ } +/******/ } else { +/******/ console.warn( +/******/ "[HMR] unexpected require(" + +/******/ request + +/******/ ") from disposed module " + +/******/ moduleId +/******/ ); +/******/ currentParents = []; +/******/ } +/******/ return require(request); +/******/ }; +/******/ var createPropertyDescriptor = function (name) { +/******/ return { +/******/ configurable: true, +/******/ enumerable: true, +/******/ get: function () { +/******/ return require[name]; +/******/ }, +/******/ set: function (value) { +/******/ require[name] = value; +/******/ } +/******/ }; +/******/ }; +/******/ for (var name in require) { +/******/ if (Object.prototype.hasOwnProperty.call(require, name) && name !== "e") { +/******/ Object.defineProperty(fn, name, createPropertyDescriptor(name)); +/******/ } +/******/ } +/******/ fn.e = function (chunkId, fetchPriority) { +/******/ return trackBlockingPromise(require.e(chunkId, fetchPriority)); +/******/ }; +/******/ return fn; +/******/ } +/******/ +/******/ function createModuleHotObject(moduleId, me) { +/******/ var _main = currentChildModule !== moduleId; +/******/ var hot = { +/******/ // private stuff +/******/ _acceptedDependencies: {}, +/******/ _acceptedErrorHandlers: {}, +/******/ _declinedDependencies: {}, +/******/ _selfAccepted: false, +/******/ _selfDeclined: false, +/******/ _selfInvalidated: false, +/******/ _disposeHandlers: [], +/******/ _main: _main, +/******/ _requireSelf: function () { +/******/ currentParents = me.parents.slice(); +/******/ currentChildModule = _main ? undefined : moduleId; +/******/ __webpack_require__(moduleId); +/******/ }, +/******/ +/******/ // Module API +/******/ active: true, +/******/ accept: function (dep, callback, errorHandler) { +/******/ if (dep === undefined) hot._selfAccepted = true; +/******/ else if (typeof dep === "function") hot._selfAccepted = dep; +/******/ else if (typeof dep === "object" && dep !== null) { +/******/ for (var i = 0; i < dep.length; i++) { +/******/ hot._acceptedDependencies[dep[i]] = callback || function () {}; +/******/ hot._acceptedErrorHandlers[dep[i]] = errorHandler; +/******/ } +/******/ } else { +/******/ hot._acceptedDependencies[dep] = callback || function () {}; +/******/ hot._acceptedErrorHandlers[dep] = errorHandler; +/******/ } +/******/ }, +/******/ decline: function (dep) { +/******/ if (dep === undefined) hot._selfDeclined = true; +/******/ else if (typeof dep === "object" && dep !== null) +/******/ for (var i = 0; i < dep.length; i++) +/******/ hot._declinedDependencies[dep[i]] = true; +/******/ else hot._declinedDependencies[dep] = true; +/******/ }, +/******/ dispose: function (callback) { +/******/ hot._disposeHandlers.push(callback); +/******/ }, +/******/ addDisposeHandler: function (callback) { +/******/ hot._disposeHandlers.push(callback); +/******/ }, +/******/ removeDisposeHandler: function (callback) { +/******/ var idx = hot._disposeHandlers.indexOf(callback); +/******/ if (idx >= 0) hot._disposeHandlers.splice(idx, 1); +/******/ }, +/******/ invalidate: function () { +/******/ this._selfInvalidated = true; +/******/ switch (currentStatus) { +/******/ case "idle": +/******/ currentUpdateApplyHandlers = []; +/******/ Object.keys(__webpack_require__.hmrI).forEach(function (key) { +/******/ __webpack_require__.hmrI[key]( +/******/ moduleId, +/******/ currentUpdateApplyHandlers +/******/ ); +/******/ }); +/******/ setStatus("ready"); +/******/ break; +/******/ case "ready": +/******/ Object.keys(__webpack_require__.hmrI).forEach(function (key) { +/******/ __webpack_require__.hmrI[key]( +/******/ moduleId, +/******/ currentUpdateApplyHandlers +/******/ ); +/******/ }); +/******/ break; +/******/ case "prepare": +/******/ case "check": +/******/ case "dispose": +/******/ case "apply": +/******/ (queuedInvalidatedModules = queuedInvalidatedModules || []).push( +/******/ moduleId +/******/ ); +/******/ break; +/******/ default: +/******/ // ignore requests in error states +/******/ break; +/******/ } +/******/ }, +/******/ +/******/ // Management API +/******/ check: hotCheck, +/******/ apply: hotApply, +/******/ status: function (l) { +/******/ if (!l) return currentStatus; +/******/ registeredStatusHandlers.push(l); +/******/ }, +/******/ addStatusHandler: function (l) { +/******/ registeredStatusHandlers.push(l); +/******/ }, +/******/ removeStatusHandler: function (l) { +/******/ var idx = registeredStatusHandlers.indexOf(l); +/******/ if (idx >= 0) registeredStatusHandlers.splice(idx, 1); +/******/ }, +/******/ +/******/ // inherit from previous dispose call +/******/ data: currentModuleData[moduleId] +/******/ }; +/******/ currentChildModule = undefined; +/******/ return hot; +/******/ } +/******/ +/******/ function setStatus(newStatus) { +/******/ currentStatus = newStatus; +/******/ var results = []; +/******/ +/******/ for (var i = 0; i < registeredStatusHandlers.length; i++) +/******/ results[i] = registeredStatusHandlers[i].call(null, newStatus); +/******/ +/******/ return Promise.all(results).then(function () {}); +/******/ } +/******/ +/******/ function unblock() { +/******/ if (--blockingPromises === 0) { +/******/ setStatus("ready").then(function () { +/******/ if (blockingPromises === 0) { +/******/ var list = blockingPromisesWaiting; +/******/ blockingPromisesWaiting = []; +/******/ for (var i = 0; i < list.length; i++) { +/******/ list[i](); +/******/ } +/******/ } +/******/ }); +/******/ } +/******/ } +/******/ +/******/ function trackBlockingPromise(promise) { +/******/ switch (currentStatus) { +/******/ case "ready": +/******/ setStatus("prepare"); +/******/ /* fallthrough */ +/******/ case "prepare": +/******/ blockingPromises++; +/******/ promise.then(unblock, unblock); +/******/ return promise; +/******/ default: +/******/ return promise; +/******/ } +/******/ } +/******/ +/******/ function waitForBlockingPromises(fn) { +/******/ if (blockingPromises === 0) return fn(); +/******/ return new Promise(function (resolve) { +/******/ blockingPromisesWaiting.push(function () { +/******/ resolve(fn()); +/******/ }); +/******/ }); +/******/ } +/******/ +/******/ function hotCheck(applyOnUpdate) { +/******/ if (currentStatus !== "idle") { +/******/ throw new Error("check() is only allowed in idle status"); +/******/ } +/******/ return setStatus("check") +/******/ .then(__webpack_require__.hmrM) +/******/ .then(function (update) { +/******/ if (!update) { +/******/ return setStatus(applyInvalidatedModules() ? "ready" : "idle").then( +/******/ function () { +/******/ return null; +/******/ } +/******/ ); +/******/ } +/******/ +/******/ return setStatus("prepare").then(function () { +/******/ var updatedModules = []; +/******/ currentUpdateApplyHandlers = []; +/******/ +/******/ return Promise.all( +/******/ Object.keys(__webpack_require__.hmrC).reduce(function ( +/******/ promises, +/******/ key +/******/ ) { +/******/ __webpack_require__.hmrC[key]( +/******/ update.c, +/******/ update.r, +/******/ update.m, +/******/ promises, +/******/ currentUpdateApplyHandlers, +/******/ updatedModules, +/******/ update.css +/******/ ); +/******/ return promises; +/******/ }, []) +/******/ ).then(function () { +/******/ return waitForBlockingPromises(function () { +/******/ if (applyOnUpdate) { +/******/ return internalApply(applyOnUpdate); +/******/ } +/******/ return setStatus("ready").then(function () { +/******/ return updatedModules; +/******/ }); +/******/ }); +/******/ }); +/******/ }); +/******/ }); +/******/ } +/******/ +/******/ function hotApply(options) { +/******/ if (currentStatus !== "ready") { +/******/ return Promise.resolve().then(function () { +/******/ throw new Error( +/******/ "apply() is only allowed in ready status (state: " + +/******/ currentStatus + +/******/ ")" +/******/ ); +/******/ }); +/******/ } +/******/ return internalApply(options); +/******/ } +/******/ +/******/ function internalApply(options) { +/******/ options = options || {}; +/******/ +/******/ applyInvalidatedModules(); +/******/ +/******/ var results = currentUpdateApplyHandlers.map(function (handler) { +/******/ return handler(options); +/******/ }); +/******/ currentUpdateApplyHandlers = undefined; +/******/ +/******/ var errors = results +/******/ .map(function (r) { +/******/ return r.error; +/******/ }) +/******/ .filter(Boolean); +/******/ +/******/ if (errors.length > 0) { +/******/ return setStatus("abort").then(function () { +/******/ throw errors[0]; +/******/ }); +/******/ } +/******/ +/******/ // Now in "dispose" phase +/******/ var disposePromise = setStatus("dispose"); +/******/ +/******/ results.forEach(function (result) { +/******/ if (result.dispose) result.dispose(); +/******/ }); +/******/ +/******/ // Now in "apply" phase +/******/ var applyPromise = setStatus("apply"); +/******/ +/******/ var error; +/******/ var reportError = function (err) { +/******/ if (!error) error = err; +/******/ }; +/******/ +/******/ var outdatedModules = []; +/******/ +/******/ var onAccepted = function () { +/******/ return Promise.all([disposePromise, applyPromise]).then(function () { +/******/ // handle errors in accept handlers and self accepted module load +/******/ if (error) { +/******/ return setStatus("fail").then(function () { +/******/ throw error; +/******/ }); +/******/ } +/******/ +/******/ if (queuedInvalidatedModules) { +/******/ return internalApply(options).then(function (list) { +/******/ outdatedModules.forEach(function (moduleId) { +/******/ if (list.indexOf(moduleId) < 0) list.push(moduleId); +/******/ }); +/******/ return list; +/******/ }); +/******/ } +/******/ +/******/ return setStatus("idle").then(function () { +/******/ return outdatedModules; +/******/ }); +/******/ }); +/******/ }; +/******/ +/******/ return Promise.all( +/******/ results +/******/ .filter(function (result) { +/******/ return result.apply; +/******/ }) +/******/ .map(function (result) { +/******/ return result.apply(reportError); +/******/ }) +/******/ ) +/******/ .then(function (applyResults) { +/******/ applyResults.forEach(function (modules) { +/******/ if (modules) { +/******/ for (var i = 0; i < modules.length; i++) { +/******/ outdatedModules.push(modules[i]); +/******/ } +/******/ } +/******/ }); +/******/ }) +/******/ .then(onAccepted); +/******/ } +/******/ +/******/ function applyInvalidatedModules() { +/******/ if (queuedInvalidatedModules) { +/******/ if (!currentUpdateApplyHandlers) currentUpdateApplyHandlers = []; +/******/ Object.keys(__webpack_require__.hmrI).forEach(function (key) { +/******/ queuedInvalidatedModules.forEach(function (moduleId) { +/******/ __webpack_require__.hmrI[key]( +/******/ moduleId, +/******/ currentUpdateApplyHandlers +/******/ ); +/******/ }); +/******/ }); +/******/ queuedInvalidatedModules = undefined; +/******/ return true; +/******/ } +/******/ } +/******/ })(); +/******/ +/******/ /* webpack/runtime/publicPath */ +/******/ (() => { +/******/ __webpack_require__.p = "/static/assets/"; +/******/ })(); +/******/ +/******/ /* webpack/runtime/react refresh */ +/******/ (() => { +/******/ const setup = (moduleId) => { +/******/ const refresh = { +/******/ moduleId: moduleId, +/******/ register: (type, id) => { +/******/ const typeId = moduleId + ' ' + id; +/******/ refresh.runtime.register(type, typeId); +/******/ }, +/******/ signature: () => (refresh.runtime.createSignatureFunctionForTransform()), +/******/ runtime: { +/******/ createSignatureFunctionForTransform: () => ((type) => (type)), +/******/ register: x => {} +/******/ }, +/******/ }; +/******/ return refresh; +/******/ }; +/******/ +/******/ __webpack_require__.i.push((options) => { +/******/ const originalFactory = options.factory; +/******/ options.factory = function(moduleObject, moduleExports, webpackRequire) { +/******/ const hotRequire = (request) => (webpackRequire(request)); +/******/ const createPropertyDescriptor = (name) => { +/******/ return { +/******/ configurable: true, +/******/ enumerable: true, +/******/ get: () => (webpackRequire[name]), +/******/ set: (value) => { +/******/ webpackRequire[name] = value; +/******/ }, +/******/ }; +/******/ }; +/******/ for (const name in webpackRequire) { +/******/ if (name === "$Refresh$") continue; +/******/ if (Object.prototype.hasOwnProperty.call(webpackRequire, name)) { +/******/ Object.defineProperty(hotRequire, name, createPropertyDescriptor(name)); +/******/ } +/******/ } +/******/ hotRequire.$Refresh$ = setup(options.id); +/******/ originalFactory.call(this, moduleObject, moduleExports, hotRequire); +/******/ }; +/******/ }); +/******/ })(); +/******/ +/******/ /* webpack/runtime/consumes */ +/******/ (() => { +/******/ var parseVersion = (str) => { +/******/ // see webpack/lib/util/semver.js for original code +/******/ var p=p=>{return p.split(".").map(p=>{return+p==p?+p:p})},n=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r; +/******/ } +/******/ var versionLt = (a, b) => { +/******/ // see webpack/lib/util/semver.js for original code +/******/ a=parseVersion(a),b=parseVersion(b);for(var r=0;;){if(r>=a.length)return r<b.length&&"u"!=(typeof b[r])[0];var e=a[r],n=(typeof e)[0];if(r>=b.length)return"u"==n;var t=b[r],f=(typeof t)[0];if(n!=f)return"o"==n&&"n"==f||("s"==f||"u"==n);if("o"!=n&&"u"!=n&&e!=t)return e<t;r++} +/******/ } +/******/ var rangeToString = (range) => { +/******/ // see webpack/lib/util/semver.js for original code +/******/ var r=range[0],n="";if(1===range.length)return"*";if(r+.5){n+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a<range.length;a++){e--,n+="u"==(typeof(t=range[a]))[0]?"-":(e>0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a<range.length;a++){var t=range[a];g.push(0===t?"not("+o()+")":1===t?"("+o()+" || "+o()+")":2===t?g.pop()+" "+g.pop():rangeToString(t))}return o();function o(){return g.pop().replace(/^\((.+)\)$/,"$1")} +/******/ } +/******/ var satisfy = (range, version) => { +/******/ // see webpack/lib/util/semver.js for original code +/******/ if(0 in range){version=parseVersion(version);var e=range[0],r=e<0;r&&(e=-e-1);for(var n=0,i=1,a=!0;;i++,n++){var f,s,g=i<range.length?(typeof range[i])[0]:"";if(n>=version.length||"o"==(s=(typeof(f=version[n]))[0]))return!a||("u"==g?i>e&&!r:""==g!=r);if("u"==s){if(!a||"u"!=g)return!1}else if(a)if(g==s)if(i<=e){if(f!=range[i])return!1}else{if(r?f>range[i]:f<range[i])return!1;f!=range[i]&&(a=!1)}else if("s"!=g&&"n"!=g){if(r||i<=e)return!1;a=!1,i--}else{if(i<=e||s<g!=r)return!1; [...] +/******/ } +/******/ var exists = (scope, key) => { +/******/ return scope && __webpack_require__.o(scope, key); +/******/ } +/******/ var get = (entry) => { +/******/ entry.loaded = 1; +/******/ return entry.get() +/******/ }; +/******/ var eagerOnly = (versions) => { +/******/ return Object.keys(versions).reduce((filtered, version) => { +/******/ if (versions[version].eager) { +/******/ filtered[version] = versions[version]; +/******/ } +/******/ return filtered; +/******/ }, {}); +/******/ }; +/******/ var findLatestVersion = (scope, key, eager) => { +/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key]; +/******/ var key = Object.keys(versions).reduce((a, b) => { +/******/ return !a || versionLt(a, b) ? b : a; +/******/ }, 0); +/******/ return key && versions[key]; +/******/ }; +/******/ var findSatisfyingVersion = (scope, key, requiredVersion, eager) => { +/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key]; +/******/ var key = Object.keys(versions).reduce((a, b) => { +/******/ if (!satisfy(requiredVersion, b)) return a; +/******/ return !a || versionLt(a, b) ? b : a; +/******/ }, 0); +/******/ return key && versions[key] +/******/ }; +/******/ var findSingletonVersionKey = (scope, key, eager) => { +/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key]; +/******/ return Object.keys(versions).reduce((a, b) => { +/******/ return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a; +/******/ }, 0); +/******/ }; +/******/ var getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => { +/******/ return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")" +/******/ }; +/******/ var getInvalidVersionMessage = (scope, scopeName, key, requiredVersion, eager) => { +/******/ var versions = scope[key]; +/******/ return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\n" + +/******/ "Available versions: " + Object.keys(versions).map((key) => { +/******/ return key + " from " + versions[key].from; +/******/ }).join(", "); +/******/ }; +/******/ var fail = (msg) => { +/******/ throw new Error(msg); +/******/ } +/******/ var failAsNotExist = (scopeName, key) => { +/******/ return fail("Shared module " + key + " doesn't exist in shared scope " + scopeName); +/******/ } +/******/ var warn = /*#__PURE__*/ (msg) => { +/******/ if (typeof console !== "undefined" && console.warn) console.warn(msg); +/******/ }; +/******/ var init = (fn) => (function(scopeName, key, eager, c, d) { +/******/ var promise = __webpack_require__.I(scopeName); +/******/ if (promise && promise.then && !eager) { +/******/ return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], key, false, c, d)); +/******/ } +/******/ return fn(scopeName, __webpack_require__.S[scopeName], key, eager, c, d); +/******/ }); +/******/ +/******/ var useFallback = (scopeName, key, fallback) => { +/******/ return fallback ? fallback() : failAsNotExist(scopeName, key); +/******/ } +/******/ var load = /*#__PURE__*/ init((scopeName, scope, key, eager, fallback) => { +/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback); +/******/ return get(findLatestVersion(scope, key, eager)); +/******/ }); +/******/ var loadVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => { +/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback); +/******/ var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager); +/******/ if (satisfyingVersion) return get(satisfyingVersion); +/******/ warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager)) +/******/ return get(findLatestVersion(scope, key, eager)); +/******/ }); +/******/ var loadStrictVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => { +/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback); +/******/ var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager); +/******/ if (satisfyingVersion) return get(satisfyingVersion); +/******/ if (fallback) return fallback(); +/******/ fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager)); +/******/ }); +/******/ var loadSingleton = /*#__PURE__*/ init((scopeName, scope, key, eager, fallback) => { +/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback); +/******/ var version = findSingletonVersionKey(scope, key, eager); +/******/ return get(scope[key][version]); +/******/ }); +/******/ var loadSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => { +/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback); +/******/ var version = findSingletonVersionKey(scope, key, eager); +/******/ if (!satisfy(requiredVersion, version)) { +/******/ warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); +/******/ } +/******/ return get(scope[key][version]); +/******/ }); +/******/ var loadStrictSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => { +/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback); +/******/ var version = findSingletonVersionKey(scope, key, eager); +/******/ if (!satisfy(requiredVersion, version)) { +/******/ fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); +/******/ } +/******/ return get(scope[key][version]); +/******/ }); +/******/ var installedModules = {}; +/******/ var moduleToHandlerMapping = { +/******/ "webpack/sharing/consume/default/react-dom/react-dom": () => (loadSingletonVersion("default", "react-dom", true, [1,17,0,2], () => (() => (__webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js"))))), +/******/ "webpack/sharing/consume/default/react/react": () => (loadSingletonVersion("default", "react", true, [1,17,0,2], () => (() => (__webpack_require__(/*! react */ "./node_modules/react/index.js"))))) +/******/ }; +/******/ var initialConsumes = ["webpack/sharing/consume/default/react-dom/react-dom","webpack/sharing/consume/default/react/react"]; +/******/ initialConsumes.forEach((id) => { +/******/ __webpack_require__.m[id] = (module) => { +/******/ // Handle case when module is used sync +/******/ installedModules[id] = 0; +/******/ delete __webpack_require__.c[id]; +/******/ var factory = moduleToHandlerMapping[id](); +/******/ if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id); +/******/ module.exports = factory(); +/******/ } +/******/ }); +/******/ // no chunk loading of consumes +/******/ })(); +/******/ +/******/ /* webpack/runtime/jsonp chunk loading */ +/******/ (() => { +/******/ // no baseURI +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = __webpack_require__.hmrS_jsonp = __webpack_require__.hmrS_jsonp || { +/******/ "service-worker": 0, +/******/ "webpack_sharing_consume_default_react-dom_react-dom-webpack_sharing_consume_default_react_rea-153fef": 0 +/******/ }; +/******/ +/******/ // no chunk on demand loading +/******/ +/******/ // no prefetching +/******/ +/******/ // no preloaded +/******/ +/******/ var currentUpdatedModulesList; +/******/ var waitingUpdateResolves = {}; +/******/ function loadUpdateChunk(chunkId, updatedModulesList) { +/******/ currentUpdatedModulesList = updatedModulesList; +/******/ return new Promise((resolve, reject) => { +/******/ waitingUpdateResolves[chunkId] = resolve; +/******/ // start update chunk loading +/******/ var url = __webpack_require__.p + __webpack_require__.hu(chunkId); +/******/ // create error before stack unwound to get useful stacktrace later +/******/ var error = new Error(); +/******/ var loadingEnded = (event) => { +/******/ if(waitingUpdateResolves[chunkId]) { +/******/ waitingUpdateResolves[chunkId] = undefined +/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); +/******/ var realSrc = event && event.target && event.target.src; +/******/ error.message = 'Loading hot update chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; +/******/ error.name = 'ChunkLoadError'; +/******/ error.type = errorType; +/******/ error.request = realSrc; +/******/ reject(error); +/******/ } +/******/ }; +/******/ __webpack_require__.l(url, loadingEnded); +/******/ }); +/******/ } +/******/ +/******/ globalThis["webpackHotUpdatesuperset"] = (chunkId, moreModules, runtime) => { +/******/ for(var moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ currentUpdate[moduleId] = moreModules[moduleId]; +/******/ if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId); +/******/ } +/******/ } +/******/ if(runtime) currentUpdateRuntime.push(runtime); +/******/ if(waitingUpdateResolves[chunkId]) { +/******/ waitingUpdateResolves[chunkId](); +/******/ waitingUpdateResolves[chunkId] = undefined; +/******/ } +/******/ }; +/******/ +/******/ var currentUpdateChunks; +/******/ var currentUpdate; +/******/ var currentUpdateRemovedChunks; +/******/ var currentUpdateRuntime; +/******/ function applyHandler(options) { +/******/ if (__webpack_require__.f) delete __webpack_require__.f.jsonpHmr; +/******/ currentUpdateChunks = undefined; +/******/ function getAffectedModuleEffects(updateModuleId) { +/******/ var outdatedModules = [updateModuleId]; +/******/ var outdatedDependencies = {}; +/******/ +/******/ var queue = outdatedModules.map(function (id) { +/******/ return { +/******/ chain: [id], +/******/ id: id +/******/ }; +/******/ }); +/******/ while (queue.length > 0) { +/******/ var queueItem = queue.pop(); +/******/ var moduleId = queueItem.id; +/******/ var chain = queueItem.chain; +/******/ var module = __webpack_require__.c[moduleId]; +/******/ if ( +/******/ !module || +/******/ (module.hot._selfAccepted && !module.hot._selfInvalidated) +/******/ ) +/******/ continue; +/******/ if (module.hot._selfDeclined) { +/******/ return { +/******/ type: "self-declined", +/******/ chain: chain, +/******/ moduleId: moduleId +/******/ }; +/******/ } +/******/ if (module.hot._main) { +/******/ return { +/******/ type: "unaccepted", +/******/ chain: chain, +/******/ moduleId: moduleId +/******/ }; +/******/ } +/******/ for (var i = 0; i < module.parents.length; i++) { +/******/ var parentId = module.parents[i]; +/******/ var parent = __webpack_require__.c[parentId]; +/******/ if (!parent) continue; +/******/ if (parent.hot._declinedDependencies[moduleId]) { +/******/ return { +/******/ type: "declined", +/******/ chain: chain.concat([parentId]), +/******/ moduleId: moduleId, +/******/ parentId: parentId +/******/ }; +/******/ } +/******/ if (outdatedModules.indexOf(parentId) !== -1) continue; +/******/ if (parent.hot._acceptedDependencies[moduleId]) { +/******/ if (!outdatedDependencies[parentId]) +/******/ outdatedDependencies[parentId] = []; +/******/ addAllToSet(outdatedDependencies[parentId], [moduleId]); +/******/ continue; +/******/ } +/******/ delete outdatedDependencies[parentId]; +/******/ outdatedModules.push(parentId); +/******/ queue.push({ +/******/ chain: chain.concat([parentId]), +/******/ id: parentId +/******/ }); +/******/ } +/******/ } +/******/ +/******/ return { +/******/ type: "accepted", +/******/ moduleId: updateModuleId, +/******/ outdatedModules: outdatedModules, +/******/ outdatedDependencies: outdatedDependencies +/******/ }; +/******/ } +/******/ +/******/ function addAllToSet(a, b) { +/******/ for (var i = 0; i < b.length; i++) { +/******/ var item = b[i]; +/******/ if (a.indexOf(item) === -1) a.push(item); +/******/ } +/******/ } +/******/ +/******/ // at begin all updates modules are outdated +/******/ // the "outdated" status can propagate to parents if they don't accept the children +/******/ var outdatedDependencies = {}; +/******/ var outdatedModules = []; +/******/ var appliedUpdate = {}; +/******/ +/******/ var warnUnexpectedRequire = function warnUnexpectedRequire(module) { +/******/ console.warn( +/******/ "[HMR] unexpected require(" + module.id + ") to disposed module" +/******/ ); +/******/ }; +/******/ +/******/ for (var moduleId in currentUpdate) { +/******/ if (__webpack_require__.o(currentUpdate, moduleId)) { +/******/ var newModuleFactory = currentUpdate[moduleId]; +/******/ var result = newModuleFactory +/******/ ? getAffectedModuleEffects(moduleId) +/******/ : { +/******/ type: "disposed", +/******/ moduleId: moduleId +/******/ }; +/******/ /** @type {Error|false} */ +/******/ var abortError = false; +/******/ var doApply = false; +/******/ var doDispose = false; +/******/ var chainInfo = ""; +/******/ if (result.chain) { +/******/ chainInfo = "\nUpdate propagation: " + result.chain.join(" -> "); +/******/ } +/******/ switch (result.type) { +/******/ case "self-declined": +/******/ if (options.onDeclined) options.onDeclined(result); +/******/ if (!options.ignoreDeclined) +/******/ abortError = new Error( +/******/ "Aborted because of self decline: " + +/******/ result.moduleId + +/******/ chainInfo +/******/ ); +/******/ break; +/******/ case "declined": +/******/ if (options.onDeclined) options.onDeclined(result); +/******/ if (!options.ignoreDeclined) +/******/ abortError = new Error( +/******/ "Aborted because of declined dependency: " + +/******/ result.moduleId + +/******/ " in " + +/******/ result.parentId + +/******/ chainInfo +/******/ ); +/******/ break; +/******/ case "unaccepted": +/******/ if (options.onUnaccepted) options.onUnaccepted(result); +/******/ if (!options.ignoreUnaccepted) +/******/ abortError = new Error( +/******/ "Aborted because " + moduleId + " is not accepted" + chainInfo +/******/ ); +/******/ break; +/******/ case "accepted": +/******/ if (options.onAccepted) options.onAccepted(result); +/******/ doApply = true; +/******/ break; +/******/ case "disposed": +/******/ if (options.onDisposed) options.onDisposed(result); +/******/ doDispose = true; +/******/ break; +/******/ default: +/******/ throw new Error("Unexception type " + result.type); +/******/ } +/******/ if (abortError) { +/******/ return { +/******/ error: abortError +/******/ }; +/******/ } +/******/ if (doApply) { +/******/ appliedUpdate[moduleId] = newModuleFactory; +/******/ addAllToSet(outdatedModules, result.outdatedModules); +/******/ for (moduleId in result.outdatedDependencies) { +/******/ if (__webpack_require__.o(result.outdatedDependencies, moduleId)) { +/******/ if (!outdatedDependencies[moduleId]) +/******/ outdatedDependencies[moduleId] = []; +/******/ addAllToSet( +/******/ outdatedDependencies[moduleId], +/******/ result.outdatedDependencies[moduleId] +/******/ ); +/******/ } +/******/ } +/******/ } +/******/ if (doDispose) { +/******/ addAllToSet(outdatedModules, [result.moduleId]); +/******/ appliedUpdate[moduleId] = warnUnexpectedRequire; +/******/ } +/******/ } +/******/ } +/******/ currentUpdate = undefined; +/******/ +/******/ // Store self accepted outdated modules to require them later by the module system +/******/ var outdatedSelfAcceptedModules = []; +/******/ for (var j = 0; j < outdatedModules.length; j++) { +/******/ var outdatedModuleId = outdatedModules[j]; +/******/ var module = __webpack_require__.c[outdatedModuleId]; +/******/ if ( +/******/ module && +/******/ (module.hot._selfAccepted || module.hot._main) && +/******/ // removed self-accepted modules should not be required +/******/ appliedUpdate[outdatedModuleId] !== warnUnexpectedRequire && +/******/ // when called invalidate self-accepting is not possible +/******/ !module.hot._selfInvalidated +/******/ ) { +/******/ outdatedSelfAcceptedModules.push({ +/******/ module: outdatedModuleId, +/******/ require: module.hot._requireSelf, +/******/ errorHandler: module.hot._selfAccepted +/******/ }); +/******/ } +/******/ } +/******/ +/******/ var moduleOutdatedDependencies; +/******/ +/******/ return { +/******/ dispose: function () { +/******/ currentUpdateRemovedChunks.forEach(function (chunkId) { +/******/ delete installedChunks[chunkId]; +/******/ }); +/******/ currentUpdateRemovedChunks = undefined; +/******/ +/******/ var idx; +/******/ var queue = outdatedModules.slice(); +/******/ while (queue.length > 0) { +/******/ var moduleId = queue.pop(); +/******/ var module = __webpack_require__.c[moduleId]; +/******/ if (!module) continue; +/******/ +/******/ var data = {}; +/******/ +/******/ // Call dispose handlers +/******/ var disposeHandlers = module.hot._disposeHandlers; +/******/ for (j = 0; j < disposeHandlers.length; j++) { +/******/ disposeHandlers[j].call(null, data); +/******/ } +/******/ __webpack_require__.hmrD[moduleId] = data; +/******/ +/******/ // disable module (this disables requires from this module) +/******/ module.hot.active = false; +/******/ +/******/ // remove module from cache +/******/ delete __webpack_require__.c[moduleId]; +/******/ +/******/ // when disposing there is no need to call dispose handler +/******/ delete outdatedDependencies[moduleId]; +/******/ +/******/ // remove "parents" references from all children +/******/ for (j = 0; j < module.children.length; j++) { +/******/ var child = __webpack_require__.c[module.children[j]]; +/******/ if (!child) continue; +/******/ idx = child.parents.indexOf(moduleId); +/******/ if (idx >= 0) { +/******/ child.parents.splice(idx, 1); +/******/ } +/******/ } +/******/ } +/******/ +/******/ // remove outdated dependency from module children +/******/ var dependency; +/******/ for (var outdatedModuleId in outdatedDependencies) { +/******/ if (__webpack_require__.o(outdatedDependencies, outdatedModuleId)) { +/******/ module = __webpack_require__.c[outdatedModuleId]; +/******/ if (module) { +/******/ moduleOutdatedDependencies = +/******/ outdatedDependencies[outdatedModuleId]; +/******/ for (j = 0; j < moduleOutdatedDependencies.length; j++) { +/******/ dependency = moduleOutdatedDependencies[j]; +/******/ idx = module.children.indexOf(dependency); +/******/ if (idx >= 0) module.children.splice(idx, 1); +/******/ } +/******/ } +/******/ } +/******/ } +/******/ }, +/******/ apply: function (reportError) { +/******/ var acceptPromises = []; +/******/ // insert new code +/******/ for (var updateModuleId in appliedUpdate) { +/******/ if (__webpack_require__.o(appliedUpdate, updateModuleId)) { +/******/ __webpack_require__.m[updateModuleId] = appliedUpdate[updateModuleId]; +/******/ } +/******/ } +/******/ +/******/ // run new runtime modules +/******/ for (var i = 0; i < currentUpdateRuntime.length; i++) { +/******/ currentUpdateRuntime[i](__webpack_require__); +/******/ } +/******/ +/******/ // call accept handlers +/******/ for (var outdatedModuleId in outdatedDependencies) { +/******/ if (__webpack_require__.o(outdatedDependencies, outdatedModuleId)) { +/******/ var module = __webpack_require__.c[outdatedModuleId]; +/******/ if (module) { +/******/ moduleOutdatedDependencies = +/******/ outdatedDependencies[outdatedModuleId]; +/******/ var callbacks = []; +/******/ var errorHandlers = []; +/******/ var dependenciesForCallbacks = []; +/******/ for (var j = 0; j < moduleOutdatedDependencies.length; j++) { +/******/ var dependency = moduleOutdatedDependencies[j]; +/******/ var acceptCallback = +/******/ module.hot._acceptedDependencies[dependency]; +/******/ var errorHandler = +/******/ module.hot._acceptedErrorHandlers[dependency]; +/******/ if (acceptCallback) { +/******/ if (callbacks.indexOf(acceptCallback) !== -1) continue; +/******/ callbacks.push(acceptCallback); +/******/ errorHandlers.push(errorHandler); +/******/ dependenciesForCallbacks.push(dependency); +/******/ } +/******/ } +/******/ for (var k = 0; k < callbacks.length; k++) { +/******/ var result; +/******/ try { +/******/ result = callbacks[k].call(null, moduleOutdatedDependencies); +/******/ } catch (err) { +/******/ if (typeof errorHandlers[k] === "function") { +/******/ try { +/******/ errorHandlers[k](err, { +/******/ moduleId: outdatedModuleId, +/******/ dependencyId: dependenciesForCallbacks[k] +/******/ }); +/******/ } catch (err2) { +/******/ if (options.onErrored) { +/******/ options.onErrored({ +/******/ type: "accept-error-handler-errored", +/******/ moduleId: outdatedModuleId, +/******/ dependencyId: dependenciesForCallbacks[k], +/******/ error: err2, +/******/ originalError: err +/******/ }); +/******/ } +/******/ if (!options.ignoreErrored) { +/******/ reportError(err2); +/******/ reportError(err); +/******/ } +/******/ } +/******/ } else { +/******/ if (options.onErrored) { +/******/ options.onErrored({ +/******/ type: "accept-errored", +/******/ moduleId: outdatedModuleId, +/******/ dependencyId: dependenciesForCallbacks[k], +/******/ error: err +/******/ }); +/******/ } +/******/ if (!options.ignoreErrored) { +/******/ reportError(err); +/******/ } +/******/ } +/******/ } +/******/ if (result && typeof result.then === "function") { +/******/ acceptPromises.push(result); +/******/ } +/******/ } +/******/ } +/******/ } +/******/ } +/******/ +/******/ var onAccepted = function () { +/******/ // Load self accepted modules +/******/ for (var o = 0; o < outdatedSelfAcceptedModules.length; o++) { +/******/ var item = outdatedSelfAcceptedModules[o]; +/******/ var moduleId = item.module; +/******/ try { +/******/ item.require(moduleId); +/******/ } catch (err) { +/******/ if (typeof item.errorHandler === "function") { +/******/ try { +/******/ item.errorHandler(err, { +/******/ moduleId: moduleId, +/******/ module: __webpack_require__.c[moduleId] +/******/ }); +/******/ } catch (err1) { +/******/ if (options.onErrored) { +/******/ options.onErrored({ +/******/ type: "self-accept-error-handler-errored", +/******/ moduleId: moduleId, +/******/ error: err1, +/******/ originalError: err +/******/ }); +/******/ } +/******/ if (!options.ignoreErrored) { +/******/ reportError(err1); +/******/ reportError(err); +/******/ } +/******/ } +/******/ } else { +/******/ if (options.onErrored) { +/******/ options.onErrored({ +/******/ type: "self-accept-errored", +/******/ moduleId: moduleId, +/******/ error: err +/******/ }); +/******/ } +/******/ if (!options.ignoreErrored) { +/******/ reportError(err); +/******/ } +/******/ } +/******/ } +/******/ } +/******/ }; +/******/ +/******/ return Promise.all(acceptPromises) +/******/ .then(onAccepted) +/******/ .then(function () { +/******/ return outdatedModules; +/******/ }); +/******/ } +/******/ }; +/******/ } +/******/ __webpack_require__.hmrI.jsonp = function (moduleId, applyHandlers) { +/******/ if (!currentUpdate) { +/******/ currentUpdate = {}; +/******/ currentUpdateRuntime = []; +/******/ currentUpdateRemovedChunks = []; +/******/ applyHandlers.push(applyHandler); +/******/ } +/******/ if (!__webpack_require__.o(currentUpdate, moduleId)) { +/******/ currentUpdate[moduleId] = __webpack_require__.m[moduleId]; +/******/ } +/******/ }; +/******/ __webpack_require__.hmrC.jsonp = function ( +/******/ chunkIds, +/******/ removedChunks, +/******/ removedModules, +/******/ promises, +/******/ applyHandlers, +/******/ updatedModulesList +/******/ ) { +/******/ applyHandlers.push(applyHandler); +/******/ currentUpdateChunks = {}; +/******/ currentUpdateRemovedChunks = removedChunks; +/******/ currentUpdate = removedModules.reduce(function (obj, key) { +/******/ obj[key] = false; +/******/ return obj; +/******/ }, {}); +/******/ currentUpdateRuntime = []; +/******/ chunkIds.forEach(function (chunkId) { +/******/ if ( +/******/ __webpack_require__.o(installedChunks, chunkId) && +/******/ installedChunks[chunkId] !== undefined +/******/ ) { +/******/ promises.push(loadUpdateChunk(chunkId, updatedModulesList)); +/******/ currentUpdateChunks[chunkId] = true; +/******/ } else { +/******/ currentUpdateChunks[chunkId] = false; +/******/ } +/******/ }); +/******/ if (__webpack_require__.f) { +/******/ __webpack_require__.f.jsonpHmr = function (chunkId, promises) { +/******/ if ( +/******/ currentUpdateChunks && +/******/ __webpack_require__.o(currentUpdateChunks, chunkId) && +/******/ !currentUpdateChunks[chunkId] +/******/ ) { +/******/ promises.push(loadUpdateChunk(chunkId)); +/******/ currentUpdateChunks[chunkId] = true; +/******/ } +/******/ }; +/******/ } +/******/ }; +/******/ +/******/ __webpack_require__.hmrM = () => { +/******/ if (typeof fetch === "undefined") throw new Error("No browser support: need fetch API"); +/******/ return fetch(__webpack_require__.p + __webpack_require__.hmrF()).then((response) => { +/******/ if(response.status === 404) return; // no update available +/******/ if(!response.ok) throw new Error("Failed to fetch update manifest " + response.statusText); +/******/ return response.json(); +/******/ }); +/******/ }; +/******/ +/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); +/******/ +/******/ // install a JSONP callback for chunk loading +/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { +/******/ var [chunkIds, moreModules, runtime] = data; +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ return __webpack_require__.O(result); +/******/ } +/******/ +/******/ var chunkLoadingGlobal = globalThis["webpackChunksuperset"] = globalThis["webpackChunksuperset"] || []; +/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); +/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); +/******/ })(); +/******/ +/************************************************************************/ +/******/ +/******/ // module cache are used so entry inlining is disabled +/******/ // startup +/******/ // Load entry module and return exports +/******/ __webpack_require__.O(undefined, ["vendors","vendors-node_modules_rc-component_color-picker_es_index_js-node_modules_rc-component_mutate-o-484854","webpack_sharing_consume_default_react-dom_react-dom-webpack_sharing_consume_default_react_rea-153fef"], () => (__webpack_require__("./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js"))) +/******/ __webpack_require__.O(undefined, ["vendors","vendors-node_modules_rc-component_color-picker_es_index_js-node_modules_rc-component_mutate-o-484854","webpack_sharing_consume_default_react-dom_react-dom-webpack_sharing_consume_default_react_rea-153fef"], () => (__webpack_require__("./node_modules/webpack-dev-server/client/index.js?protocol=ws%3A&hostname=0.0.0.0&port=0&pathname=%2Fws&logging=info&overlay=%7B%22errors%22%3Atrue%2C%22warnings%22%3Afalse%2C%22runtimeErrors%22%3A%22er [...] +/******/ __webpack_require__.O(undefined, ["vendors","vendors-node_modules_rc-component_color-picker_es_index_js-node_modules_rc-component_mutate-o-484854","webpack_sharing_consume_default_react-dom_react-dom-webpack_sharing_consume_default_react_rea-153fef"], () => (__webpack_require__("./node_modules/webpack/hot/only-dev-server.js"))) +/******/ __webpack_require__.O(undefined, ["vendors","vendors-node_modules_rc-component_color-picker_es_index_js-node_modules_rc-component_mutate-o-484854","webpack_sharing_consume_default_react-dom_react-dom-webpack_sharing_consume_default_react_rea-153fef"], () => (__webpack_require__("./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ErrorOverlayEntry.js"))) +/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["vendors","vendors-node_modules_rc-component_color-picker_es_index_js-node_modules_rc-component_mutate-o-484854","webpack_sharing_consume_default_react-dom_react-dom-webpack_sharing_consume_default_react_rea-153fef"], () => (__webpack_require__("./src/service-worker.ts"))) +/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); +/******/ +/******/ })() +; \ No newline at end of file
