import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed 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 { DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH, useApplicationStore, } from '@finos/legend-application';
import { Tooltip, DollarIcon, clsx, InfoCircleIcon, RefreshIcon, CheckSquareIcon, SquareIcon, CustomSelectorInput, SaveIcon, PencilIcon, DragPreviewLayer, CalculateIcon, InputWithInlineValidation, CopyIcon, } from '@finos/legend-art';
import { CollectionInstanceValue, Enumeration, EnumValueExplicitReference, EnumValueInstanceValue, GenericType, GenericTypeExplicitReference, getCorrespondingStandardPrimitiveType, getMultiplicityDescription, getPrimitiveTypeInstanceFromEnum, InstanceValue, INTERNAL__PropagatedValue, isSubType, matchFunctionName, PRIMITIVE_TYPE, PrecisePrimitiveType, PrimitiveInstanceValue, PrimitiveType, SimpleFunctionExpression, Type, VariableExpression, observe_ValueSpecification, V1_PackageableType, } from '@finos/legend-graph';
import { guaranteeNonNullable, isNonNullable, guaranteeIsNumber, csvStringify, guaranteeType, isNonEmptyString, parseCSVString, uniq, } from '@finos/legend-shared';
import { flowResult } from 'mobx';
import { observer } from 'mobx-react-lite';
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState, } from 'react';
import { instanceValue_setValue, instanceValue_setValues, valueSpecification_setGenericType, } from '../../stores/shared/ValueSpecificationModifierHelper.js';
import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../graph/QueryBuilderMetaModelConst.js';
import { isValidInstanceValue, simplifyValueExpression, } from '../../stores/QueryBuilderValueSpecificationHelper.js';
import { evaluate } from 'mathjs';
import { isUsedDateFunctionSupportedInFormMode } from '../../stores/QueryBuilderStateBuilder.js';
import { buildPrimitiveInstanceValue, convertTextToEnum, convertTextToPrimitiveInstanceValue, getValueSpecificationStringValue, } from '../../stores/shared/ValueSpecificationEditorHelper.js';
import { CustomDatePicker } from './CustomDatePicker.js';
import { CustomDateOption, buildPureAdjustDateFunction, CustomFirstDayOfOption, buildPureDateFunctionExpression, CustomPreviousDayOfWeekOption, DatePickerOption, } from './CustomDatePickerHelper.js';
export const VariableInfoTooltip = (props) => {
    const { variable, children, placement } = props;
    const type = variable.genericType?.value.rawType;
    return (_jsx(Tooltip, { arrow: true, ...(placement !== undefined ? { placement } : {}), classes: {
            tooltip: 'value-spec-paramater__tooltip',
            arrow: 'value-spec-paramater__tooltip__arrow',
            tooltipPlacementRight: 'value-spec-paramater__tooltip--right',
        }, slotProps: {
            transition: {
                // disable transition
                // NOTE: somehow, this is the only workaround we have, if for example
                // we set `appear = true`, the tooltip will jump out of position
                timeout: 0,
            },
        }, title: _jsxs("div", { className: "value-spec-paramater__tooltip__content", children: [_jsxs("div", { className: "value-spec-paramater__tooltip__item", children: [_jsx("div", { className: "value-spec-paramater__tooltip__item__label", children: "Type" }), _jsx("div", { className: "value-spec-paramater__tooltip__item__value", children: type?.name ?? '(unknown)' })] }), _jsxs("div", { className: "value-spec-paramater__tooltip__item", children: [_jsx("div", { className: "value-spec-paramater__tooltip__item__label", children: "Var Name" }), _jsx("div", { className: "value-spec-paramater__tooltip__item__value", children: variable.name })] }), _jsxs("div", { className: "value-spec-paramater__tooltip__item", children: [_jsx("div", { className: "value-spec-paramater__tooltip__item__label", children: "Multiplicity" }), _jsx("div", { className: "value-spec-paramater__tooltip__item__value", children: getMultiplicityDescription(variable.multiplicity) })] })] }), children: children }));
};
export const QUERY_BUILDER_VARIABLE_DND_TYPE = 'VARIABLE';
const VariableExpressionParameterEditor = observer((props) => {
    const { valueSpecification, resetValue, isConstant, className } = props;
    const varName = valueSpecification.name;
    return (_jsxs(_Fragment, { children: [_jsx(DragPreviewLayer, { labelGetter: (item) => item.variable.name, types: [QUERY_BUILDER_VARIABLE_DND_TYPE] }), _jsxs("div", { className: clsx('value-spec-editor__variable', className, {
                    'value-spec-editor__variable__constant': isConstant,
                }), children: [_jsx("div", { className: "value-spec-editor__variable__icon", children: isConstant ? _jsx("div", { className: "icon", children: "C" }) : _jsx(DollarIcon, {}) }), _jsxs("div", { className: "value-spec-editor__variable__label", children: [_jsx("div", { className: "value-spec-editor__variable__text", children: varName }), _jsx(VariableInfoTooltip, { variable: valueSpecification, children: _jsx("div", { className: "value-spec-editor__variable__info", children: _jsx(InfoCircleIcon, {}) }) }), _jsx("button", { className: "value-spec-editor__variable__reset-btn", name: "Reset", title: "Reset", onClick: resetValue, children: _jsx(RefreshIcon, {}) })] })] })] }));
});
// eslint-disable-next-line comma-spacing
const StringPrimitiveInstanceValueEditorInner = (props, ref) => {
    const { valueSpecification, valueSelector, updateValueSpecification, errorChecker, resetValue, handleBlur, handleKeyDown, className, selectorSearchConfig, selectorConfig, lightMode, readOnly, } = props;
    const useSelector = Boolean(selectorSearchConfig);
    const applicationStore = useApplicationStore();
    const value = valueSelector(valueSpecification);
    const changeInputValue = (event) => {
        updateValueSpecification(valueSpecification, event.target.value);
    };
    // custom select
    const selectedValue = value ? { value: value, label: value } : null;
    const reloadValuesFunc = selectorSearchConfig?.reloadValues;
    const changeValue = (val) => {
        const newValue = val === null ? '' : val.value.toString();
        updateValueSpecification(valueSpecification, newValue);
    };
    const handleInputChange = (inputValue, actionChange) => {
        if (actionChange.action === 'input-change') {
            updateValueSpecification(valueSpecification, inputValue);
            reloadValuesFunc?.cancel();
            const reloadValuesFuncTransformation = reloadValuesFunc?.(inputValue);
            if (reloadValuesFuncTransformation) {
                flowResult(reloadValuesFuncTransformation).catch(applicationStore.alertUnhandledError);
            }
        }
        if (actionChange.action === 'input-blur') {
            reloadValuesFunc?.cancel();
            selectorSearchConfig?.cleanUpReloadValues?.();
        }
    };
    const isLoading = selectorSearchConfig?.isLoading;
    const queryOptions = selectorSearchConfig?.values?.length
        ? selectorSearchConfig.values.map((e) => ({
            value: e,
            label: e.toString(),
        }))
        : undefined;
    const noOptionsMessage = selectorSearchConfig?.values === undefined ? () => null : undefined;
    const resetButtonName = `reset-${valueSelector(valueSpecification)}`;
    const inputName = `input-${valueSelector(valueSpecification)}`;
    const onBlur = (event) => {
        if (event.relatedTarget?.name !== resetButtonName &&
            event.relatedTarget?.name !== inputName) {
            handleBlur?.();
        }
    };
    return (_jsxs("div", { className: clsx('value-spec-editor', className), onBlur: onBlur, children: [useSelector ? (_jsx(CustomSelectorInput, { className: "value-spec-editor__enum-selector", options: queryOptions, onChange: changeValue, value: selectedValue, inputValue: value ?? '', onInputChange: handleInputChange, darkMode: !lightMode, isLoading: isLoading, allowCreateWhileLoading: true, noOptionsMessage: noOptionsMessage, components: {
                    DropdownIndicator: null,
                }, hasError: errorChecker?.(valueSpecification), placeholder: value === '' ? '(empty)' : undefined, inputRef: ref, onKeyDown: handleKeyDown, inputName: inputName, optionCustomization: selectorConfig?.optionCustomization, disabled: readOnly })) : (_jsx(InputWithInlineValidation, { className: "panel__content__form__section__input value-spec-editor__input", spellCheck: false, value: value ?? '', placeholder: value === '' ? '(empty)' : undefined, onChange: changeInputValue, ref: ref, error: errorChecker?.(valueSpecification)
                    ? 'Invalid String value'
                    : undefined, onKeyDown: handleKeyDown, name: inputName, disabled: readOnly })), _jsx("button", { className: "value-spec-editor__reset-btn", name: resetButtonName, title: "Reset", onClick: resetValue, disabled: readOnly, children: _jsx(RefreshIcon, {}) })] }));
};
export const StringPrimitiveInstanceValueEditor = observer(forwardRef(StringPrimitiveInstanceValueEditorInner));
// eslint-disable-next-line comma-spacing
const BooleanInstanceValueEditorInner = (props) => {
    const { valueSpecification, valueSelector, updateValueSpecification, resetValue, className, readOnly, } = props;
    const value = valueSelector(valueSpecification);
    const toggleValue = () => {
        updateValueSpecification(valueSpecification, !value);
    };
    return (_jsxs("div", { className: clsx('value-spec-editor', className), children: [_jsx("button", { role: "checkbox", className: clsx('value-spec-editor__toggler__btn', {
                    'value-spec-editor__toggler__btn--toggled': value,
                }), onClick: toggleValue, disabled: readOnly, children: value ? _jsx(CheckSquareIcon, {}) : _jsx(SquareIcon, {}) }), _jsx("button", { className: "value-spec-editor__reset-btn", name: "Reset", title: "Reset", onClick: resetValue, disabled: readOnly, children: _jsx(RefreshIcon, {}) })] }));
};
export const BooleanPrimitiveInstanceValueEditor = observer(BooleanInstanceValueEditorInner);
// eslint-disable-next-line comma-spacing
const NumberPrimitiveInstanceValueEditorInner = (props, ref) => {
    const { valueSpecification, valueSelector, updateValueSpecification, errorChecker, resetValue, handleBlur, handleKeyDown, className, isInteger, readOnly, enableExpressionCalculation = true, } = props;
    const [value, setValue] = useState(valueSelector(valueSpecification)?.toString() ?? '');
    const inputRef = useRef(null);
    useImperativeHandle(ref, () => inputRef.current, []);
    const numericValue = value
        ? isInteger
            ? Number.parseInt(Number(value).toString(), 10)
            : Number(value)
        : null;
    const updateValueSpecIfValid = (val) => {
        if (val) {
            const parsedValue = isInteger
                ? Number.parseInt(Number(val).toString(), 10)
                : Number(val);
            if (!isNaN(parsedValue) &&
                parsedValue !== valueSelector(valueSpecification)) {
                updateValueSpecification(valueSpecification, parsedValue);
            }
        }
        else {
            resetValue();
        }
    };
    const handleInputChange = (event) => {
        setValue(event.target.value);
        updateValueSpecIfValid(event.target.value);
    };
    // Support expression evaluation
    const calculateExpression = () => {
        if (numericValue !== null && isNaN(numericValue)) {
            // If the value is not a number, try to evaluate it as an expression
            try {
                const calculatedValue = guaranteeIsNumber(evaluate(value));
                updateValueSpecIfValid(calculatedValue.toString());
                setValue(calculatedValue.toString());
            }
            catch {
                // If we fail to evaluate the expression, we just keep the previous value
                const prevValue = valueSelector(valueSpecification)?.toString() ?? '';
                updateValueSpecIfValid(prevValue);
                setValue(prevValue);
            }
        }
        else if (numericValue !== null) {
            // If numericValue is a number, update the value spec
            updateValueSpecIfValid(numericValue.toString());
            setValue(numericValue.toString());
        }
        else {
            // If numericValue is null, reset the value spec
            resetValue();
        }
    };
    const onKeyDown = (event) => {
        if (event.code === 'Enter') {
            calculateExpression();
            inputRef.current?.focus();
        }
        else if (event.code === 'Escape') {
            inputRef.current?.select();
        }
    };
    useEffect(() => {
        if (numericValue !== null &&
            !isNaN(numericValue) &&
            numericValue !== valueSelector(valueSpecification)) {
            const valueFromValueSpec = valueSelector(valueSpecification) !== null
                ? valueSelector(valueSpecification).toString()
                : '';
            setValue(valueFromValueSpec);
        }
    }, [numericValue, valueSpecification, valueSelector]);
    const resetButtonName = `reset-${valueSelector(valueSpecification)}`;
    const inputName = `input-${valueSelector(valueSpecification)}`;
    const calculateButtonName = `calculate-${valueSelector(valueSpecification)}`;
    const onBlur = (event) => {
        if (event.relatedTarget?.name !== resetButtonName &&
            event.relatedTarget?.name !== inputName &&
            event.relatedTarget?.name !== calculateButtonName) {
            handleBlur?.();
        }
    };
    return (_jsxs("div", { className: clsx('value-spec-editor', className), onBlur: onBlur, children: [_jsxs("div", { className: "value-spec-editor__number__input-container", children: [_jsx("input", { ref: inputRef, className: clsx('panel__content__form__section__input', 'value-spec-editor__input', 'value-spec-editor__number__input', {
                            'value-spec-editor__number__input--error': errorChecker?.(valueSpecification),
                        }), spellCheck: false, type: "text" // NOTE: we leave this as text so that we can support expression evaluation
                        , inputMode: "numeric", value: value, onChange: handleInputChange, onBlur: calculateExpression, onKeyDown: (event) => {
                            onKeyDown(event);
                            handleKeyDown?.(event);
                        }, name: inputName, disabled: readOnly }), enableExpressionCalculation && (_jsx("div", { className: "value-spec-editor__number__actions", children: _jsx("button", { className: "value-spec-editor__number__action", title: "Evaluate Expression (Enter)", name: calculateButtonName, onClick: calculateExpression, disabled: readOnly, children: _jsx(CalculateIcon, {}) }) }))] }), _jsx("button", { className: "value-spec-editor__reset-btn", name: resetButtonName, title: "Reset", onClick: resetValue, disabled: readOnly, children: _jsx(RefreshIcon, {}) })] }));
};
export const NumberPrimitiveInstanceValueEditor = observer(forwardRef(NumberPrimitiveInstanceValueEditorInner));
// eslint-disable-next-line comma-spacing
const EnumInstanceValueEditorInner = (props) => {
    const { valueSpecification, valueSelector, updateValueSpecification, errorChecker, resetValue, handleBlur, options, className, selectorConfig, lightMode, readOnly, } = props;
    const enumValue = valueSelector(valueSpecification);
    const resetButtonName = `reset-${valueSelector(valueSpecification)}`;
    const inputName = `input-${valueSelector(valueSpecification)}`;
    const changeValue = (val) => {
        updateValueSpecification(valueSpecification, val.value);
        handleBlur?.();
    };
    const onBlur = (event) => {
        if (event.relatedTarget?.name !== resetButtonName &&
            event.relatedTarget?.name !== inputName) {
            handleBlur?.();
        }
    };
    return (_jsxs("div", { className: clsx('value-spec-editor', className), onBlur: onBlur, children: [_jsx(CustomSelectorInput, { className: "value-spec-editor__enum-selector", options: options, onChange: changeValue, value: enumValue ? { value: enumValue, label: enumValue } : null, darkMode: !lightMode, hasError: errorChecker?.(valueSpecification), placeholder: "Select value", autoFocus: true, inputName: inputName, optionCustomization: selectorConfig?.optionCustomization, disabled: readOnly }), _jsx("button", { className: "value-spec-editor__reset-btn", name: resetButtonName, title: "Reset", onClick: resetValue, disabled: readOnly, children: _jsx(RefreshIcon, {}) })] }));
};
export const EnumInstanceValueEditor = observer(EnumInstanceValueEditorInner);
const stringifyValue = (values) => {
    if (values.length === 0) {
        return '';
    }
    return csvStringify([
        values
            .map((val) => {
            if (val instanceof PrimitiveInstanceValue) {
                return val.values[0];
            }
            else if (val instanceof EnumValueInstanceValue) {
                return guaranteeNonNullable(val.values[0]).value.name;
            }
            return undefined;
        })
            .filter(isNonNullable),
    ]).trim();
};
const getPlaceHolder = (expectedType) => {
    if (expectedType instanceof PrimitiveType) {
        switch (expectedType.path) {
            case PRIMITIVE_TYPE.DATE:
            case PRIMITIVE_TYPE.STRICTDATE:
                return 'yyyy-mm-dd';
            case PRIMITIVE_TYPE.DATETIME:
                return 'yyyy-mm-ddThh:mm:ss';
            default:
                return 'Add';
        }
    }
    else if (expectedType instanceof PrecisePrimitiveType) {
        // Precise primitive types (e.g. Varchar, BigInt, Timestamp) flow in from
        // accessor relation columns. Map them to their standard primitive
        // equivalent so we can pick the right placeholder.
        switch (getCorrespondingStandardPrimitiveType(expectedType.path)) {
            case PRIMITIVE_TYPE.DATE:
            case PRIMITIVE_TYPE.STRICTDATE:
                return 'yyyy-mm-dd';
            case PRIMITIVE_TYPE.DATETIME:
            case PRIMITIVE_TYPE.STRICTTIME:
                return 'yyyy-mm-ddThh:mm:ss';
            default:
                return 'Add';
        }
    }
    else if (expectedType instanceof V1_PackageableType) {
        switch (expectedType.fullPath) {
            case PRIMITIVE_TYPE.DATE:
            case PRIMITIVE_TYPE.STRICTDATE:
                return 'yyyy-mm-dd';
            case PRIMITIVE_TYPE.DATETIME:
            case PRIMITIVE_TYPE.STRICTTIME:
                return 'yyyy-mm-ddThh:mm:ss';
            default:
                return 'Add';
        }
    }
    else {
        throw new Error(`Cannot get placeholder for type ${expectedType}`);
    }
};
const PrimitiveCollectionInstanceValueEditorInner = (props) => {
    const { valueSpecification, convertTextToValueSpecification, convertValueSpecificationToText, updateValueSpecification, saveEdit, selectorSearchConfig, selectorConfig, expectedType, lightMode, readOnly, } = props;
    // local state and variables
    const applicationStore = useApplicationStore();
    const inputRef = useRef(null);
    const [inputValue, setInputValue] = useState('');
    const [inputValueIsError, setInputValueIsError] = useState(false);
    const [selectedOptions, setSelectedOptions] = useState(valueSpecification.values
        .filter((value) => guaranteeNonNullable(value))
        .map(convertValueSpecificationToText)
        .filter(isNonEmptyString)
        .map((value) => ({
        label: value,
        value,
    })));
    // typehead search setup
    const isTypeaheadSearchEnabled = expectedType === PrimitiveType.STRING && Boolean(selectorSearchConfig);
    const reloadValuesFunc = isTypeaheadSearchEnabled
        ? selectorSearchConfig?.reloadValues
        : undefined;
    const cleanUpReloadValuesFunc = isTypeaheadSearchEnabled
        ? selectorSearchConfig?.cleanUpReloadValues
        : undefined;
    const isLoading = isTypeaheadSearchEnabled
        ? selectorSearchConfig?.isLoading
        : undefined;
    const queryOptions = isTypeaheadSearchEnabled && selectorSearchConfig?.values?.length
        ? selectorSearchConfig.values.map((e) => ({
            value: e,
            label: e.toString(),
        }))
        : undefined;
    const noMatchMessage = isTypeaheadSearchEnabled && isLoading ? 'Loading...' : undefined;
    const copyButtonName = `copy-${valueSpecification.values[0] ? convertValueSpecificationToText(valueSpecification.values[0]) : ''}`;
    const inputName = `input-${valueSpecification.values[0] ? convertValueSpecificationToText(valueSpecification.values[0]) : ''}`;
    // helper functions
    const buildOptionForValueSpec = (value) => {
        const stringValue = guaranteeNonNullable(convertValueSpecificationToText(value));
        return {
            label: stringValue,
            value: stringValue,
        };
    };
    const isValueAlreadySelected = (value) => selectedOptions.map((option) => option.value).includes(value);
    /**
     * NOTE: We attempt to be less disruptive here by not throwing errors left and right, instead
     * we simply return null for values which are not valid or parsable. But perhaps, we can consider
     * passing in logger or notifier to give the users some idea of what went wrong instead of ignoring
     * their input.
     */
    const convertInputValueToValueSpec = () => {
        const trimmedInputValue = inputValue.trim();
        if (trimmedInputValue.length) {
            const newValueSpec = convertTextToValueSpecification(expectedType, trimmedInputValue);
            if (newValueSpec === null ||
                convertValueSpecificationToText(newValueSpec) === undefined ||
                isValueAlreadySelected(guaranteeNonNullable(convertValueSpecificationToText(newValueSpec)))) {
                return null;
            }
            return newValueSpec;
        }
        return null;
    };
    const addInputValueToSelectedOptions = () => {
        const newValueSpec = convertInputValueToValueSpec();
        if (newValueSpec !== null) {
            setSelectedOptions([
                ...selectedOptions,
                buildOptionForValueSpec(newValueSpec),
            ]);
            setInputValue('');
            reloadValuesFunc?.cancel();
        }
        else if (inputValue.trim().length) {
            setInputValueIsError(true);
        }
    };
    // event handlers
    const changeValue = (newSelectedOptions, actionChange) => {
        setSelectedOptions(newSelectedOptions);
        if (actionChange.action === 'select-option') {
            setInputValue('');
        }
        else if (actionChange.action === 'remove-value' &&
            actionChange.removedValue.value === inputValue) {
            setInputValueIsError(false);
        }
    };
    const handleInputChange = (newInputValue, actionChange) => {
        if (actionChange.action === 'input-change') {
            setInputValue(newInputValue);
            setInputValueIsError(false);
            reloadValuesFunc?.cancel();
            const reloadValuesFuncTransformation = reloadValuesFunc?.(newInputValue);
            if (reloadValuesFuncTransformation) {
                flowResult(reloadValuesFuncTransformation).catch(applicationStore.alertUnhandledError);
            }
        }
        if (actionChange.action === 'input-blur') {
            reloadValuesFunc?.cancel();
            cleanUpReloadValuesFunc?.();
        }
    };
    const copyValueToClipboard = async () => navigator.clipboard.writeText(selectedOptions.map((option) => option.value).join(','));
    const updateValueSpecAndSaveEdit = () => {
        const newValueSpec = convertInputValueToValueSpec();
        const finalSelectedOptions = newValueSpec !== null
            ? [...selectedOptions, buildOptionForValueSpec(newValueSpec)]
            : selectedOptions;
        const finalFormattedSelectedOptions = finalSelectedOptions
            .map((option) => option.value)
            .map((value) => convertTextToValueSpecification(expectedType, value))
            .filter(isNonNullable);
        updateValueSpecification(valueSpecification, finalFormattedSelectedOptions);
        saveEdit();
    };
    const handleKeyDown = (event) => {
        if ((event.key === 'Enter' || event.key === ',') && !event.shiftKey) {
            addInputValueToSelectedOptions();
            event.preventDefault();
        }
    };
    const handlePaste = (event) => {
        const pastedText = event.clipboardData.getData('text');
        const parsedData = parseCSVString(pastedText);
        if (!parsedData) {
            return;
        }
        const newValues = uniq(uniq(parsedData)
            .map((value) => {
            const newValueSpec = convertTextToValueSpecification(expectedType, value);
            return newValueSpec
                ? convertValueSpecificationToText(newValueSpec)
                : null;
        })
            .filter(isNonNullable)).filter((value) => !isValueAlreadySelected(value));
        setSelectedOptions([
            ...selectedOptions,
            ...newValues.map((value) => ({ label: value, value })),
        ]);
        event.preventDefault();
    };
    const onBlur = (event) => {
        if (event.relatedTarget?.name !== copyButtonName &&
            event.relatedTarget?.name !== inputName) {
            updateValueSpecAndSaveEdit();
        }
    };
    return (_jsxs("div", { className: "value-spec-editor", onBlur: onBlur, children: [_jsx(CustomSelectorInput, { className: clsx('value-spec-editor__primitive-collection-selector', {
                    'value-spec-editor__primitive-collection-selector--error': inputValueIsError,
                }), options: queryOptions, inputValue: inputValue, isMulti: true, menuIsOpen: isTypeaheadSearchEnabled &&
                    inputValue.length >= DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH, autoFocus: true, inputRef: inputRef, onChange: changeValue, onInputChange: handleInputChange, onKeyDown: handleKeyDown, onPaste: handlePaste, value: selectedOptions, darkMode: !lightMode, isLoading: isLoading, noMatchMessage: noMatchMessage, placeholder: getPlaceHolder(expectedType), components: {
                    DropdownIndicator: null,
                }, inputName: inputName, optionCustomization: selectorConfig?.optionCustomization, disabled: readOnly }), _jsx("button", { className: "value-spec-editor__list-editor__copy-button", 
                // eslint-disable-next-line no-void
                onClick: () => void copyValueToClipboard(), name: copyButtonName, title: "Copy values to clipboard", children: _jsx(CopyIcon, {}) }), _jsx("button", { className: "value-spec-editor__list-editor__save-button btn--dark", name: "Save", title: "Save", onClick: updateValueSpecAndSaveEdit, disabled: readOnly, children: _jsx(SaveIcon, {}) })] }));
};
export const PrimitiveCollectionInstanceValueEditor = observer(PrimitiveCollectionInstanceValueEditorInner);
const EnumCollectionInstanceValueEditorInner = (props) => {
    const { valueSpecification, convertTextToValueSpecification, convertValueSpecificationToText, updateValueSpecification, saveEdit, expectedType, enumOptions, selectorConfig, lightMode, readOnly, } = props;
    guaranteeNonNullable(enumOptions, 'Must pass enum options to EnumCollectionInstanceValueEditor');
    // local state and variables
    const [inputValue, setInputValue] = useState('');
    const [inputValueIsError, setInputValueIsError] = useState(false);
    const [selectedOptions, setSelectedOptions] = useState(valueSpecification.values
        .filter((value) => guaranteeNonNullable(value))
        .map(convertValueSpecificationToText)
        .filter(isNonEmptyString)
        .map((value) => ({
        label: value,
        value,
    })));
    const availableOptions = enumOptions?.filter((value) => !selectedOptions.some((selectedValue) => selectedValue.value === value.value));
    const copyButtonName = `copy-${valueSpecification.values[0] ? convertValueSpecificationToText(valueSpecification.values[0]) : ''}`;
    const inputName = `input-${valueSpecification.values[0] ? convertValueSpecificationToText(valueSpecification.values[0]) : ''}`;
    // helper functions
    const isValueAlreadySelected = (value) => selectedOptions.map((option) => option.value).includes(value);
    /**
     * NOTE: We attempt to be less disruptive here by not throwing errors left and right, instead
     * we simply return null for values which are not valid or parsable. But perhaps, we can consider
     * passing in logger or notifier to give the users some idea of what went wrong instead of ignoring
     * their input.
     */
    const convertInputValueToEnum = () => {
        const trimmedInputValue = inputValue.trim();
        if (!trimmedInputValue.length ||
            isValueAlreadySelected(trimmedInputValue) ||
            !enumOptions?.some((option) => option.value === trimmedInputValue)) {
            return null;
        }
        return trimmedInputValue;
    };
    const addInputValueToSelectedOptions = () => {
        const newEnum = convertInputValueToEnum();
        if (newEnum !== null) {
            setSelectedOptions([
                ...selectedOptions,
                {
                    label: newEnum,
                    value: newEnum,
                },
            ]);
            setInputValue('');
        }
        else if (inputValue.trim().length) {
            setInputValueIsError(true);
        }
    };
    // event handlers
    const changeValue = (newSelectedOptions, actionChange) => {
        setSelectedOptions(newSelectedOptions);
        if (actionChange.action === 'select-option') {
            setInputValue('');
        }
        else if (actionChange.action === 'remove-value' &&
            actionChange.removedValue.value === inputValue) {
            setInputValueIsError(false);
        }
    };
    const handleInputChange = (newInputValue, actionChange) => {
        if (actionChange.action === 'input-change') {
            setInputValue(newInputValue);
            setInputValueIsError(false);
        }
    };
    const handleKeyDown = (event) => {
        if ((event.key === 'Enter' || event.key === ',') && !event.shiftKey) {
            addInputValueToSelectedOptions();
            event.preventDefault();
        }
    };
    const handlePaste = (event) => {
        const pastedText = event.clipboardData.getData('text');
        const parsedData = parseCSVString(pastedText);
        if (!parsedData) {
            return;
        }
        const newValues = uniq(uniq(parsedData).filter((value) => enumOptions?.some((option) => option.value === value))).filter((value) => !isValueAlreadySelected(value));
        setSelectedOptions([
            ...selectedOptions,
            ...newValues.map((value) => ({ label: value, value })),
        ]);
        event.preventDefault();
    };
    const copyValueToClipboard = async () => navigator.clipboard.writeText(selectedOptions.map((option) => option.value).join(','));
    const updateValueSpecAndSaveEdit = () => {
        const result = selectedOptions
            .map((option) => option.value)
            .map((value) => convertTextToValueSpecification(expectedType, value))
            .filter(isNonNullable);
        updateValueSpecification(valueSpecification, result);
        saveEdit();
    };
    const onBlur = (event) => {
        if (event.relatedTarget?.name !== copyButtonName &&
            event.relatedTarget?.name !== inputName) {
            updateValueSpecAndSaveEdit();
        }
    };
    return (_jsxs("div", { className: "value-spec-editor", onBlur: onBlur, children: [_jsx(CustomSelectorInput, { className: clsx('value-spec-editor__enum-collection-selector', {
                    'value-spec-editor__enum-collection-selector--error': inputValueIsError,
                }), options: availableOptions, inputValue: inputValue, isMulti: true, autoFocus: true, onChange: changeValue, onInputChange: handleInputChange, onKeyDown: handleKeyDown, onPaste: handlePaste, value: selectedOptions, darkMode: !lightMode, placeholder: "Add", menuIsOpen: true, inputName: inputName, optionCustomization: selectorConfig?.optionCustomization, disabled: readOnly }), _jsx("button", { className: "value-spec-editor__list-editor__copy-button", 
                // eslint-disable-next-line no-void
                onClick: () => void copyValueToClipboard(), name: copyButtonName, title: "Copy values to clipboard", children: _jsx(CopyIcon, {}) }), _jsx("button", { className: "value-spec-editor__list-editor__save-button btn--dark", name: "Save", title: "Save", onClick: updateValueSpecAndSaveEdit, disabled: readOnly, children: _jsx(SaveIcon, {}) })] }));
};
export const EnumCollectionInstanceValueEditor = observer(EnumCollectionInstanceValueEditorInner);
const COLLECTION_PREVIEW_CHAR_LIMIT = 50;
const CollectionValueInstanceValueEditorInner = (props) => {
    const { valueSpecification, convertTextToValueSpecification, convertValueSpecificationToText, updateValueSpecification, stringifyCollectionValueSpecification, errorChecker, className, selectorSearchConfig, selectorConfig, expectedType, enumOptions, lightMode, readOnly, } = props;
    const [editable, setEditable] = useState(false);
    const valueText = stringifyCollectionValueSpecification(valueSpecification);
    const previewText = `List(${valueSpecification.values.length === 0
        ? 'empty'
        : valueSpecification.values.length})${valueSpecification.values.length === 0
        ? ''
        : `: ${valueText.length > COLLECTION_PREVIEW_CHAR_LIMIT
            ? `${valueText.substring(0, COLLECTION_PREVIEW_CHAR_LIMIT)}...`
            : valueText}`}`;
    const enableEdit = () => setEditable(true);
    const saveEdit = () => {
        if (editable) {
            setEditable(false);
        }
    };
    if (editable) {
        return (_jsx(_Fragment, { children: _jsx("div", { className: clsx('value-spec-editor', className), children: enumOptions !== undefined ? (_jsx(EnumCollectionInstanceValueEditor, { valueSpecification: valueSpecification, updateValueSpecification: updateValueSpecification, convertTextToValueSpecification: convertTextToValueSpecification, convertValueSpecificationToText: convertValueSpecificationToText, expectedType: expectedType, saveEdit: saveEdit, enumOptions: enumOptions, selectorConfig: selectorConfig, lightMode: lightMode, readOnly: readOnly })) : (_jsx(PrimitiveCollectionInstanceValueEditor, { valueSpecification: valueSpecification, updateValueSpecification: updateValueSpecification, convertTextToValueSpecification: convertTextToValueSpecification, convertValueSpecificationToText: convertValueSpecificationToText, expectedType: expectedType, saveEdit: saveEdit, selectorSearchConfig: selectorSearchConfig, selectorConfig: selectorConfig, lightMode: lightMode, readOnly: readOnly })) }) }));
    }
    return (_jsxs("div", { className: clsx('value-spec-editor', className), onClick: readOnly ? () => { } : enableEdit, title: readOnly ? '' : 'Click to edit', style: { cursor: readOnly ? 'not-allowed' : '' }, children: [_jsx("div", { className: clsx('value-spec-editor__list-editor__preview', {
                    'value-spec-editor__list-editor__preview--error': errorChecker?.(valueSpecification),
                }), children: previewText }), _jsx("button", { className: "value-spec-editor__list-editor__edit-icon", children: _jsx(PencilIcon, {}) })] }));
};
export const CollectionValueInstanceValueEditor = observer(CollectionValueInstanceValueEditorInner);
const UnsupportedValueSpecificationEditor = () => (_jsx("div", { className: "value-spec-editor--unsupported", children: "unsupported" }));
const DateInstanceValueEditorInner = (props) => {
    const { valueSpecification, valueSelector, updateValueSpecification, resetValue, handleBlur, typeCheckOption, displayAsEditableValue, className, readOnly, } = props;
    return (_jsxs("div", { className: clsx('value-spec-editor', className), children: [_jsx(CustomDatePicker, { valueSpecification: valueSpecification, valueSelector: valueSelector, typeCheckOption: typeCheckOption, updateValueSpecification: updateValueSpecification, hasError: valueSpecification instanceof PrimitiveInstanceValue &&
                    !isValidInstanceValue(valueSpecification), handleBlur: handleBlur, displayAsEditableValue: displayAsEditableValue, readOnly: readOnly }), !displayAsEditableValue && (_jsx("button", { className: "value-spec-editor__reset-btn", name: "Reset", title: "Reset", onClick: resetValue, disabled: readOnly, children: _jsx(RefreshIcon, {}) }))] }));
};
export const DateInstanceValueEditor = observer(DateInstanceValueEditorInner);
/**
 * TODO we should pass in the props `resetValueSpecification`. Reset
 * should be part of this editor. Also through here we can call `observe_` accordingly.
 *
 * See https://github.com/finos/legend-studio/pull/1021
 */
export const BasicValueSpecificationEditor = forwardRef(function BasicValueSpecificationEditorInner(props, ref) {
    const { className, valueSpecification, graph, observerContext, typeCheckOption, setValueSpecification, resetValue, selectorSearchConfig, selectorConfig, isConstant, handleBlur, handleKeyDown, displayDateEditorAsEditableValue, readOnly, enableExpressionCalculation, } = props;
    const applicationStore = useApplicationStore();
    const errorChecker = (_valueSpecification) => !isValidInstanceValue(_valueSpecification);
    const dateValueSelector = (_valueSpecification) => {
        return _valueSpecification instanceof SimpleFunctionExpression
            ? ''
            : _valueSpecification.values[0];
    };
    const dateUpdateValueSpecification = (_valueSpecification, value, options) => {
        if (value instanceof CustomDateOption) {
            setValueSpecification(buildPureAdjustDateFunction(value, graph, observerContext));
        }
        else if (value instanceof CustomFirstDayOfOption) {
            setValueSpecification(buildPureDateFunctionExpression(value, graph, observerContext));
        }
        else if (value instanceof CustomPreviousDayOfWeekOption) {
            setValueSpecification(buildPureDateFunctionExpression(value, graph, observerContext));
        }
        else if (value instanceof DatePickerOption) {
            setValueSpecification(buildPureDateFunctionExpression(value, graph, observerContext));
        }
        else {
            if (_valueSpecification instanceof SimpleFunctionExpression) {
                setValueSpecification(buildPrimitiveInstanceValue(graph, guaranteeNonNullable(options?.primitiveTypeEnum), value, observerContext));
            }
            else if (_valueSpecification instanceof InstanceValue) {
                instanceValue_setValue(_valueSpecification, value, 0, observerContext);
                if (_valueSpecification.genericType.value.rawType.path !==
                    guaranteeNonNullable(options?.primitiveTypeEnum)) {
                    valueSpecification_setGenericType(_valueSpecification, GenericTypeExplicitReference.create(new GenericType(getPrimitiveTypeInstanceFromEnum(guaranteeNonNullable(options?.primitiveTypeEnum)))));
                }
                setValueSpecification(_valueSpecification);
            }
            else if (options?.primitiveTypeEnum === PRIMITIVE_TYPE.LATESTDATE) {
                setValueSpecification(buildPrimitiveInstanceValue(graph, PRIMITIVE_TYPE.LATESTDATE, value, observerContext));
            }
        }
    };
    if (valueSpecification instanceof PrimitiveInstanceValue) {
        const _type = valueSpecification.genericType.value.rawType;
        // eslint-disable-next-line comma-spacing
        const valueSelector = (val) => val.values[0];
        // eslint-disable-next-line comma-spacing
        const updateValueSpecification = (_valueSpecification, value) => {
            instanceValue_setValue(_valueSpecification, value, 0, observerContext);
            setValueSpecification(_valueSpecification);
        };
        switch (_type.path) {
            case PRIMITIVE_TYPE.STRING:
                return (_jsx(StringPrimitiveInstanceValueEditor, { valueSpecification: valueSpecification, valueSelector: valueSelector, updateValueSpecification: updateValueSpecification, errorChecker: errorChecker, className: className, resetValue: resetValue, selectorSearchConfig: selectorSearchConfig, selectorConfig: selectorConfig, ref: ref, handleBlur: handleBlur, handleKeyDown: handleKeyDown, lightMode: applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, readOnly: readOnly }));
            case PRIMITIVE_TYPE.BOOLEAN:
                return (_jsx(BooleanPrimitiveInstanceValueEditor, { valueSpecification: valueSpecification, valueSelector: valueSelector, updateValueSpecification: updateValueSpecification, className: className, resetValue: resetValue, readOnly: readOnly }));
            case PRIMITIVE_TYPE.NUMBER:
            case PRIMITIVE_TYPE.FLOAT:
            case PRIMITIVE_TYPE.DECIMAL:
            case PRIMITIVE_TYPE.BINARY:
            case PRIMITIVE_TYPE.BYTE:
            case PRIMITIVE_TYPE.INTEGER:
                return (_jsx(NumberPrimitiveInstanceValueEditor, { valueSpecification: valueSpecification, valueSelector: valueSelector, isInteger: _type.path === PRIMITIVE_TYPE.INTEGER, updateValueSpecification: updateValueSpecification, errorChecker: errorChecker, className: className, resetValue: resetValue, ref: ref, handleBlur: handleBlur, handleKeyDown: handleKeyDown, readOnly: readOnly, enableExpressionCalculation: enableExpressionCalculation }));
            case PRIMITIVE_TYPE.DATE:
            case PRIMITIVE_TYPE.STRICTDATE:
            case PRIMITIVE_TYPE.DATETIME:
            case PRIMITIVE_TYPE.LATESTDATE:
                return (_jsx(DateInstanceValueEditor, { valueSpecification: valueSpecification, valueSelector: dateValueSelector, typeCheckOption: typeCheckOption, className: className, updateValueSpecification: dateUpdateValueSpecification, resetValue: resetValue, handleBlur: handleBlur, displayAsEditableValue: displayDateEditorAsEditableValue, errorChecker: (_valueSpecification) => _valueSpecification instanceof PrimitiveInstanceValue &&
                        errorChecker(_valueSpecification), readOnly: readOnly }));
            default:
                return _jsx(UnsupportedValueSpecificationEditor, {});
        }
    }
    else if (valueSpecification instanceof EnumValueInstanceValue) {
        const enumType = guaranteeType(valueSpecification.genericType?.value.rawType, Enumeration);
        const options = enumType.values.map((value) => ({
            label: value.name,
            value: value.name,
        }));
        return (_jsx(EnumInstanceValueEditor, { valueSpecification: valueSpecification, valueSelector: (val) => val.values[0] === undefined ? null : val.values[0].value.name, options: options, className: className, resetValue: resetValue, updateValueSpecification: (_valueSpecification, value) => {
                const enumValue = guaranteeNonNullable(enumType.values.find((val) => val.name === value), `Unable to find enum value ${value} in enumeration ${enumType.name}`);
                instanceValue_setValue(_valueSpecification, EnumValueExplicitReference.create(enumValue), 0, observerContext);
                setValueSpecification(_valueSpecification);
            }, errorChecker: (_valueSpecification) => !isValidInstanceValue(_valueSpecification), handleBlur: handleBlur, selectorConfig: selectorConfig, lightMode: applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, readOnly: readOnly }));
    }
    else if (valueSpecification instanceof CollectionInstanceValue &&
        valueSpecification.genericType) {
        const updateValueSpecification = (collectionValueSpecification, valueSpecifications) => {
            instanceValue_setValues(collectionValueSpecification, valueSpecifications, observerContext);
            setValueSpecification(collectionValueSpecification);
        };
        const convertTextToValueSpecification = (type, text) => {
            if (type instanceof Enumeration) {
                const enumValue = convertTextToEnum(text, type);
                if (enumValue) {
                    const enumValueInstanceValue = new EnumValueInstanceValue(GenericTypeExplicitReference.create(new GenericType(type)));
                    instanceValue_setValues(enumValueInstanceValue, [EnumValueExplicitReference.create(enumValue)], observerContext);
                    return observe_ValueSpecification(enumValueInstanceValue, observerContext);
                }
            }
            else {
                const primitiveVal = convertTextToPrimitiveInstanceValue(guaranteeType(type, Type), text, observerContext);
                if (primitiveVal) {
                    return observe_ValueSpecification(primitiveVal, observerContext);
                }
            }
            return null;
        };
        const enumOptions = typeCheckOption.expectedType instanceof Enumeration
            ? typeCheckOption.expectedType.values.map((enumValue) => ({
                label: enumValue.name,
                value: enumValue.name,
            }))
            : undefined;
        // NOTE: since when we fill in the arguments, `[]` (or `nullish` value in Pure)
        // is used for parameters we don't handle, we should not attempt to support empty collection
        // without generic type here as that  is equivalent to `[]`
        return (_jsx(CollectionValueInstanceValueEditor, { valueSpecification: valueSpecification, updateValueSpecification: updateValueSpecification, expectedType: typeCheckOption.expectedType, className: className, selectorSearchConfig: selectorSearchConfig, selectorConfig: selectorConfig, stringifyCollectionValueSpecification: (collectionValueSpecification) => stringifyValue(collectionValueSpecification.values), errorChecker: errorChecker, convertValueSpecificationToText: (_valueSpecification) => getValueSpecificationStringValue(_valueSpecification, applicationStore, { omitEnumOwnerName: true }), convertTextToValueSpecification: convertTextToValueSpecification, enumOptions: enumOptions, lightMode: applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, readOnly: readOnly }));
    }
    // property expression
    else if (valueSpecification instanceof VariableExpression) {
        return (_jsx(VariableExpressionParameterEditor, { valueSpecification: valueSpecification, className: className, resetValue: resetValue, isConstant: Boolean(isConstant) }));
    }
    else if (valueSpecification instanceof INTERNAL__PropagatedValue) {
        return (_jsx(BasicValueSpecificationEditor, { valueSpecification: valueSpecification.getValue(), graph: graph, observerContext: observerContext, typeCheckOption: typeCheckOption, setValueSpecification: setValueSpecification, resetValue: resetValue, handleBlur: handleBlur, handleKeyDown: handleKeyDown, displayDateEditorAsEditableValue: displayDateEditorAsEditableValue, selectorSearchConfig: selectorSearchConfig, selectorConfig: selectorConfig, readOnly: readOnly }));
    }
    else if (valueSpecification instanceof SimpleFunctionExpression) {
        if (isSubType(typeCheckOption.expectedType, PrimitiveType.DATE)) {
            if (isUsedDateFunctionSupportedInFormMode(valueSpecification)) {
                return (_jsx(DateInstanceValueEditor, { valueSpecification: valueSpecification, valueSelector: dateValueSelector, typeCheckOption: typeCheckOption, className: className, updateValueSpecification: dateUpdateValueSpecification, resetValue: resetValue, handleBlur: handleBlur, displayAsEditableValue: displayDateEditorAsEditableValue, readOnly: readOnly }));
            }
            else {
                return _jsx(UnsupportedValueSpecificationEditor, {});
            }
        }
        else if (
        // TODO: think of other ways we could make use of this code path where we can simplify
        // an expression value to simple value, not just handling minus() function only
        isSubType(typeCheckOption.expectedType, PrimitiveType.NUMBER) &&
            matchFunctionName(valueSpecification.functionName, QUERY_BUILDER_SUPPORTED_FUNCTIONS.MINUS)) {
            const simplifiedValue = simplifyValueExpression(valueSpecification, observerContext);
            if (simplifiedValue instanceof PrimitiveInstanceValue &&
                isSubType(simplifiedValue.genericType.value.rawType, PrimitiveType.NUMBER)) {
                return (_jsx(NumberPrimitiveInstanceValueEditor, { valueSpecification: simplifiedValue, valueSelector: (val) => val.values[0], isInteger: simplifiedValue.genericType.value.rawType ===
                        PrimitiveType.INTEGER, updateValueSpecification: (_valueSpecification, value) => {
                        instanceValue_setValue(_valueSpecification, value, 0, observerContext);
                        setValueSpecification(_valueSpecification);
                    }, className: className, resetValue: resetValue, ref: ref, handleBlur: handleBlur, handleKeyDown: handleKeyDown, readOnly: readOnly }));
            }
        }
    }
    return _jsx(UnsupportedValueSpecificationEditor, {});
});
export const EditableBasicValueSpecificationEditor = observer((props) => {
    const { valueSpecification, setValueSpecification, graph, observerContext, typeCheckOption, resetValue, selectorSearchConfig, selectorConfig, isConstant, initializeAsEditable, readOnly, enableExpressionCalculation = true, displayAsString = true, } = props;
    const applicationStore = useApplicationStore();
    const [isEditingValue, setIsEditingValue] = useState(initializeAsEditable ?? false);
    const inputRef = useRef(null);
    useEffect(() => {
        if (isEditingValue) {
            inputRef.current?.focus();
        }
    }, [isEditingValue, inputRef]);
    const editableDisplayValueSupported = (valueSpecification instanceof PrimitiveInstanceValue &&
        !isSubType(valueSpecification.genericType.value.rawType, PrimitiveType.DATE) &&
        valueSpecification.genericType.value.rawType !==
            PrimitiveType.BOOLEAN) ||
        valueSpecification instanceof EnumValueInstanceValue;
    const shouldRenderEditor = isEditingValue || !editableDisplayValueSupported;
    const valueSpecStringValue = getValueSpecificationStringValue(valueSpecification, applicationStore, {
        omitEnumOwnerName: true,
    });
    return shouldRenderEditor ? (_jsx(BasicValueSpecificationEditor, { valueSpecification: valueSpecification, setValueSpecification: setValueSpecification, graph: graph, observerContext: observerContext, typeCheckOption: typeCheckOption, resetValue: resetValue, selectorSearchConfig: selectorSearchConfig, selectorConfig: selectorConfig, isConstant: isConstant, ref: inputRef, handleBlur: () => setIsEditingValue(false), handleKeyDown: (event) => {
            if (event.key === 'Enter') {
                setIsEditingValue(false);
            }
        }, displayDateEditorAsEditableValue: true, readOnly: readOnly, enableExpressionCalculation: enableExpressionCalculation })) : (_jsx("div", { className: "value-spec-editor__editable__display", children: _jsx("span", { className: clsx('value-spec-editor__editable__display--content editable-value', {
                'value-spec-editor__editable__display--content--error': valueSpecification instanceof InstanceValue &&
                    !isValidInstanceValue(valueSpecification),
            }), onClick: readOnly
                ? () => { }
                : () => {
                    setIsEditingValue(true);
                }, style: { cursor: readOnly ? 'not-allowed' : '' }, children: displayAsString
                ? `"${valueSpecStringValue !== undefined ? valueSpecStringValue : ''}"`
                : valueSpecStringValue }) }));
});
//# sourceMappingURL=BasicValueSpecificationEditor.js.map