diff --git a/src/main/resources/public/css/form-js.css b/src/main/resources/public/css/form-js.css index 1abed5c..6768d0b 100644 --- a/src/main/resources/public/css/form-js.css +++ b/src/main/resources/public/css/form-js.css @@ -28,21 +28,57 @@ --color-red-360-100-97: hsl(360, 100%, 97%); --color-white: hsl(0, 0%, 100%); --color-black: hsl(0, 0%, 0%); - --color-background: var(--color-white); - --color-background-disabled: var(--color-grey-225-10-95); - --color-background-adornment: var(--color-grey-225-10-95); - --color-icon-base: var(--color-black); - --color-text: var(--color-grey-225-10-15); - --color-text-light: var(--color-grey-225-10-35); - --color-text-lighter: var(--color-grey-225-10-45); - --color-text-lightest: var(--color-grey-225-10-55); - --color-text-inverted: var(--color-white); - --color-borders: var(--color-grey-225-10-55); - --color-borders-disabled: var(--color-grey-225-10-75); - --color-borders-adornment: var(--color-grey-225-10-85); - --color-warning: var(--color-red-360-100-45); - --color-accent: var(--color-blue-205-100-40); - --color-datepicker-focused-day: var(--color-grey-225-10-55); + /** + * Specify color variables in the following schema: + * 1 - use specified layer + * 2 - use layer one + * 3 - use fallback + */ + --color-background: var( + --cds-field, + var(--cds-field-01, var(--color-white)) + ); + --color-background-disabled: var(--cds-background, var(--color-grey-225-10-95)); + --color-background-readonly: var(--cds-background, var(--color-grey-225-10-95)); + --color-background-adornment: var( + --cds-field, + var(--cds-field-01, var(--color-grey-225-10-95)) + ); + --color-background-inverted: var(--cds-background-inverse, var(--color-grey-225-10-90)); + --color-background-inverted-hover: var(--cds-background-inverse-hover, var(--color-grey-225-10-93)); + --color-background-active: var(--cds-background-active, var(--color-grey-225-10-75)); + --color-layer: var( + --cds-layer, + var(--cds-layer-01, var(--color-white)) + ); + --color-icon-base: var(--cds-icon-primary, var(--color-black)); + --color-icon-inverted: var(--cds-icon-inverse, var(--color-black)); + --color-text: var(--cds-text-primary, var(--color-grey-225-10-15)); + --color-text-light: var(--cds-text-secondary, var(--color-grey-225-10-35)); + --color-text-lighter: var(--cds-text-secondary, var(--color-grey-225-10-45)); + --color-text-lightest: var(--cds-text-placeholder, var(--color-grey-225-10-55)); + --color-text-inverted: var(--cds-text-inverse, var(--color-text)); + --color-text-disabled: var(--cds-text-disabled, var(--color-text-light)); + --color-borders: var( + --cds-border-strong, + var(--cds-border-strong-01, var(--color-grey-225-10-55)) + ); + --color-borders-disabled: var(--cds-border-disabled, var(--color-grey-225-10-75)); + --color-borders-adornment: var( + --cds-border-subtle, + var(--cds-border-subtle-01, var(--color-grey-225-10-85)) + ); + --color-borders-readonly: var(--cds-border-subtle, var(--color-grey-225-10-75)); + --color-borders-inverted: var(--cds-border-inverse, var(--color-grey-225-10-90)); + --color-warning: var(--cds-text-error, var(--color-red-360-100-45)); + --color-warning-light: var(--cds-text-error, var(--color-red-360-100-92)); + --color-accent: var(--cds-link-primary, var(--color-blue-205-100-40)); + --color-accent-readonly: var( + --cds-border-strong, + var(--cds-border-strong-01, var(--color-grey-225-10-55)) + ); + --color-datepicker-focused-day: var(--cds-button-primary, var(--color-grey-225-10-55)); + --color-shadow: var(--cds-shadow, var(--color-grey-225-10-85)); --font-family: "IBM Plex Sans", sans-serif; --font-size-base: 14px; --font-size-input: 14px; @@ -56,11 +92,49 @@ --form-field-height: 36px; --border-definition: 1px solid var(--color-borders); --border-definition-adornment: 1px solid var(--color-borders-adornment); - --outline-definition: 1px solid var(--color-borders); + --outline-definition: 1px solid var(--cds-focus, var(--color-borders)); --border-definition-disabled: 1px solid var(--color-borders-disabled); + --border-definition-readonly: 1px solid var(--color-borders-readonly); height: 100%; } +.fjs-no-theme { + --cds-field: initial; + --cds-field-01: initial; + --cds-background: initial; + --cds-background-inverse: initial; + --cds-background-inverse-hover: initial; + --cds-background-active: initial; + --cds-layer: initial; + --cds-layer-01: initial; + --cds-layer-02: initial; + --cds-icon-primary: initial; + --cds-icon-secondary: initial; + --cds-icon-inverse: initial; + --cds-text-primary: initial; + --cds-text-secondary: initial; + --cds-text-placeholder: initial; + --cds-text-inverse: initial; + --cds-text-disabled: initial; + --cds-border-strong: initial; + --cds-border-strong-01: initial; + --cds-border-disabled: initial; + --cds-border-subtle: initial; + --cds-border-subtle-01: initial; + --cds-border-inverse: initial; + --cds-text-error: initial; + --cds-link-primary: initial; + --cds-button-primary: initial; + --cds-shadow: initial; + --cds-focus: initial; + --cds-interactive: initial; + --cds-border-interactive: initial; + --cds-highlight: initial; + --cds-field-02: initial; + --cds-field-hover-02: initial; + --cds-toggle-off: initial; +} + /** * Layout styles */ @@ -81,10 +155,9 @@ } .fjs-container .fjs-layout-row { - width: 100%; + flex: auto; padding: 9px 0; position: relative; - margin-left: 1px; } .fjs-container .fjs-column { @@ -102,6 +175,8 @@ .fjs-container .cds--grid .cds--row { align-items: start; + margin-left: 0; + margin-right: 0; } @media (max-width: 66rem) { @@ -119,8 +194,8 @@ letter-spacing: var(--letter-spacing-base); font-weight: 400; color: var(--color-text); - background-color: var(--color-background); position: relative; + padding: 0 4px; } .fjs-container .fjs-form * { @@ -165,6 +240,7 @@ .fjs-container .fjs-taglist-input, .fjs-container .fjs-textarea, .fjs-container .fjs-select { + color: var(--color-text); border-color: var(--color-borders); background-color: var(--color-background); font-family: inherit; @@ -182,7 +258,9 @@ .fjs-container .fjs-taglist-input::placeholder, .fjs-container .fjs-textarea::placeholder, .fjs-container .fjs-select > option:disabled, -.fjs-container .fjs-select [disabled] { +.fjs-container .fjs-select [disabled], +.fjs-container .fjs-select > option:read-only, +.fjs-container .fjs-select [read-only] { color: var(--color-text-lightest); font-size: var(--font-size-input); line-height: var(--line-height-input); @@ -193,6 +271,9 @@ .fjs-container .fjs-form-field-label { display: flex; align-items: center; + white-space: nowrap; + overflow: hidden; + color: var(--color-text-light); } .fjs-container .fjs-incollapsible-label { @@ -207,10 +288,6 @@ letter-spacing: var(--letter-spacing-label); } -.fjs-container .fjs-form-field-label { - color: var(--color-text-light); -} - .fjs-container .fjs-form-field-description { color: var(--color-text-lighter); } @@ -256,8 +333,7 @@ color: var(--color-text-lighter); padding: 8px; width: auto !important; - min-width: 34px; - max-width: 30%; + min-width: min(34px, 20%); display: flex; overflow: hidden; } @@ -337,6 +413,7 @@ .fjs-container .fjs-input-group .fjs-taglist, .fjs-container .fjs-input-group .fjs-select { height: unset; + min-width: min(60px, 40%); width: 100%; } @@ -358,8 +435,9 @@ } .fjs-container .fjs-input-group .fjs-select-display.fjs-select-placeholder, -.fjs-container .fjs-disabled .fjs-input-group .fjs-select-display { - color: var(--color-text-lightest); +.fjs-container .fjs-disabled .fjs-input-group .fjs-select-display, +.fjs-container .fjs-readonly .fjs-input-group .fjs-select-display { + color: var(--color-text-lighter); line-height: var(--line-height-input); } @@ -396,6 +474,7 @@ width: 100%; height: 100%; display: flex; + position: relative; } .fjs-container .fjs-textarea { @@ -413,7 +492,7 @@ display: flex; flex-direction: column; border-radius: 0 2px 2px 0; - width: 23px; + width: clamp(16px, 40%, 23px); overflow: clip; border-left: var(--border-definition-adornment); } @@ -426,16 +505,16 @@ .fjs-container .fjs-number-arrow-container button { border: none; flex: 1; - color: var(--color-text-light); - background-color: var(--color-grey-225-10-95); + color: var(--color-text); + background-color: var(--color-background); font-weight: bold; font-size: 10px; line-height: 15px; } .fjs-container .fjs-number-arrow-container button:hover { - background-color: var(--color-grey-225-10-93); - color: var(--color-text); + background-color: var(--color-background-inverted-hover); + color: var(--cds-text-inverse, var(--color-text)); } .fjs-container .fjs-radio { @@ -449,7 +528,7 @@ } .fjs-container .fjs-button[type=submit] { - color: var(--color-text-inverted); + color: var(--cds-text-inverse, var(--color-white)); background-color: var(--color-accent); border-color: var(--color-accent); } @@ -503,26 +582,73 @@ .fjs-container .fjs-number-arrow-container.fjs-disabled button, .fjs-container .fjs-taglist.fjs-disabled, .fjs-container .fjs-disabled .fjs-input-group { - background-color: var(--color-background-disabled); + color: var(--color-text-disabled); + background-color: var(--cds-field, var(--color-background-disabled)); border-color: var(--color-borders-disabled); } +.fjs-container .fjs-number-arrow-container.fjs-disabled button { + background-color: var(--cds-toggle-off, var(--color-background-disabled)); +} + +.fjs-container .fjs-readonly .fjs-input:read-only:not(:disabled), +.fjs-container .fjs-readonly .fjs-textarea:read-only:not(:disabled), +.fjs-container .fjs-readonly .fjs-select:read-only:not(:disabled), +.fjs-container .fjs-number-arrow-container.fjs-readonly button, +.fjs-container .fjs-taglist.fjs-readonly, +.fjs-container .fjs-readonly .fjs-input-group { + background-color: var(--color-background-readonly); + border-color: var(--color-borders-readonly); +} + +.fjs-container .fjs-form-field-checkbox.fjs-readonly, +.fjs-container .fjs-form-field-checklist.fjs-readonly, +.fjs-container .fjs-form-field-radio.fjs-readonly { + pointer-events: none; +} + +.fjs-container .fjs-form-field-checkbox.fjs-readonly .fjs-input:not(:disabled), +.fjs-container .fjs-form-field-checklist.fjs-readonly .fjs-input:not(:disabled), +.fjs-container .fjs-form-field-radio.fjs-readonly .fjs-input:not(:disabled) { + opacity: 0.4; + accent-color: var(--color-accent-readonly); +} + .fjs-container .fjs-button[type=submit]:disabled, .fjs-container .fjs-button[type=reset]:disabled { - color: var(--text-light); + color: var(--cds-text-on-color-disabled, var(--color-text-light)); background-color: var(--color-background-disabled); border-color: var(--color-borders-disabled); } +.fjs-container .fjs-button[type=submit]:read-only, +.fjs-container .fjs-button[type=reset]:read-only { + color: var(--text-light); + background-color: var(--color-background-readonly); + border-color: var(--color-borders-readonly); +} + .fjs-container .fjs-disabled .fjs-input-group .fjs-input-adornment, .fjs-container .fjs-disabled .fjs-input-group .fjs-number-arrow-container, .fjs-container .fjs-disabled .fjs-input-group .fjs-number-arrow-separator { border-color: var(--color-borders-disabled); } +.fjs-container .fjs-disabled .fjs-input-group .fjs-number-arrow-container .fjs-number-arrow-up, +.fjs-container .fjs-disabled .fjs-input-group .fjs-number-arrow-container .fjs-number-arrow-down { + pointer-events: none; +} + +.fjs-container .fjs-readonly .fjs-input-group .fjs-input-adornment, +.fjs-container .fjs-readonly .fjs-input-group .fjs-number-arrow-container, +.fjs-container .fjs-readonly .fjs-input-group .fjs-number-arrow-separator { + border-color: var(--color-borders-readonly); +} + .fjs-container .fjs-form-field.fjs-has-errors .fjs-input, .fjs-container .fjs-form-field.fjs-has-errors .fjs-select, .fjs-container .fjs-form-field.fjs-has-errors .fjs-textarea, +.fjs-container .fjs-form-field.fjs-has-errors .fjs-taglist, .fjs-container .fjs-form-field.fjs-has-errors .fjs-input-group, .fjs-container .fjs-form-field.fjs-has-errors .fjs-input-group .fjs-input { border-color: var(--color-warning); @@ -546,8 +672,7 @@ } .fjs-container .fjs-form-field.fjs-has-errors .fjs-input-adornment { - border-color: var(--color-red-360-100-92); - background: var(--color-red-360-100-97); + border-color: var(--color-warning-light); } .fjs-container .fjs-form-field-error { @@ -589,6 +714,14 @@ top: -5px; } +.fjs-container .fjs-select-hidden-input { + width: 0; + overflow: hidden; + opacity: 0; + padding: 0; + border: none; +} + .fjs-container .fjs-taglist { display: flex; flex-wrap: wrap; @@ -604,12 +737,14 @@ display: flex; overflow: hidden; user-select: none; - background-color: var(--color-grey-225-10-90); + color: var(--color-text-inverted); + background-color: var(--color-background-inverted); border-radius: 2px; } -.fjs-container .fjs-taglist.fjs-disabled .fjs-taglist-tag { - background-color: var(--color-grey-225-10-85); +.fjs-container .fjs-taglist.fjs-disabled .fjs-taglist-tag, +.fjs-container .fjs-taglist.fjs-readonly .fjs-taglist-tag { + background-color: var(--color-background-inverted); } .fjs-container .fjs-taglist .fjs-taglist-tags { @@ -622,7 +757,8 @@ padding: 2px 6px 2px 8px; } -.fjs-container .fjs-taglist.fjs-disabled .fjs-taglist-tag .fjs-taglist-tag-label { +.fjs-container .fjs-taglist.fjs-disabled .fjs-taglist-tag .fjs-taglist-tag-label, +.fjs-container .fjs-taglist.fjs-readonly .fjs-taglist-tag .fjs-taglist-tag-label { padding: 2px 8px; } @@ -632,7 +768,7 @@ height: 24px; text-align: center; line-height: 28px; - background-color: var(--color-grey-225-10-80); + background-color: var(--cds-background-inverse, var(--color-grey-225-10-80)); border: none; padding: 1px 0; } @@ -640,12 +776,12 @@ .fjs-container .fjs-taglist .fjs-taglist-tag .fjs-taglist-tag-remove > svg { margin-bottom: 4px; opacity: 0.6; - color: var(--color-icon-base); + color: var(--color-icon-inverted); } .fjs-container .fjs-taglist .fjs-taglist-tag .fjs-taglist-tag-remove:hover, .fjs-container .fjs-taglist .fjs-taglist-tag .fjs-taglist-tag-remove:focus-visible { - background-color: var(--color-grey-225-10-75); + background-color: var(--color-background-active); } .fjs-container .fjs-taglist .fjs-taglist-tag .fjs-taglist-tag-remove:hover > svg, @@ -674,14 +810,14 @@ width: 100%; border-radius: 3px; margin-top: 3px; - box-shadow: 0px 0px 5px var(--color-grey-225-10-85); - background-color: var(--color-white); + box-shadow: 0px 0px 5px var(--color-shadow); + background-color: var(--color-layer); } .fjs-container .fjs-dropdownlist .fjs-dropdownlist-item { padding: 6px 8px; - border-bottom: 1px solid var(--color-grey-225-10-90); - color: var(--color-grey-225-10-35); + border-bottom: 1px solid var(--color-borders-inverted); + color: var(--color-text-light); } .fjs-container .fjs-dropdownlist .fjs-dropdownlist-item:last-child { @@ -689,8 +825,8 @@ } .fjs-container .fjs-dropdownlist .fjs-dropdownlist-item.focused { - background-color: var(--color-grey-225-10-90); - color: var(--color-black); + background-color: var(--color-background-inverted); + color: var(--color-text-inverted); } .fjs-container .fjs-dropdownlist .fjs-dropdownlist-empty { @@ -3342,4 +3478,4 @@ span.flatpickr-weekday { } span.flatpickr-day.selected { font-weight: bold; -} +} \ No newline at end of file diff --git a/src/main/resources/public/js/form-viewer.umd.js b/src/main/resources/public/js/form-viewer.umd.js index 8f9bef5..1133039 100644 --- a/src/main/resources/public/js/form-viewer.umd.js +++ b/src/main/resources/public/js/form-viewer.umd.js @@ -11859,7 +11859,7 @@ * @return { ValueProducer } */ static of(fn) { - return new ValueProducer$1(fn); + return new ValueProducer(fn); } }; @@ -12084,7 +12084,7 @@ */ assign(options = {}) { - return Variables$1.of({ + return Variables.of({ ...this, ...options }); @@ -12102,7 +12102,7 @@ parent: this.parent }; - return Variables$1.of({ + return Variables.of({ ...defaultOptions, ...options }); @@ -12119,7 +12119,7 @@ raw } = options; - return new Variables$1({ + return new Variables({ name, tokens: [ ...tokens ], children: [ ...children ], @@ -16975,7 +16975,7 @@ if (text.length == 0) throw new RangeError("A document must have at least one line"); if (text.length == 1 && !text[0]) - return Text$1.empty; + return Text.empty; return text.length <= 32 /* Tree.Branch */ ? new TextLeaf(text) : TextNode.from(TextLeaf.split(text, [])); } }; @@ -32140,365 +32140,365 @@ })); }; - syntaxHighlighting(HighlightStyle.define([ - { tag: tags.strong, fontWeight: 'bold' }, - { tag: tags.emphasis, fontStyle: 'italic' }, - ])); - - EditorView.theme({ - '& .cm-lintRange': { - position: 'relative', - }, - '& .cm-lintRange::after': { - content: '""', - width: '100%', - position: 'absolute', - left: '0px', - bottom: '-2px', - height: '3px', - backgroundRepeat: 'repeat-x', - }, - '& .cm-lintRange.cm-lintRange-warning, & .cm-lintRange.cm-lintRange-error': { - backgroundImage: 'none', - }, - '& .cm-lintPoint::after': { - bottom: '-2px' - } - }); - - const _urlify = (color) => `%23${color.slice(1)}`; - - const colors = { - black: '#1f2b36', - darkGrey: '#2f3d58', - grey: '#404a5c', - midGrey: '#576071', - lightGrey: '#c5d1e5', - offWhite: '#d9e0f5', - snowWhite: '#eaf1ff', - white: '#ffffff', - mossGreen: '#7ab6aa', - iceBlue: '#6cbfd8', - waterBlue: '#065aaa', - brightBlue: '#0a56b9', - deepBlue: '#355472', - red: '#9f1c15', - orangeBrown: '#b4502f', - yellow: '#debd71', - lila: '#9a4890', - purple: '#5b2c83' - }; - - const colorByRole = { - lightBackground: colors.white, - darkBackground: colors.snowWhite, - selection: colors.snowWhite, - tooltipBackground: colors.offWhite, - error: colors.red, - warning: colors.yellow, - invalid: '#b40000' - }; - - EditorView.theme( - { - '&': { color: colors.black, backgroundColor: colorByRole.lightBackground }, - '.cm-content': { caretColor: colors.darkGrey }, - '.cm-cursor, .cm-dropCursor': { borderLeftColor: colors.darkGrey }, - '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': - { backgroundColor: colorByRole.selection }, - - '.cm-panels': { backgroundColor: colorByRole.darkBackground, color: colors.grey }, - '.cm-panels.cm-panels-top': { borderBottom: `2px solid ${ colors.black }` }, - '.cm-panels.cm-panels-bottom': { borderTop: `2px solid ${ colors.black }` }, - - '.cm-searchMatch': { - backgroundColor: '#72a1ff59', - outline: `1px solid ${colors.midGrey}` - }, - '.cm-searchMatch.cm-searchMatch-selected': { backgroundColor: colors.offWhite }, - '.cm-activeLine': { backgroundColor: colorByRole.selection }, - '.cm-selectionMatch': { backgroundColor: colors.offWhite }, - - '&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': { - outline: `1px solid ${colors.grey}` - }, - - '&.cm-focused .cm-matchingBracket': { - backgroundColor: colors.snowWhite - }, - - '.cm-gutters': { - backgroundColor: '#f3f7fe', - color: '#52668d', - border: 'none', - padding: '0 5px' - }, - - '.cm-activeLineGutter': { - backgroundColor: colorByRole.selection - }, - - '.cm-foldPlaceholder': { - backgroundColor: 'transparent', - border: 'none', - color: '#ddd' - }, - - '.cm-tooltip': { - border: 'none', - backgroundColor: colorByRole.tooltipBackground - }, - '.cm-tooltip .cm-tooltip-arrow:before': { - borderTopColor: 'transparent', - borderBottomColor: 'transparent' - }, - '.cm-tooltip .cm-tooltip-arrow:after': { - borderTopColor: colorByRole.tooltipBackground, - borderBottomColor: colorByRole.tooltipBackground - }, - '.cm-tooltip-autocomplete': { - '& > ul > li[aria-selected]': { - backgroundColor: colorByRole.darkBackground, - color: colors.midGrey - } - }, - '& .cm-lintRange.cm-lintRange-warning::after': { - backgroundImage: `url("data:image/svg+xml,")`, - }, - '& .cm-lintRange.cm-lintRange-error::after': { - backgroundImage: `url("data:image/svg+xml,")`, - }, - '& .cm-diagnostic-warning': { - border: `1px solid ${colorByRole.warning}`, - borderLeft: `5px solid ${colorByRole.warning}`, - background: colorByRole.lightBackground, - }, - '& .cm-diagnostic-error': { - border: `1px solid ${colorByRole.error}`, - borderLeft: `5px solid ${colorByRole.error}`, - background: colorByRole.lightBackground - }, - '& .cm-diagnostic': { - padding: '3px 8px' - } - }, - { dark: false } - ); - - syntaxHighlighting(HighlightStyle.define([ - { - tag: [ tags.macroName, tags.variableName ], - color: colors.waterBlue - }, - { - tag: [ tags.special(tags.bracket) ], - color: colors.waterBlue, - fontWeight: 'bold' - }, - { - tag: [ tags.color, tags.name, tags.definition(tags.name), tags.constant(tags.name), tags.standard(tags.name), tags.propertyName, ], - color: colors.deepBlue - }, - { - tag: [ tags.definition(tags.variableName), tags.function(tags.variableName), tags.function(tags.propertyName) ], - color: colors.brightBlue, - }, - { tag: [ tags.labelName ], color: colors.orangeBrown }, - { - tag: [ tags.annotation ], - color: colorByRole.invalid - }, - { - tag: [ tags.number, tags.changed, tags.annotation, tags.modifier, tags.self, tags.namespace, tags.atom, tags.bool, tags.special(tags.variableName) ], - color: colors.red - }, - { - tag: [ tags.typeName, tags.className, tags.attributeName ], - color: colors.lila - }, - { - tag: [ tags.operator, tags.operatorKeyword, tags.tagName, tags.keyword ], - color: colors.purple - }, - { - tag: [ tags.angleBracket, tags.squareBracket, tags.brace, tags.separator, tags.punctuation ], - color: colors.midGrey - }, - { - tag: [ tags.regexp ], - color: colors.deepBlue - }, - { - tag: [ tags.quote ], - color: colors.darkGrey - }, - { tag: [ tags.string, tags.character, tags.deleted ], color: colors.orangeBrown }, - { - tag: tags.link, - color: colors.mossGreen, - textDecoration: 'underline', - textUnderlinePosition: 'under' - }, - { - tag: [ tags.url, tags.escape, tags.special(tags.string) ], - color: colors.red - }, - { tag: [ tags.meta ], color: colors.iceBlue }, - { tag: [ tags.comment ], color: colors.midGrey, fontStyle: 'italic' }, - { tag: tags.strong, fontWeight: 'bold', color: colors.deepBlue }, - { tag: tags.emphasis, fontStyle: 'italic', color: colors.deepBlue }, - { tag: tags.strikethrough, textDecoration: 'line-through' }, - { tag: tags.heading, fontWeight: 'bold', color: colors.midGray }, - { tag: tags.special(tags.heading1), fontWeight: 'bold', color: colors.darkGrey }, - { - tag: [ tags.heading1, tags.heading2, tags.heading3, tags.heading4 ], - fontWeight: 'bold', - color: colors.midGrey - }, - { tag: [ tags.heading5, tags.heading6, tags.processingInstruction, tags.inserted ], color: colors.grey }, - { - tag: [ tags.contentSeparator ], - color: colors.yellow - }, - { tag: tags.invalid, color: colors.midGrey, borderBottom: `1px dotted ${colorByRole.invalid}` } - ])); - - const ivory = '#abb2bf', - peach = '#f07178', - stone = '#7d8799', - invalid = '#ffffff', - pastelYellow = '#fffce1', - pastelOrange = '#ec9e6f', - raisinBlack = '#21252b', - highlightBackground = 'rgba(0, 0, 0, 0.5)', - background = '#292d3e', - tooltipBackground = '#353a42', - selection = 'rgba(128, 203, 196, 0.2)', - cursor = '#ffcc00'; - - const urlHash = '%23'; - const warningColorHex = 'fff890'; - const errorColor = 'red'; - const warningBackgroundColor = '#281e16'; - const errorBackgroundColor = '#281616'; - - EditorView.theme( - { - '&': { - color: '#ffffff', - backgroundColor: background - }, - '.cm-content': { - caretColor: cursor - }, - '&.cm-focused .cm-cursor': { - borderLeftColor: cursor - }, - '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': - { backgroundColor: selection }, - '.cm-panels': { backgroundColor: raisinBlack, color: '#ffffff' }, - '.cm-panels.cm-panels-top': { borderBottom: '2px solid black' }, - '.cm-panels.cm-panels-bottom': { borderTop: '2px solid black' }, - '.cm-searchMatch': { - backgroundColor: '#72a1ff59', - outline: '1px solid #457dff' - }, - '.cm-searchMatch.cm-searchMatch-selected': { - backgroundColor: '#6199ff2f' - }, - '.cm-activeLine': { backgroundColor: highlightBackground }, - '.cm-selectionMatch': { backgroundColor: '#aafe661a' }, - '&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': { - backgroundColor: '#bad0f847', - outline: '1px solid #515a6b' - }, - '.cm-gutters': { - background: '#292d3e', - color: '#676e95', - border: 'none', - padding: '0 5px' - }, - '.cm-activeLineGutter': { - backgroundColor: highlightBackground - }, - '.cm-foldPlaceholder': { - backgroundColor: 'transparent', - border: 'none', - color: '#ddd' - }, - '.cm-tooltip': { - border: 'none', - backgroundColor: tooltipBackground - }, - '.cm-tooltip .cm-tooltip-arrow:before': { - borderTopColor: 'transparent', - borderBottomColor: 'transparent' - }, - '.cm-tooltip .cm-tooltip-arrow:after': { - borderTopColor: tooltipBackground, - borderBottomColor: tooltipBackground - }, - '.cm-tooltip-autocomplete': { - '& > ul > li[aria-selected]': { - backgroundColor: highlightBackground, - color: ivory - } - }, - '& .cm-lintRange.cm-lintRange-warning::after': { - backgroundImage: `url("data:image/svg+xml,")`, - }, - '& .cm-lintRange.cm-lintRange-error::after': { - backgroundImage: `url("data:image/svg+xml,")`, - }, - '& .cm-diagnostic-warning': { - borderLeft: `5px solid #${warningColorHex}`, - background: warningBackgroundColor - }, - '& .cm-diagnostic-error': { - borderLeft: `5px solid ${errorColor}`, - background: errorBackgroundColor - }, - '& .cm-diagnostic': { - borderRadius: '2px', - padding: '3px 8px' - } - }, - { dark: true } - ); - - syntaxHighlighting(HighlightStyle.define([ - - // Markdown headings - { tag: tags.heading1, color: pastelYellow }, - { tag: tags.heading2, color: pastelYellow }, - { tag: tags.heading3, color: pastelYellow }, - { tag: tags.heading4, color: pastelYellow }, - { tag: tags.heading5, color: pastelYellow }, - { tag: tags.heading6, color: pastelYellow }, - - // Feelers - { tag: tags.special(tags.bracket), color: pastelOrange, fontWeight: 'bold' }, - - // Everything else - { tag: tags.keyword, color: '#c792ea' }, - { tag: tags.operator, color: '#89ddff' }, - { tag: tags.special(tags.variableName), color: '#eeffff' }, - { tag: tags.typeName, color: '#f07178' }, - { tag: tags.atom, color: '#f78c6c' }, - { tag: tags.number, color: '#ff5370' }, - { tag: tags.bool, color: '#ff5370' }, - { tag: tags.definition(tags.variableName), color: '#82aaff' }, - { tag: tags.string, color: '#c3e88d' }, - { tag: tags.comment, color: stone }, - { tag: tags.tagName, color: '#ff5370' }, - { tag: tags.bracket, color: '#a2a1a4' }, - { tag: tags.meta, color: '#ffcb6b' }, - { tag: tags.special(tags.string), color: peach }, - { tag: tags.propertyName, color: pastelOrange }, - { tag: tags.variableName, color: pastelOrange }, - { tag: tags.attributeName, color: peach }, - { tag: tags.className, color: peach }, - { tag: tags.invalid, color: invalid } + syntaxHighlighting(HighlightStyle.define([ + { tag: tags.strong, fontWeight: 'bold' }, + { tag: tags.emphasis, fontStyle: 'italic' }, + ])); + + EditorView.theme({ + '& .cm-lintRange': { + position: 'relative', + }, + '& .cm-lintRange::after': { + content: '""', + width: '100%', + position: 'absolute', + left: '0px', + bottom: '-2px', + height: '3px', + backgroundRepeat: 'repeat-x', + }, + '& .cm-lintRange.cm-lintRange-warning, & .cm-lintRange.cm-lintRange-error': { + backgroundImage: 'none', + }, + '& .cm-lintPoint::after': { + bottom: '-2px' + } + }); + + const _urlify = (color) => `%23${color.slice(1)}`; + + const colors = { + black: '#1f2b36', + darkGrey: '#2f3d58', + grey: '#404a5c', + midGrey: '#576071', + lightGrey: '#c5d1e5', + offWhite: '#d9e0f5', + snowWhite: '#eaf1ff', + white: '#ffffff', + mossGreen: '#7ab6aa', + iceBlue: '#6cbfd8', + waterBlue: '#065aaa', + brightBlue: '#0a56b9', + deepBlue: '#355472', + red: '#9f1c15', + orangeBrown: '#b4502f', + yellow: '#debd71', + lila: '#9a4890', + purple: '#5b2c83' + }; + + const colorByRole = { + lightBackground: colors.white, + darkBackground: colors.snowWhite, + selection: colors.snowWhite, + tooltipBackground: colors.offWhite, + error: colors.red, + warning: colors.yellow, + invalid: '#b40000' + }; + + EditorView.theme( + { + '&': { color: colors.black, backgroundColor: colorByRole.lightBackground }, + '.cm-content': { caretColor: colors.darkGrey }, + '.cm-cursor, .cm-dropCursor': { borderLeftColor: colors.darkGrey }, + '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': + { backgroundColor: colorByRole.selection }, + + '.cm-panels': { backgroundColor: colorByRole.darkBackground, color: colors.grey }, + '.cm-panels.cm-panels-top': { borderBottom: `2px solid ${ colors.black }` }, + '.cm-panels.cm-panels-bottom': { borderTop: `2px solid ${ colors.black }` }, + + '.cm-searchMatch': { + backgroundColor: '#72a1ff59', + outline: `1px solid ${colors.midGrey}` + }, + '.cm-searchMatch.cm-searchMatch-selected': { backgroundColor: colors.offWhite }, + '.cm-activeLine': { backgroundColor: colorByRole.selection }, + '.cm-selectionMatch': { backgroundColor: colors.offWhite }, + + '&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': { + outline: `1px solid ${colors.grey}` + }, + + '&.cm-focused .cm-matchingBracket': { + backgroundColor: colors.snowWhite + }, + + '.cm-gutters': { + backgroundColor: '#f3f7fe', + color: '#52668d', + border: 'none', + padding: '0 5px' + }, + + '.cm-activeLineGutter': { + backgroundColor: colorByRole.selection + }, + + '.cm-foldPlaceholder': { + backgroundColor: 'transparent', + border: 'none', + color: '#ddd' + }, + + '.cm-tooltip': { + border: 'none', + backgroundColor: colorByRole.tooltipBackground + }, + '.cm-tooltip .cm-tooltip-arrow:before': { + borderTopColor: 'transparent', + borderBottomColor: 'transparent' + }, + '.cm-tooltip .cm-tooltip-arrow:after': { + borderTopColor: colorByRole.tooltipBackground, + borderBottomColor: colorByRole.tooltipBackground + }, + '.cm-tooltip-autocomplete': { + '& > ul > li[aria-selected]': { + backgroundColor: colorByRole.darkBackground, + color: colors.midGrey + } + }, + '& .cm-lintRange.cm-lintRange-warning::after': { + backgroundImage: `url("data:image/svg+xml,")`, + }, + '& .cm-lintRange.cm-lintRange-error::after': { + backgroundImage: `url("data:image/svg+xml,")`, + }, + '& .cm-diagnostic-warning': { + border: `1px solid ${colorByRole.warning}`, + borderLeft: `5px solid ${colorByRole.warning}`, + background: colorByRole.lightBackground, + }, + '& .cm-diagnostic-error': { + border: `1px solid ${colorByRole.error}`, + borderLeft: `5px solid ${colorByRole.error}`, + background: colorByRole.lightBackground + }, + '& .cm-diagnostic': { + padding: '3px 8px' + } + }, + { dark: false } + ); + + syntaxHighlighting(HighlightStyle.define([ + { + tag: [ tags.macroName, tags.variableName ], + color: colors.waterBlue + }, + { + tag: [ tags.special(tags.bracket) ], + color: colors.waterBlue, + fontWeight: 'bold' + }, + { + tag: [ tags.color, tags.name, tags.definition(tags.name), tags.constant(tags.name), tags.standard(tags.name), tags.propertyName, ], + color: colors.deepBlue + }, + { + tag: [ tags.definition(tags.variableName), tags.function(tags.variableName), tags.function(tags.propertyName) ], + color: colors.brightBlue, + }, + { tag: [ tags.labelName ], color: colors.orangeBrown }, + { + tag: [ tags.annotation ], + color: colorByRole.invalid + }, + { + tag: [ tags.number, tags.changed, tags.annotation, tags.modifier, tags.self, tags.namespace, tags.atom, tags.bool, tags.special(tags.variableName) ], + color: colors.red + }, + { + tag: [ tags.typeName, tags.className, tags.attributeName ], + color: colors.lila + }, + { + tag: [ tags.operator, tags.operatorKeyword, tags.tagName, tags.keyword ], + color: colors.purple + }, + { + tag: [ tags.angleBracket, tags.squareBracket, tags.brace, tags.separator, tags.punctuation ], + color: colors.midGrey + }, + { + tag: [ tags.regexp ], + color: colors.deepBlue + }, + { + tag: [ tags.quote ], + color: colors.darkGrey + }, + { tag: [ tags.string, tags.character, tags.deleted ], color: colors.orangeBrown }, + { + tag: tags.link, + color: colors.mossGreen, + textDecoration: 'underline', + textUnderlinePosition: 'under' + }, + { + tag: [ tags.url, tags.escape, tags.special(tags.string) ], + color: colors.red + }, + { tag: [ tags.meta ], color: colors.iceBlue }, + { tag: [ tags.comment ], color: colors.midGrey, fontStyle: 'italic' }, + { tag: tags.strong, fontWeight: 'bold', color: colors.deepBlue }, + { tag: tags.emphasis, fontStyle: 'italic', color: colors.deepBlue }, + { tag: tags.strikethrough, textDecoration: 'line-through' }, + { tag: tags.heading, fontWeight: 'bold', color: colors.midGray }, + { tag: tags.special(tags.heading1), fontWeight: 'bold', color: colors.darkGrey }, + { + tag: [ tags.heading1, tags.heading2, tags.heading3, tags.heading4 ], + fontWeight: 'bold', + color: colors.midGrey + }, + { tag: [ tags.heading5, tags.heading6, tags.processingInstruction, tags.inserted ], color: colors.grey }, + { + tag: [ tags.contentSeparator ], + color: colors.yellow + }, + { tag: tags.invalid, color: colors.midGrey, borderBottom: `1px dotted ${colorByRole.invalid}` } + ])); + + const ivory = '#abb2bf', + peach = '#f07178', + stone = '#7d8799', + invalid = '#ffffff', + pastelYellow = '#fffce1', + pastelOrange = '#ec9e6f', + raisinBlack = '#21252b', + highlightBackground = 'rgba(0, 0, 0, 0.5)', + background = '#292d3e', + tooltipBackground = '#353a42', + selection = 'rgba(128, 203, 196, 0.2)', + cursor = '#ffcc00'; + + const urlHash = '%23'; + const warningColorHex = 'fff890'; + const errorColor = 'red'; + const warningBackgroundColor = '#281e16'; + const errorBackgroundColor = '#281616'; + + EditorView.theme( + { + '&': { + color: '#ffffff', + backgroundColor: background + }, + '.cm-content': { + caretColor: cursor + }, + '&.cm-focused .cm-cursor': { + borderLeftColor: cursor + }, + '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': + { backgroundColor: selection }, + '.cm-panels': { backgroundColor: raisinBlack, color: '#ffffff' }, + '.cm-panels.cm-panels-top': { borderBottom: '2px solid black' }, + '.cm-panels.cm-panels-bottom': { borderTop: '2px solid black' }, + '.cm-searchMatch': { + backgroundColor: '#72a1ff59', + outline: '1px solid #457dff' + }, + '.cm-searchMatch.cm-searchMatch-selected': { + backgroundColor: '#6199ff2f' + }, + '.cm-activeLine': { backgroundColor: highlightBackground }, + '.cm-selectionMatch': { backgroundColor: '#aafe661a' }, + '&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': { + backgroundColor: '#bad0f847', + outline: '1px solid #515a6b' + }, + '.cm-gutters': { + background: '#292d3e', + color: '#676e95', + border: 'none', + padding: '0 5px' + }, + '.cm-activeLineGutter': { + backgroundColor: highlightBackground + }, + '.cm-foldPlaceholder': { + backgroundColor: 'transparent', + border: 'none', + color: '#ddd' + }, + '.cm-tooltip': { + border: 'none', + backgroundColor: tooltipBackground + }, + '.cm-tooltip .cm-tooltip-arrow:before': { + borderTopColor: 'transparent', + borderBottomColor: 'transparent' + }, + '.cm-tooltip .cm-tooltip-arrow:after': { + borderTopColor: tooltipBackground, + borderBottomColor: tooltipBackground + }, + '.cm-tooltip-autocomplete': { + '& > ul > li[aria-selected]': { + backgroundColor: highlightBackground, + color: ivory + } + }, + '& .cm-lintRange.cm-lintRange-warning::after': { + backgroundImage: `url("data:image/svg+xml,")`, + }, + '& .cm-lintRange.cm-lintRange-error::after': { + backgroundImage: `url("data:image/svg+xml,")`, + }, + '& .cm-diagnostic-warning': { + borderLeft: `5px solid #${warningColorHex}`, + background: warningBackgroundColor + }, + '& .cm-diagnostic-error': { + borderLeft: `5px solid ${errorColor}`, + background: errorBackgroundColor + }, + '& .cm-diagnostic': { + borderRadius: '2px', + padding: '3px 8px' + } + }, + { dark: true } + ); + + syntaxHighlighting(HighlightStyle.define([ + + // Markdown headings + { tag: tags.heading1, color: pastelYellow }, + { tag: tags.heading2, color: pastelYellow }, + { tag: tags.heading3, color: pastelYellow }, + { tag: tags.heading4, color: pastelYellow }, + { tag: tags.heading5, color: pastelYellow }, + { tag: tags.heading6, color: pastelYellow }, + + // Feelers + { tag: tags.special(tags.bracket), color: pastelOrange, fontWeight: 'bold' }, + + // Everything else + { tag: tags.keyword, color: '#c792ea' }, + { tag: tags.operator, color: '#89ddff' }, + { tag: tags.special(tags.variableName), color: '#eeffff' }, + { tag: tags.typeName, color: '#f07178' }, + { tag: tags.atom, color: '#f78c6c' }, + { tag: tags.number, color: '#ff5370' }, + { tag: tags.bool, color: '#ff5370' }, + { tag: tags.definition(tags.variableName), color: '#82aaff' }, + { tag: tags.string, color: '#c3e88d' }, + { tag: tags.comment, color: stone }, + { tag: tags.tagName, color: '#ff5370' }, + { tag: tags.bracket, color: '#a2a1a4' }, + { tag: tags.meta, color: '#ffcb6b' }, + { tag: tags.special(tags.string), color: peach }, + { tag: tags.propertyName, color: pastelOrange }, + { tag: tags.variableName, color: pastelOrange }, + { tag: tags.attributeName, color: peach }, + { tag: tags.className, color: peach }, + { tag: tags.invalid, color: invalid } ])); // This file was generated by lezer-generator. You probably shouldn't edit it. @@ -32506,85 +32506,85 @@ FeelBlock = 2, SimpleTextBlock = 3; - /* global console */ - - const CHAR_TABLE = { - '{': 123, - '}': 125 - }; - - const isClosingFeelScope = (input, offset = 0) => { - - const isReadingCloseCurrent = input.peek(offset) === CHAR_TABLE['}']; - const isReadingCloseAhead = input.peek(offset + 1) === CHAR_TABLE['}']; - - const isReadingClose = isReadingCloseCurrent && isReadingCloseAhead; - - return isReadingClose || input.peek(offset) === -1; - - }; - - const feelBlock = new ExternalTokenizer((input, stack) => { - - let lookAhead = 0; - - // check if we haven't reached the end of a templating tag - while (!isClosingFeelScope(input, lookAhead)) { lookAhead++; } - - if (lookAhead > 0) { - input.advance(lookAhead); - input.acceptToken(FeelBlock); - } - + /* global console */ + + const CHAR_TABLE = { + '{': 123, + '}': 125 + }; + + const isClosingFeelScope = (input, offset = 0) => { + + const isReadingCloseCurrent = input.peek(offset) === CHAR_TABLE['}']; + const isReadingCloseAhead = input.peek(offset + 1) === CHAR_TABLE['}']; + + const isReadingClose = isReadingCloseCurrent && isReadingCloseAhead; + + return isReadingClose || input.peek(offset) === -1; + + }; + + const feelBlock = new ExternalTokenizer((input, stack) => { + + let lookAhead = 0; + + // check if we haven't reached the end of a templating tag + while (!isClosingFeelScope(input, lookAhead)) { lookAhead++; } + + if (lookAhead > 0) { + input.advance(lookAhead); + input.acceptToken(FeelBlock); + } + + }); + + const isClosingTextScope = (input, offset = 0) => { + const isReadingOpenCurrent = input.peek(offset) === CHAR_TABLE['{']; + const isReadingOpenAhead = input.peek(offset + 1) === CHAR_TABLE['{']; + + const isReadOpen = isReadingOpenCurrent && isReadingOpenAhead; + + return isReadOpen || input.peek(offset) === -1; + }; + + + const simpleTextBlock = new ExternalTokenizer((input, stack) => { + + let lookAhead = 0; + + // check if we haven't reached the start of a templating tag + while (!isClosingTextScope(input, lookAhead)) { lookAhead++; } + + if (lookAhead > 0) { + input.advance(lookAhead); + input.acceptToken(SimpleTextBlock); + } + + }); + + // Anytime this tokenizer is run, simply tag the rest of the input as FEEL + const feel = new ExternalTokenizer((input, stack) => { + + let lookAhead = 0; + + while (input.peek(lookAhead) !== -1) { lookAhead++; } + + if (lookAhead > 0) { + input.advance(lookAhead); + input.acceptToken(Feel); + } + }); - const isClosingTextScope = (input, offset = 0) => { - const isReadingOpenCurrent = input.peek(offset) === CHAR_TABLE['{']; - const isReadingOpenAhead = input.peek(offset + 1) === CHAR_TABLE['{']; - - const isReadOpen = isReadingOpenCurrent && isReadingOpenAhead; - - return isReadOpen || input.peek(offset) === -1; - }; - - - const simpleTextBlock = new ExternalTokenizer((input, stack) => { - - let lookAhead = 0; - - // check if we haven't reached the start of a templating tag - while (!isClosingTextScope(input, lookAhead)) { lookAhead++; } - - if (lookAhead > 0) { - input.advance(lookAhead); - input.acceptToken(SimpleTextBlock); - } - - }); - - // Anytime this tokenizer is run, simply tag the rest of the input as FEEL - const feel = new ExternalTokenizer((input, stack) => { - - let lookAhead = 0; - - while (input.peek(lookAhead) !== -1) { lookAhead++; } - - if (lookAhead > 0) { - input.advance(lookAhead); - input.acceptToken(Feel); - } - - }); - - const feelersHighlighting = styleTags({ - ConditionalSpanner: tags.special(tags.bracket), - ConditionalSpannerClose: tags.special(tags.bracket), - ConditionalSpannerCloseNl: tags.special(tags.bracket), - LoopSpanner: tags.special(tags.bracket), - LoopSpannerClose: tags.special(tags.bracket), - LoopSpannerCloseNl: tags.special(tags.bracket), - EmptyInsert: tags.special(tags.bracket), - Insert: tags.special(tags.bracket), + const feelersHighlighting = styleTags({ + ConditionalSpanner: tags.special(tags.bracket), + ConditionalSpannerClose: tags.special(tags.bracket), + ConditionalSpannerCloseNl: tags.special(tags.bracket), + LoopSpanner: tags.special(tags.bracket), + LoopSpannerClose: tags.special(tags.bracket), + LoopSpannerCloseNl: tags.special(tags.bracket), + EmptyInsert: tags.special(tags.bracket), + Insert: tags.special(tags.bracket), }); // This file was generated by lezer-generator. You probably shouldn't edit it. @@ -32604,282 +32604,282 @@ tokenPrec: 0 }); - function buildSimpleTree(parseTree, templateString) { - - const stack = [ { children: [] } ]; - const isLeafNode = (node) => [ 'SimpleTextBlock', 'Feel', 'FeelBlock' ].includes(node.type.name); - - parseTree.iterate({ - enter: (node, pos, type) => { - - const nodeRepresentation = { - name: node.type.name, - children: [] - }; - - if (isLeafNode(node)) { - nodeRepresentation.content = templateString.slice(node.from, node.to); - } - - stack.push(nodeRepresentation); - }, - leave: (node, pos, type) => { - const result = stack.pop(); - const parent = stack[stack.length - 1]; - result.parent = parent; - parent.children.push(result); - } - }); - - return stack[0].children[0]; - } - - /** - * @typedef {object} EvaluationOptions - * @property {boolean} [debug=false] - whether to enable debug mode, which displays errors inline instead of throwing them - * @property {function} [buildDebugString=(e) => `{{ ${e.message.toLowerCase()} }}`] - function that takes an error and returns the string to display in debug mode - * @property {boolean} [strict=false] - whether to expect strict data types out of our FEEL expression, e.g. boolean for conditionals - */ - - /** - * @param {string} templateString - the template string to evaluate - * @param {object} [context={}] - the context object to evaluate the template string against - * @param {EvaluationOptions} [options={}] - options to configure the evaluation - * @return {string} the evaluated template string - */ - const evaluate = (templateString, context = {}, options = {}) => { - - const { - debug = false, - buildDebugString = (e) => `{{ ${e.message.toLowerCase()} }}`, - strict = false - } = options; - - const parseTree = parser.parse(templateString); - - const simpleTreeRoot = buildSimpleTree(parseTree, templateString); - - const evaluateNode = buildNodeEvaluator(debug, buildDebugString, strict); - - return evaluateNode(simpleTreeRoot, enhanceContext(context, null)); - + function buildSimpleTree(parseTree, templateString) { + + const stack = [ { children: [] } ]; + const isLeafNode = (node) => [ 'SimpleTextBlock', 'Feel', 'FeelBlock' ].includes(node.type.name); + + parseTree.iterate({ + enter: (node, pos, type) => { + + const nodeRepresentation = { + name: node.type.name, + children: [] + }; + + if (isLeafNode(node)) { + nodeRepresentation.content = templateString.slice(node.from, node.to); + } + + stack.push(nodeRepresentation); + }, + leave: (node, pos, type) => { + const result = stack.pop(); + const parent = stack[stack.length - 1]; + result.parent = parent; + parent.children.push(result); + } + }); + + return stack[0].children[0]; + } + + /** + * @typedef {object} EvaluationOptions + * @property {boolean} [debug=false] - whether to enable debug mode, which displays errors inline instead of throwing them + * @property {function} [buildDebugString=(e) => `{{ ${e.message.toLowerCase()} }}`] - function that takes an error and returns the string to display in debug mode + * @property {boolean} [strict=false] - whether to expect strict data types out of our FEEL expression, e.g. boolean for conditionals + */ + + /** + * @param {string} templateString - the template string to evaluate + * @param {object} [context={}] - the context object to evaluate the template string against + * @param {EvaluationOptions} [options={}] - options to configure the evaluation + * @return {string} the evaluated template string + */ + const evaluate = (templateString, context = {}, options = {}) => { + + const { + debug = false, + buildDebugString = (e) => `{{ ${e.message.toLowerCase()} }}`, + strict = false + } = options; + + const parseTree = parser.parse(templateString); + + const simpleTreeRoot = buildSimpleTree(parseTree, templateString); + + const evaluateNode = buildNodeEvaluator(debug, buildDebugString, strict); + + return evaluateNode(simpleTreeRoot, enhanceContext(context, null)); + + }; + + const buildNodeEvaluator = (debug, buildDebugString, strict) => { + + const errorHandler = (error) => { + + if (debug) { + return buildDebugString(error); + } + + throw error; + }; + + const evaluateNodeValue = (node, context = {}) => { + + switch (node.name) { + + case 'SimpleTextBlock': + return node.content; + + case 'Insert': { + const feel = node.children[0].content; + + try { + return evaluate$1(feel, context); + } + catch { + return errorHandler(new Error(`FEEL expression ${feel} couldn't be evaluated`)); + } + } + + case 'EmptyInsert': + return ''; + + case 'Feel': + case 'FeelBlock': { + try { + return evaluate$1(node.content, context); + } + catch { + return errorHandler(new Error(`FEEL expression ${node.content} couldn't be evaluated`)); + } + } + + case 'Feelers': + return node.children.map(child => evaluateNode(child, context)).join(''); + + case 'ConditionalSpanner': { + const feel = node.children[0].content; + let shouldRender; + + try { + shouldRender = evaluate$1(feel, context); + } + catch { + return errorHandler(new Error(`FEEL expression ${feel} couldn't be evaluated`)); + } + + if (strict && typeof(shouldRender) !== 'boolean') { + return errorHandler(new Error(`FEEL expression ${feel} expected to evaluate to a boolean`)); + } + + if (shouldRender) { + const children = node.children.slice(1, node.children.length - 1); + const innerRender = children.map(child => evaluateNode(child, context)).join(''); + + const closeNode = node.children[node.children.length - 1]; + const shouldAddNewline = closeNode.name.endsWith('Nl') && !innerRender.endsWith('\n'); + + return innerRender + (shouldAddNewline ? '\n' : ''); + } + + return ''; + } + + case 'LoopSpanner': { + const feel = node.children[0].content; + let loopArray; + + try { + loopArray = evaluate$1(feel, context); + } + catch { + return errorHandler(new Error(`FEEL expression ${feel} couldn't be evaluated`)); + } + + if (!Array.isArray(loopArray)) { + + if (strict) { + return errorHandler(new Error(`FEEL expression ${feel} expected to evaluate to an array`)); + } + + // if not strict, we treat undefined/null as an empty array + else if (loopArray === undefined || loopArray === null) { + loopArray = []; + } + + // if not strict, we treat a single item as an array with one item + else { + loopArray = [ loopArray ]; + } + + } + + const childrenToLoop = node.children.slice(1, node.children.length - 1); + + const evaluateChildren = (arrayElement, parentContext) => { + const childContext = enhanceContext(arrayElement, parentContext); + return childrenToLoop.map(child => evaluateNode(child, childContext)).join(''); + }; + + const innerRender = loopArray.map(arrayElement => evaluateChildren(arrayElement, context)).join(''); + const closeNode = node.children[node.children.length - 1]; + const shouldAddNewline = closeNode.name.endsWith('Nl') && !innerRender.endsWith('\n'); + + return innerRender + (shouldAddNewline ? '\n' : ''); + }} + + }; + + const evaluateNode = (node, context = {}) => { + try { + return evaluateNodeValue(node, context); + } catch (error) { + return errorHandler(error); + } + }; + + return evaluateNode; + + }; + + const enhanceContext = (context, parentContext) => { + + if (typeof(context) === 'object') { + return { this: context, parent: parentContext, ...context, _this_: context, _parent_: parentContext }; + } + + return { this: context, parent: parentContext, _this_: context, _parent_: parentContext }; + }; - const buildNodeEvaluator = (debug, buildDebugString, strict) => { - - const errorHandler = (error) => { - - if (debug) { - return buildDebugString(error); - } - - throw error; - }; - - const evaluateNodeValue = (node, context = {}) => { - - switch (node.name) { - - case 'SimpleTextBlock': - return node.content; - - case 'Insert': { - const feel = node.children[0].content; - - try { - return evaluate$1(feel, context); - } - catch { - return errorHandler(new Error(`FEEL expression ${feel} couldn't be evaluated`)); - } - } - - case 'EmptyInsert': - return ''; - - case 'Feel': - case 'FeelBlock': { - try { - return evaluate$1(node.content, context); - } - catch { - return errorHandler(new Error(`FEEL expression ${node.content} couldn't be evaluated`)); - } - } - - case 'Feelers': - return node.children.map(child => evaluateNode(child, context)).join(''); - - case 'ConditionalSpanner': { - const feel = node.children[0].content; - let shouldRender; - - try { - shouldRender = evaluate$1(feel, context); - } - catch { - return errorHandler(new Error(`FEEL expression ${feel} couldn't be evaluated`)); - } - - if (strict && typeof(shouldRender) !== 'boolean') { - return errorHandler(new Error(`FEEL expression ${feel} expected to evaluate to a boolean`)); - } - - if (shouldRender) { - const children = node.children.slice(1, node.children.length - 1); - const innerRender = children.map(child => evaluateNode(child, context)).join(''); - - const closeNode = node.children[node.children.length - 1]; - const shouldAddNewline = closeNode.name.endsWith('Nl') && !innerRender.endsWith('\n'); - - return innerRender + (shouldAddNewline ? '\n' : ''); - } - - return ''; - } - - case 'LoopSpanner': { - const feel = node.children[0].content; - let loopArray; - - try { - loopArray = evaluate$1(feel, context); - } - catch { - return errorHandler(new Error(`FEEL expression ${feel} couldn't be evaluated`)); - } - - if (!Array.isArray(loopArray)) { - - if (strict) { - return errorHandler(new Error(`FEEL expression ${feel} expected to evaluate to an array`)); - } - - // if not strict, we treat undefined/null as an empty array - else if (loopArray === undefined || loopArray === null) { - loopArray = []; - } - - // if not strict, we treat a single item as an array with one item - else { - loopArray = [ loopArray ]; - } - - } - - const childrenToLoop = node.children.slice(1, node.children.length - 1); - - const evaluateChildren = (arrayElement, parentContext) => { - const childContext = enhanceContext(arrayElement, parentContext); - return childrenToLoop.map(child => evaluateNode(child, childContext)).join(''); - }; - - const innerRender = loopArray.map(arrayElement => evaluateChildren(arrayElement, context)).join(''); - const closeNode = node.children[node.children.length - 1]; - const shouldAddNewline = closeNode.name.endsWith('Nl') && !innerRender.endsWith('\n'); - - return innerRender + (shouldAddNewline ? '\n' : ''); - }} - - }; - - const evaluateNode = (node, context = {}) => { - try { - return evaluateNodeValue(node, context); - } catch (error) { - return errorHandler(error); - } - }; - - return evaluateNode; - - }; - - const enhanceContext = (context, parentContext) => { - - if (typeof(context) === 'object') { - return { this: context, parent: parentContext, ...context, _this_: context, _parent_: parentContext }; - } - - return { this: context, parent: parentContext, _this_: context, _parent_: parentContext }; - - }; - - /** - * Create warnings for empty inserts in the given tree. - * - * @param {Tree} syntaxTree - * @returns {LintMessage[]} array of syntax errors - */ - function lintEmptyInserts(syntaxTree) { - - const lintMessages = []; - - syntaxTree.iterate({ - enter: node => { - if (node.type.name === 'EmptyInsert') { - lintMessages.push( - { - from: node.from, - to: node.to, - severity: 'warning', - message: 'this insert is empty and will be ignored', - type: 'emptyInsert' - } - ); - } - } - }); - - return lintMessages; - } - - /** - * Generates lint messages for the given syntax tree. - * - * @param {Tree} syntaxTree - * @returns {LintMessage[]} array of all lint messages - */ - function lintAll(syntaxTree) { - - const lintMessages = [ - - ...lintEmptyInserts(syntaxTree) - ]; - - return lintMessages; - } - - - /** - * CodeMirror extension that provides linting for FEEL expressions. - * - * @param {EditorView} editorView - * @returns {Source} CodeMirror linting source - */ - function cmFeelersLinter() { - const lintFeel = cmFeelLinter(); - return editorView => { - - const feelMessages = lintFeel(editorView); - - // don't lint if the Editor is empty - if (editorView.state.doc.length === 0) { - return []; - } - - const tree = syntaxTree(editorView.state); - - const feelersMessages = lintAll(tree); - - return [ - ...feelMessages, - ...feelersMessages.map(message => ({ - ...message, - source: 'feelers linter' - })) - ]; - }; + /** + * Create warnings for empty inserts in the given tree. + * + * @param {Tree} syntaxTree + * @returns {LintMessage[]} array of syntax errors + */ + function lintEmptyInserts(syntaxTree) { + + const lintMessages = []; + + syntaxTree.iterate({ + enter: node => { + if (node.type.name === 'EmptyInsert') { + lintMessages.push( + { + from: node.from, + to: node.to, + severity: 'warning', + message: 'this insert is empty and will be ignored', + type: 'emptyInsert' + } + ); + } + } + }); + + return lintMessages; + } + + /** + * Generates lint messages for the given syntax tree. + * + * @param {Tree} syntaxTree + * @returns {LintMessage[]} array of all lint messages + */ + function lintAll(syntaxTree) { + + const lintMessages = [ + + ...lintEmptyInserts(syntaxTree) + ]; + + return lintMessages; + } + + + /** + * CodeMirror extension that provides linting for FEEL expressions. + * + * @param {EditorView} editorView + * @returns {Source} CodeMirror linting source + */ + function cmFeelersLinter() { + const lintFeel = cmFeelLinter(); + return editorView => { + + const feelMessages = lintFeel(editorView); + + // don't lint if the Editor is empty + if (editorView.state.doc.length === 0) { + return []; + } + + const tree = syntaxTree(editorView.state); + + const feelersMessages = lintAll(tree); + + return [ + ...feelMessages, + ...feelersMessages.map(message => ({ + ...message, + source: 'feelers linter' + })) + ]; + }; } linter(cmFeelersLinter()); @@ -32893,7 +32893,7 @@ }; (function (module) { - (function(){ + (function(){ /** * Created by Tivie on 13-07-2015. */ @@ -33089,7 +33089,7 @@ } return ret; } - + /** * Created by Tivie on 06-01-2015. */ @@ -33455,7 +33455,7 @@ } return true; }; - + /** * showdownjs helper functions */ @@ -35040,7 +35040,7 @@ 'octocat': ':octocat:', 'showdown': 'S' }; - + /** * Created by Estevao on 31-05-2015. */ @@ -35642,7 +35642,7 @@ metadata.raw = raw; }; }; - + /** * Turn Markdown link shortcuts into XHTML tags. */ @@ -35740,7 +35740,7 @@ text = globals.converter._dispatch('anchors.after', text, options, globals); return text; }); - + // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-] var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi, @@ -35816,7 +35816,7 @@ return text; }); - + /** * These are all the transformations that form block-level * tags like paragraphs, headers, and list items. @@ -35848,7 +35848,7 @@ return text; }); - + showdown.subParser('blockQuotes', function (text, options, globals) { text = globals.converter._dispatch('blockQuotes.before', text, options, globals); @@ -35890,7 +35890,7 @@ text = globals.converter._dispatch('blockQuotes.after', text, options, globals); return text; }); - + /** * Process Markdown `
` blocks.
   	 */
@@ -35928,7 +35928,7 @@
   	  text = globals.converter._dispatch('codeBlocks.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 *
   	 *   *  Backtick quotes are used for  spans.
@@ -35976,7 +35976,7 @@
   	  text = globals.converter._dispatch('codeSpans.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Create a full HTML document from the processed markdown
   	 */
@@ -36038,7 +36038,7 @@
   	  text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Convert all tabs to spaces
   	 */
@@ -36071,7 +36071,7 @@
   	  text = globals.converter._dispatch('detab.after', text, options, globals);
   	  return text;
   	});
-
+
   	showdown.subParser('ellipsis', function (text, options, globals) {
 
   	  if (!options.ellipsis) {
@@ -36086,7 +36086,7 @@
 
   	  return text;
   	});
-
+
   	/**
   	 * Turn emoji codes into emojis
   	 *
@@ -36113,7 +36113,7 @@
 
   	  return text;
   	});
-
+
   	/**
   	 * Smart processing for ampersands and angle brackets that need to be encoded.
   	 */
@@ -36136,7 +36136,7 @@
   	  text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Returns the string, with after processing the following backslash escape sequences.
   	 *
@@ -36157,7 +36157,7 @@
   	  text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Encode/escape certain characters inside Markdown code runs.
   	 * The point is that in code, these characters are literals,
@@ -36180,7 +36180,7 @@
   	  text = globals.converter._dispatch('encodeCode.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they
   	 * don't conflict with their use in Markdown for code, italics and strong.
@@ -36206,7 +36206,7 @@
   	  text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Handle github codeblocks prior to running HashHTML so that
   	 * HTML contained within the codeblock gets escaped properly
@@ -36252,7 +36252,7 @@
 
   	  return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals);
   	});
-
+
   	showdown.subParser('hashBlock', function (text, options, globals) {
   	  text = globals.converter._dispatch('hashBlock.before', text, options, globals);
   	  text = text.replace(/(^\n+|\n+$)/g, '');
@@ -36260,7 +36260,7 @@
   	  text = globals.converter._dispatch('hashBlock.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Hash and escape  elements that should not be parsed as markdown
   	 */
@@ -36278,7 +36278,7 @@
   	  text = globals.converter._dispatch('hashCodeTags.after', text, options, globals);
   	  return text;
   	});
-
+
   	showdown.subParser('hashElement', function (text, options, globals) {
 
   	  return function (wholeMatch, m1) {
@@ -36297,7 +36297,7 @@
   	    return blockText;
   	  };
   	});
-
+
   	showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
   	  text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals);
 
@@ -36395,7 +36395,7 @@
   	  text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Hash span elements that should not be parsed as markdown
   	 */
@@ -36458,7 +36458,7 @@
   	  text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Hash and escape 
 elements that should not be parsed as markdown
   	 */
@@ -36477,7 +36477,7 @@
   	  text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals);
   	  return text;
   	});
-
+
   	showdown.subParser('headers', function (text, options, globals) {
 
   	  text = globals.converter._dispatch('headers.before', text, options, globals);
@@ -36603,7 +36603,7 @@
   	  text = globals.converter._dispatch('headers.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Turn Markdown link shortcuts into XHTML  tags.
   	 */
@@ -36618,7 +36618,7 @@
   	  text = globals.converter._dispatch('horizontalRule.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Turn Markdown image shortcuts into  tags.
   	 */
@@ -36722,7 +36722,7 @@
   	  text = globals.converter._dispatch('images.after', text, options, globals);
   	  return text;
   	});
-
+
   	showdown.subParser('italicsAndBold', function (text, options, globals) {
 
   	  text = globals.converter._dispatch('italicsAndBold.before', text, options, globals);
@@ -36792,7 +36792,7 @@
   	  text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Form HTML ordered (numbered) and unordered (bulleted) lists.
   	 */
@@ -36995,7 +36995,7 @@
   	  text = globals.converter._dispatch('lists.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Parse metadata at the top of the document
   	 */
@@ -37044,7 +37044,7 @@
   	  text = globals.converter._dispatch('metadata.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 * Remove one level of line-leading tabs or spaces
   	 */
@@ -37061,7 +37061,7 @@
   	  text = globals.converter._dispatch('outdent.after', text, options, globals);
   	  return text;
   	});
-
+
   	/**
   	 *
   	 */
@@ -37131,7 +37131,7 @@
   	  text = text.replace(/\n+$/g, '');
   	  return globals.converter._dispatch('paragraphs.after', text, options, globals);
   	});
-
+
   	/**
   	 * Run extension
   	 */
@@ -37151,7 +37151,7 @@
 
   	  return text;
   	});
-
+
   	/**
   	 * These are all the transformations that occur *within* block-level
   	 * tags like paragraphs, headers, and list items.
@@ -37200,7 +37200,7 @@
   	  text = globals.converter._dispatch('spanGamut.after', text, options, globals);
   	  return text;
   	});
-
+
   	showdown.subParser('strikethrough', function (text, options, globals) {
 
   	  function parseInside (txt) {
@@ -37218,7 +37218,7 @@
 
   	  return text;
   	});
-
+
   	/**
   	 * Strips link definitions from text, stores the URLs and titles in
   	 * hash references.
@@ -37276,7 +37276,7 @@
 
   	  return text;
   	});
-
+
   	showdown.subParser('tables', function (text, options, globals) {
 
   	  if (!options.tables) {
@@ -37416,7 +37416,7 @@
 
   	  return text;
   	});
-
+
   	showdown.subParser('underline', function (text, options, globals) {
 
   	  if (!options.underline) {
@@ -37448,7 +37448,7 @@
 
   	  return text;
   	});
-
+
   	/**
   	 * Swap back in all the special characters we've hidden.
   	 */
@@ -37463,7 +37463,7 @@
   	  text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals);
   	  return text;
   	});
-
+
   	showdown.subParser('makeMarkdown.blockquote', function (node, globals) {
 
   	  var txt = '';
@@ -37485,19 +37485,19 @@
   	  txt = '> ' + txt.split('\n').join('\n> ');
   	  return txt;
   	});
-
+
   	showdown.subParser('makeMarkdown.codeBlock', function (node, globals) {
 
   	  var lang = node.getAttribute('language'),
   	      num  = node.getAttribute('precodenum');
   	  return '```' + lang + '\n' + globals.preList[num] + '\n```';
   	});
-
+
   	showdown.subParser('makeMarkdown.codeSpan', function (node) {
 
   	  return '`' + node.innerHTML + '`';
   	});
-
+
   	showdown.subParser('makeMarkdown.emphasis', function (node, globals) {
 
   	  var txt = '';
@@ -37512,7 +37512,7 @@
   	  }
   	  return txt;
   	});
-
+
   	showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) {
 
   	  var headerMark = new Array(headerLevel + 1).join('#'),
@@ -37529,12 +37529,12 @@
   	  }
   	  return txt;
   	});
-
+
   	showdown.subParser('makeMarkdown.hr', function () {
 
   	  return '---';
   	});
-
+
   	showdown.subParser('makeMarkdown.image', function (node) {
 
   	  var txt = '';
@@ -37552,7 +37552,7 @@
   	  }
   	  return txt;
   	});
-
+
   	showdown.subParser('makeMarkdown.links', function (node, globals) {
 
   	  var txt = '';
@@ -37572,7 +37572,7 @@
   	  }
   	  return txt;
   	});
-
+
   	showdown.subParser('makeMarkdown.list', function (node, globals, type) {
 
   	  var txt = '';
@@ -37605,7 +37605,7 @@
   	  txt += '\n\n';
   	  return txt.trim();
   	});
-
+
   	showdown.subParser('makeMarkdown.listItem', function (node, globals) {
 
   	  var listItemTxt = '';
@@ -37630,7 +37630,7 @@
 
   	  return listItemTxt;
   	});
-
+
 
 
   	showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) {
@@ -37750,7 +37750,7 @@
 
   	  return txt;
   	});
-
+
   	showdown.subParser('makeMarkdown.paragraph', function (node, globals) {
 
   	  var txt = '';
@@ -37767,13 +37767,13 @@
 
   	  return txt;
   	});
-
+
   	showdown.subParser('makeMarkdown.pre', function (node, globals) {
 
   	  var num  = node.getAttribute('prenum');
   	  return '
' + globals.preList[num] + '
'; }); - + showdown.subParser('makeMarkdown.strikethrough', function (node, globals) { var txt = ''; @@ -37788,7 +37788,7 @@ } return txt; }); - + showdown.subParser('makeMarkdown.strong', function (node, globals) { var txt = ''; @@ -37803,7 +37803,7 @@ } return txt; }); - + showdown.subParser('makeMarkdown.table', function (node, globals) { var txt = '', @@ -37873,7 +37873,7 @@ return txt.trim(); }); - + showdown.subParser('makeMarkdown.tableCell', function (node, globals) { var txt = ''; @@ -37888,7 +37888,7 @@ } return txt.trim(); }); - + showdown.subParser('makeMarkdown.txt', function (node) { var txt = node.nodeValue; @@ -37931,7 +37931,7 @@ return txt; }); - + var root = this; // AMD Loader @@ -37942,1034 +37942,1034 @@ } else { root.showdown = showdown; } - }).call(commonjsGlobal); + }).call(commonjsGlobal); } (showdown)); - /* - * big.js v6.2.1 - * A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic. - * Copyright (c) 2022 Michael Mclaughlin - * https://github.com/MikeMcl/big.js/LICENCE.md - */ - - - /************************************** EDITABLE DEFAULTS *****************************************/ - - - // The default values below must be integers within the stated ranges. - - /* - * The maximum number of decimal places (DP) of the results of operations involving division: - * div and sqrt, and pow with negative exponents. - */ - var DP = 20, // 0 to MAX_DP - - /* - * The rounding mode (RM) used when rounding to the above decimal places. - * - * 0 Towards zero (i.e. truncate, no rounding). (ROUND_DOWN) - * 1 To nearest neighbour. If equidistant, round up. (ROUND_HALF_UP) - * 2 To nearest neighbour. If equidistant, to even. (ROUND_HALF_EVEN) - * 3 Away from zero. (ROUND_UP) - */ - RM = 1, // 0, 1, 2 or 3 - - // The maximum value of DP and Big.DP. - MAX_DP = 1E6, // 0 to 1000000 - - // The maximum magnitude of the exponent argument to the pow method. - MAX_POWER = 1E6, // 1 to 1000000 - - /* - * The negative exponent (NE) at and beneath which toString returns exponential notation. - * (JavaScript numbers: -7) - * -1000000 is the minimum recommended exponent value of a Big. - */ - NE = -7, // 0 to -1000000 - - /* - * The positive exponent (PE) at and above which toString returns exponential notation. - * (JavaScript numbers: 21) - * 1000000 is the maximum recommended exponent value of a Big, but this limit is not enforced. - */ - PE = 21, // 0 to 1000000 - - /* - * When true, an error will be thrown if a primitive number is passed to the Big constructor, - * or if valueOf is called, or if toNumber is called on a Big which cannot be converted to a - * primitive number without a loss of precision. - */ - STRICT = false, // true or false - - - /**************************************************************************************************/ - - - // Error messages. - NAME = '[big.js] ', - INVALID = NAME + 'Invalid ', - INVALID_DP = INVALID + 'decimal places', - INVALID_RM = INVALID + 'rounding mode', - DIV_BY_ZERO = NAME + 'Division by zero', - - // The shared prototype object. - P$2 = {}, - UNDEFINED = void 0, - NUMERIC = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i; - - - /* - * Create and return a Big constructor. - */ - function _Big_() { - - /* - * The Big constructor and exported function. - * Create and return a new instance of a Big number object. - * - * n {number|string|Big} A numeric value. - */ - function Big(n) { - var x = this; - - // Enable constructor usage without new. - if (!(x instanceof Big)) return n === UNDEFINED ? _Big_() : new Big(n); - - // Duplicate. - if (n instanceof Big) { - x.s = n.s; - x.e = n.e; - x.c = n.c.slice(); - } else { - if (typeof n !== 'string') { - if (Big.strict === true && typeof n !== 'bigint') { - throw TypeError(INVALID + 'value'); - } - - // Minus zero? - n = n === 0 && 1 / n < 0 ? '-0' : String(n); - } - - parse(x, n); - } - - // Retain a reference to this Big constructor. - // Shadow Big.prototype.constructor which points to Object. - x.constructor = Big; - } - - Big.prototype = P$2; - Big.DP = DP; - Big.RM = RM; - Big.NE = NE; - Big.PE = PE; - Big.strict = STRICT; - Big.roundDown = 0; - Big.roundHalfUp = 1; - Big.roundHalfEven = 2; - Big.roundUp = 3; - - return Big; - } - - - /* - * Parse the number or string value passed to a Big constructor. - * - * x {Big} A Big number instance. - * n {number|string} A numeric value. - */ - function parse(x, n) { - var e, i, nl; - - if (!NUMERIC.test(n)) { - throw Error(INVALID + 'number'); - } - - // Determine sign. - x.s = n.charAt(0) == '-' ? (n = n.slice(1), -1) : 1; - - // Decimal point? - if ((e = n.indexOf('.')) > -1) n = n.replace('.', ''); - - // Exponential form? - if ((i = n.search(/e/i)) > 0) { - - // Determine exponent. - if (e < 0) e = i; - e += +n.slice(i + 1); - n = n.substring(0, i); - } else if (e < 0) { - - // Integer. - e = n.length; - } - - nl = n.length; - - // Determine leading zeros. - for (i = 0; i < nl && n.charAt(i) == '0';) ++i; - - if (i == nl) { - - // Zero. - x.c = [x.e = 0]; - } else { - - // Determine trailing zeros. - for (; nl > 0 && n.charAt(--nl) == '0';); - x.e = e - i - 1; - x.c = []; - - // Convert string to array of digits without leading/trailing zeros. - for (e = 0; i <= nl;) x.c[e++] = +n.charAt(i++); - } - - return x; - } - - - /* - * Round Big x to a maximum of sd significant digits using rounding mode rm. - * - * x {Big} The Big to round. - * sd {number} Significant digits: integer, 0 to MAX_DP inclusive. - * rm {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). - * [more] {boolean} Whether the result of division was truncated. - */ - function round(x, sd, rm, more) { - var xc = x.c; - - if (rm === UNDEFINED) rm = x.constructor.RM; - if (rm !== 0 && rm !== 1 && rm !== 2 && rm !== 3) { - throw Error(INVALID_RM); - } - - if (sd < 1) { - more = - rm === 3 && (more || !!xc[0]) || sd === 0 && ( - rm === 1 && xc[0] >= 5 || - rm === 2 && (xc[0] > 5 || xc[0] === 5 && (more || xc[1] !== UNDEFINED)) - ); - - xc.length = 1; - - if (more) { - - // 1, 0.1, 0.01, 0.001, 0.0001 etc. - x.e = x.e - sd + 1; - xc[0] = 1; - } else { - - // Zero. - xc[0] = x.e = 0; - } - } else if (sd < xc.length) { - - // xc[sd] is the digit after the digit that may be rounded up. - more = - rm === 1 && xc[sd] >= 5 || - rm === 2 && (xc[sd] > 5 || xc[sd] === 5 && - (more || xc[sd + 1] !== UNDEFINED || xc[sd - 1] & 1)) || - rm === 3 && (more || !!xc[0]); - - // Remove any digits after the required precision. - xc.length = sd; - - // Round up? - if (more) { - - // Rounding up may mean the previous digit has to be rounded up. - for (; ++xc[--sd] > 9;) { - xc[sd] = 0; - if (sd === 0) { - ++x.e; - xc.unshift(1); - break; - } - } - } - - // Remove trailing zeros. - for (sd = xc.length; !xc[--sd];) xc.pop(); - } - - return x; - } - - - /* - * Return a string representing the value of Big x in normal or exponential notation. - * Handles P.toExponential, P.toFixed, P.toJSON, P.toPrecision, P.toString and P.valueOf. - */ - function stringify(x, doExponential, isNonzero) { - var e = x.e, - s = x.c.join(''), - n = s.length; - - // Exponential notation? - if (doExponential) { - s = s.charAt(0) + (n > 1 ? '.' + s.slice(1) : '') + (e < 0 ? 'e' : 'e+') + e; - - // Normal notation. - } else if (e < 0) { - for (; ++e;) s = '0' + s; - s = '0.' + s; - } else if (e > 0) { - if (++e > n) { - for (e -= n; e--;) s += '0'; - } else if (e < n) { - s = s.slice(0, e) + '.' + s.slice(e); - } - } else if (n > 1) { - s = s.charAt(0) + '.' + s.slice(1); - } - - return x.s < 0 && isNonzero ? '-' + s : s; - } - - - // Prototype/instance methods - - - /* - * Return a new Big whose value is the absolute value of this Big. - */ - P$2.abs = function () { - var x = new this.constructor(this); - x.s = 1; - return x; - }; - - - /* - * Return 1 if the value of this Big is greater than the value of Big y, - * -1 if the value of this Big is less than the value of Big y, or - * 0 if they have the same value. - */ - P$2.cmp = function (y) { - var isneg, - x = this, - xc = x.c, - yc = (y = new x.constructor(y)).c, - i = x.s, - j = y.s, - k = x.e, - l = y.e; - - // Either zero? - if (!xc[0] || !yc[0]) return !xc[0] ? !yc[0] ? 0 : -j : i; - - // Signs differ? - if (i != j) return i; - - isneg = i < 0; - - // Compare exponents. - if (k != l) return k > l ^ isneg ? 1 : -1; - - j = (k = xc.length) < (l = yc.length) ? k : l; - - // Compare digit by digit. - for (i = -1; ++i < j;) { - if (xc[i] != yc[i]) return xc[i] > yc[i] ^ isneg ? 1 : -1; - } - - // Compare lengths. - return k == l ? 0 : k > l ^ isneg ? 1 : -1; - }; - - - /* - * Return a new Big whose value is the value of this Big divided by the value of Big y, rounded, - * if necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM. - */ - P$2.div = function (y) { - var x = this, - Big = x.constructor, - a = x.c, // dividend - b = (y = new Big(y)).c, // divisor - k = x.s == y.s ? 1 : -1, - dp = Big.DP; - - if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { - throw Error(INVALID_DP); - } - - // Divisor is zero? - if (!b[0]) { - throw Error(DIV_BY_ZERO); - } - - // Dividend is 0? Return +-0. - if (!a[0]) { - y.s = k; - y.c = [y.e = 0]; - return y; - } - - var bl, bt, n, cmp, ri, - bz = b.slice(), - ai = bl = b.length, - al = a.length, - r = a.slice(0, bl), // remainder - rl = r.length, - q = y, // quotient - qc = q.c = [], - qi = 0, - p = dp + (q.e = x.e - y.e) + 1; // precision of the result - - q.s = k; - k = p < 0 ? 0 : p; - - // Create version of divisor with leading zero. - bz.unshift(0); - - // Add zeros to make remainder as long as divisor. - for (; rl++ < bl;) r.push(0); - - do { - - // n is how many times the divisor goes into current remainder. - for (n = 0; n < 10; n++) { - - // Compare divisor and remainder. - if (bl != (rl = r.length)) { - cmp = bl > rl ? 1 : -1; - } else { - for (ri = -1, cmp = 0; ++ri < bl;) { - if (b[ri] != r[ri]) { - cmp = b[ri] > r[ri] ? 1 : -1; - break; - } - } - } - - // If divisor < remainder, subtract divisor from remainder. - if (cmp < 0) { - - // Remainder can't be more than 1 digit longer than divisor. - // Equalise lengths using divisor with extra leading zero? - for (bt = rl == bl ? b : bz; rl;) { - if (r[--rl] < bt[rl]) { - ri = rl; - for (; ri && !r[--ri];) r[ri] = 9; - --r[ri]; - r[rl] += 10; - } - r[rl] -= bt[rl]; - } - - for (; !r[0];) r.shift(); - } else { - break; - } - } - - // Add the digit n to the result array. - qc[qi++] = cmp ? n : ++n; - - // Update the remainder. - if (r[0] && cmp) r[rl] = a[ai] || 0; - else r = [a[ai]]; - - } while ((ai++ < al || r[0] !== UNDEFINED) && k--); - - // Leading zero? Do not remove if result is simply zero (qi == 1). - if (!qc[0] && qi != 1) { - - // There can't be more than one zero. - qc.shift(); - q.e--; - p--; - } - - // Round? - if (qi > p) round(q, p, Big.RM, r[0] !== UNDEFINED); - - return q; - }; - - - /* - * Return true if the value of this Big is equal to the value of Big y, otherwise return false. - */ - P$2.eq = function (y) { - return this.cmp(y) === 0; - }; - - - /* - * Return true if the value of this Big is greater than the value of Big y, otherwise return - * false. - */ - P$2.gt = function (y) { - return this.cmp(y) > 0; - }; - - - /* - * Return true if the value of this Big is greater than or equal to the value of Big y, otherwise - * return false. - */ - P$2.gte = function (y) { - return this.cmp(y) > -1; - }; - - - /* - * Return true if the value of this Big is less than the value of Big y, otherwise return false. - */ - P$2.lt = function (y) { - return this.cmp(y) < 0; - }; - - - /* - * Return true if the value of this Big is less than or equal to the value of Big y, otherwise - * return false. - */ - P$2.lte = function (y) { - return this.cmp(y) < 1; - }; - - - /* - * Return a new Big whose value is the value of this Big minus the value of Big y. - */ - P$2.minus = P$2.sub = function (y) { - var i, j, t, xlty, - x = this, - Big = x.constructor, - a = x.s, - b = (y = new Big(y)).s; - - // Signs differ? - if (a != b) { - y.s = -b; - return x.plus(y); - } - - var xc = x.c.slice(), - xe = x.e, - yc = y.c, - ye = y.e; - - // Either zero? - if (!xc[0] || !yc[0]) { - if (yc[0]) { - y.s = -b; - } else if (xc[0]) { - y = new Big(x); - } else { - y.s = 1; - } - return y; - } - - // Determine which is the bigger number. Prepend zeros to equalise exponents. - if (a = xe - ye) { - - if (xlty = a < 0) { - a = -a; - t = xc; - } else { - ye = xe; - t = yc; - } - - t.reverse(); - for (b = a; b--;) t.push(0); - t.reverse(); - } else { - - // Exponents equal. Check digit by digit. - j = ((xlty = xc.length < yc.length) ? xc : yc).length; - - for (a = b = 0; b < j; b++) { - if (xc[b] != yc[b]) { - xlty = xc[b] < yc[b]; - break; - } - } - } - - // x < y? Point xc to the array of the bigger number. - if (xlty) { - t = xc; - xc = yc; - yc = t; - y.s = -y.s; - } - - /* - * Append zeros to xc if shorter. No need to add zeros to yc if shorter as subtraction only - * needs to start at yc.length. - */ - if ((b = (j = yc.length) - (i = xc.length)) > 0) for (; b--;) xc[i++] = 0; - - // Subtract yc from xc. - for (b = i; j > a;) { - if (xc[--j] < yc[j]) { - for (i = j; i && !xc[--i];) xc[i] = 9; - --xc[i]; - xc[j] += 10; - } - - xc[j] -= yc[j]; - } - - // Remove trailing zeros. - for (; xc[--b] === 0;) xc.pop(); - - // Remove leading zeros and adjust exponent accordingly. - for (; xc[0] === 0;) { - xc.shift(); - --ye; - } - - if (!xc[0]) { - - // n - n = +0 - y.s = 1; - - // Result must be zero. - xc = [ye = 0]; - } - - y.c = xc; - y.e = ye; - - return y; - }; - - - /* - * Return a new Big whose value is the value of this Big modulo the value of Big y. - */ - P$2.mod = function (y) { - var ygtx, - x = this, - Big = x.constructor, - a = x.s, - b = (y = new Big(y)).s; - - if (!y.c[0]) { - throw Error(DIV_BY_ZERO); - } - - x.s = y.s = 1; - ygtx = y.cmp(x) == 1; - x.s = a; - y.s = b; - - if (ygtx) return new Big(x); - - a = Big.DP; - b = Big.RM; - Big.DP = Big.RM = 0; - x = x.div(y); - Big.DP = a; - Big.RM = b; - - return this.minus(x.times(y)); - }; - - - /* - * Return a new Big whose value is the value of this Big negated. - */ - P$2.neg = function () { - var x = new this.constructor(this); - x.s = -x.s; - return x; - }; - - - /* - * Return a new Big whose value is the value of this Big plus the value of Big y. - */ - P$2.plus = P$2.add = function (y) { - var e, k, t, - x = this, - Big = x.constructor; - - y = new Big(y); - - // Signs differ? - if (x.s != y.s) { - y.s = -y.s; - return x.minus(y); - } - - var xe = x.e, - xc = x.c, - ye = y.e, - yc = y.c; - - // Either zero? - if (!xc[0] || !yc[0]) { - if (!yc[0]) { - if (xc[0]) { - y = new Big(x); - } else { - y.s = x.s; - } - } - return y; - } - - xc = xc.slice(); - - // Prepend zeros to equalise exponents. - // Note: reverse faster than unshifts. - if (e = xe - ye) { - if (e > 0) { - ye = xe; - t = yc; - } else { - e = -e; - t = xc; - } - - t.reverse(); - for (; e--;) t.push(0); - t.reverse(); - } - - // Point xc to the longer array. - if (xc.length - yc.length < 0) { - t = yc; - yc = xc; - xc = t; - } - - e = yc.length; - - // Only start adding at yc.length - 1 as the further digits of xc can be left as they are. - for (k = 0; e; xc[e] %= 10) k = (xc[--e] = xc[e] + yc[e] + k) / 10 | 0; - - // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - - if (k) { - xc.unshift(k); - ++ye; - } - - // Remove trailing zeros. - for (e = xc.length; xc[--e] === 0;) xc.pop(); - - y.c = xc; - y.e = ye; - - return y; - }; - - - /* - * Return a Big whose value is the value of this Big raised to the power n. - * If n is negative, round to a maximum of Big.DP decimal places using rounding - * mode Big.RM. - * - * n {number} Integer, -MAX_POWER to MAX_POWER inclusive. - */ - P$2.pow = function (n) { - var x = this, - one = new x.constructor('1'), - y = one, - isneg = n < 0; - - if (n !== ~~n || n < -MAX_POWER || n > MAX_POWER) { - throw Error(INVALID + 'exponent'); - } - - if (isneg) n = -n; - - for (;;) { - if (n & 1) y = y.times(x); - n >>= 1; - if (!n) break; - x = x.times(x); - } - - return isneg ? one.div(y) : y; - }; - - - /* - * Return a new Big whose value is the value of this Big rounded to a maximum precision of sd - * significant digits using rounding mode rm, or Big.RM if rm is not specified. - * - * sd {number} Significant digits: integer, 1 to MAX_DP inclusive. - * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). - */ - P$2.prec = function (sd, rm) { - if (sd !== ~~sd || sd < 1 || sd > MAX_DP) { - throw Error(INVALID + 'precision'); - } - return round(new this.constructor(this), sd, rm); - }; - - - /* - * Return a new Big whose value is the value of this Big rounded to a maximum of dp decimal places - * using rounding mode rm, or Big.RM if rm is not specified. - * If dp is negative, round to an integer which is a multiple of 10**-dp. - * If dp is not specified, round to 0 decimal places. - * - * dp? {number} Integer, -MAX_DP to MAX_DP inclusive. - * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). - */ - P$2.round = function (dp, rm) { - if (dp === UNDEFINED) dp = 0; - else if (dp !== ~~dp || dp < -MAX_DP || dp > MAX_DP) { - throw Error(INVALID_DP); - } - return round(new this.constructor(this), dp + this.e + 1, rm); - }; - - - /* - * Return a new Big whose value is the square root of the value of this Big, rounded, if - * necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM. - */ - P$2.sqrt = function () { - var r, c, t, - x = this, - Big = x.constructor, - s = x.s, - e = x.e, - half = new Big('0.5'); - - // Zero? - if (!x.c[0]) return new Big(x); - - // Negative? - if (s < 0) { - throw Error(NAME + 'No square root'); - } - - // Estimate. - s = Math.sqrt(x + ''); - - // Math.sqrt underflow/overflow? - // Re-estimate: pass x coefficient to Math.sqrt as integer, then adjust the result exponent. - if (s === 0 || s === 1 / 0) { - c = x.c.join(''); - if (!(c.length + e & 1)) c += '0'; - s = Math.sqrt(c); - e = ((e + 1) / 2 | 0) - (e < 0 || e & 1); - r = new Big((s == 1 / 0 ? '5e' : (s = s.toExponential()).slice(0, s.indexOf('e') + 1)) + e); - } else { - r = new Big(s + ''); - } - - e = r.e + (Big.DP += 4); - - // Newton-Raphson iteration. - do { - t = r; - r = half.times(t.plus(x.div(t))); - } while (t.c.slice(0, e).join('') !== r.c.slice(0, e).join('')); - - return round(r, (Big.DP -= 4) + r.e + 1, Big.RM); - }; - - - /* - * Return a new Big whose value is the value of this Big times the value of Big y. - */ - P$2.times = P$2.mul = function (y) { - var c, - x = this, - Big = x.constructor, - xc = x.c, - yc = (y = new Big(y)).c, - a = xc.length, - b = yc.length, - i = x.e, - j = y.e; - - // Determine sign of result. - y.s = x.s == y.s ? 1 : -1; - - // Return signed 0 if either 0. - if (!xc[0] || !yc[0]) { - y.c = [y.e = 0]; - return y; - } - - // Initialise exponent of result as x.e + y.e. - y.e = i + j; - - // If array xc has fewer digits than yc, swap xc and yc, and lengths. - if (a < b) { - c = xc; - xc = yc; - yc = c; - j = a; - a = b; - b = j; - } - - // Initialise coefficient array of result with zeros. - for (c = new Array(j = a + b); j--;) c[j] = 0; - - // Multiply. - - // i is initially xc.length. - for (i = b; i--;) { - b = 0; - - // a is yc.length. - for (j = a + i; j > i;) { - - // Current sum of products at this digit position, plus carry. - b = c[j] + yc[i] * xc[j - i - 1] + b; - c[j--] = b % 10; - - // carry - b = b / 10 | 0; - } - - c[j] = b; - } - - // Increment result exponent if there is a final carry, otherwise remove leading zero. - if (b) ++y.e; - else c.shift(); - - // Remove trailing zeros. - for (i = c.length; !c[--i];) c.pop(); - y.c = c; - - return y; - }; - - - /* - * Return a string representing the value of this Big in exponential notation rounded to dp fixed - * decimal places using rounding mode rm, or Big.RM if rm is not specified. - * - * dp? {number} Decimal places: integer, 0 to MAX_DP inclusive. - * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). - */ - P$2.toExponential = function (dp, rm) { - var x = this, - n = x.c[0]; - - if (dp !== UNDEFINED) { - if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { - throw Error(INVALID_DP); - } - x = round(new x.constructor(x), ++dp, rm); - for (; x.c.length < dp;) x.c.push(0); - } - - return stringify(x, true, !!n); - }; - - - /* - * Return a string representing the value of this Big in normal notation rounded to dp fixed - * decimal places using rounding mode rm, or Big.RM if rm is not specified. - * - * dp? {number} Decimal places: integer, 0 to MAX_DP inclusive. - * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). - * - * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. - * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. - */ - P$2.toFixed = function (dp, rm) { - var x = this, - n = x.c[0]; - - if (dp !== UNDEFINED) { - if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { - throw Error(INVALID_DP); - } - x = round(new x.constructor(x), dp + x.e + 1, rm); - - // x.e may have changed if the value is rounded up. - for (dp = dp + x.e + 1; x.c.length < dp;) x.c.push(0); - } - - return stringify(x, false, !!n); - }; - - - /* - * Return a string representing the value of this Big. - * Return exponential notation if this Big has a positive exponent equal to or greater than - * Big.PE, or a negative exponent equal to or less than Big.NE. - * Omit the sign for negative zero. - */ - P$2[Symbol.for('nodejs.util.inspect.custom')] = P$2.toJSON = P$2.toString = function () { - var x = this, - Big = x.constructor; - return stringify(x, x.e <= Big.NE || x.e >= Big.PE, !!x.c[0]); - }; - - - /* - * Return the value of this Big as a primitve number. - */ - P$2.toNumber = function () { - var n = Number(stringify(this, true, true)); - if (this.constructor.strict === true && !this.eq(n.toString())) { - throw Error(NAME + 'Imprecise conversion'); - } - return n; - }; - - - /* - * Return a string representing the value of this Big rounded to sd significant digits using - * rounding mode rm, or Big.RM if rm is not specified. - * Use exponential notation if sd is less than the number of digits necessary to represent - * the integer part of the value in normal notation. - * - * sd {number} Significant digits: integer, 1 to MAX_DP inclusive. - * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). - */ - P$2.toPrecision = function (sd, rm) { - var x = this, - Big = x.constructor, - n = x.c[0]; - - if (sd !== UNDEFINED) { - if (sd !== ~~sd || sd < 1 || sd > MAX_DP) { - throw Error(INVALID + 'precision'); - } - x = round(new Big(x), sd, rm); - for (; x.c.length < sd;) x.c.push(0); - } - - return stringify(x, sd <= x.e || x.e <= Big.NE || x.e >= Big.PE, !!n); - }; - - - /* - * Return a string representing the value of this Big. - * Return exponential notation if this Big has a positive exponent equal to or greater than - * Big.PE, or a negative exponent equal to or less than Big.NE. - * Include the sign for negative zero. - */ - P$2.valueOf = function () { - var x = this, - Big = x.constructor; - if (Big.strict === true) { - throw Error(NAME + 'valueOf disallowed'); - } - return stringify(x, x.e <= Big.NE || x.e >= Big.PE, true); - }; - - - // Export - - + /* + * big.js v6.2.1 + * A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic. + * Copyright (c) 2022 Michael Mclaughlin + * https://github.com/MikeMcl/big.js/LICENCE.md + */ + + + /************************************** EDITABLE DEFAULTS *****************************************/ + + + // The default values below must be integers within the stated ranges. + + /* + * The maximum number of decimal places (DP) of the results of operations involving division: + * div and sqrt, and pow with negative exponents. + */ + var DP = 20, // 0 to MAX_DP + + /* + * The rounding mode (RM) used when rounding to the above decimal places. + * + * 0 Towards zero (i.e. truncate, no rounding). (ROUND_DOWN) + * 1 To nearest neighbour. If equidistant, round up. (ROUND_HALF_UP) + * 2 To nearest neighbour. If equidistant, to even. (ROUND_HALF_EVEN) + * 3 Away from zero. (ROUND_UP) + */ + RM = 1, // 0, 1, 2 or 3 + + // The maximum value of DP and Big.DP. + MAX_DP = 1E6, // 0 to 1000000 + + // The maximum magnitude of the exponent argument to the pow method. + MAX_POWER = 1E6, // 1 to 1000000 + + /* + * The negative exponent (NE) at and beneath which toString returns exponential notation. + * (JavaScript numbers: -7) + * -1000000 is the minimum recommended exponent value of a Big. + */ + NE = -7, // 0 to -1000000 + + /* + * The positive exponent (PE) at and above which toString returns exponential notation. + * (JavaScript numbers: 21) + * 1000000 is the maximum recommended exponent value of a Big, but this limit is not enforced. + */ + PE = 21, // 0 to 1000000 + + /* + * When true, an error will be thrown if a primitive number is passed to the Big constructor, + * or if valueOf is called, or if toNumber is called on a Big which cannot be converted to a + * primitive number without a loss of precision. + */ + STRICT = false, // true or false + + + /**************************************************************************************************/ + + + // Error messages. + NAME = '[big.js] ', + INVALID = NAME + 'Invalid ', + INVALID_DP = INVALID + 'decimal places', + INVALID_RM = INVALID + 'rounding mode', + DIV_BY_ZERO = NAME + 'Division by zero', + + // The shared prototype object. + P$2 = {}, + UNDEFINED = void 0, + NUMERIC = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i; + + + /* + * Create and return a Big constructor. + */ + function _Big_() { + + /* + * The Big constructor and exported function. + * Create and return a new instance of a Big number object. + * + * n {number|string|Big} A numeric value. + */ + function Big(n) { + var x = this; + + // Enable constructor usage without new. + if (!(x instanceof Big)) return n === UNDEFINED ? _Big_() : new Big(n); + + // Duplicate. + if (n instanceof Big) { + x.s = n.s; + x.e = n.e; + x.c = n.c.slice(); + } else { + if (typeof n !== 'string') { + if (Big.strict === true && typeof n !== 'bigint') { + throw TypeError(INVALID + 'value'); + } + + // Minus zero? + n = n === 0 && 1 / n < 0 ? '-0' : String(n); + } + + parse(x, n); + } + + // Retain a reference to this Big constructor. + // Shadow Big.prototype.constructor which points to Object. + x.constructor = Big; + } + + Big.prototype = P$2; + Big.DP = DP; + Big.RM = RM; + Big.NE = NE; + Big.PE = PE; + Big.strict = STRICT; + Big.roundDown = 0; + Big.roundHalfUp = 1; + Big.roundHalfEven = 2; + Big.roundUp = 3; + + return Big; + } + + + /* + * Parse the number or string value passed to a Big constructor. + * + * x {Big} A Big number instance. + * n {number|string} A numeric value. + */ + function parse(x, n) { + var e, i, nl; + + if (!NUMERIC.test(n)) { + throw Error(INVALID + 'number'); + } + + // Determine sign. + x.s = n.charAt(0) == '-' ? (n = n.slice(1), -1) : 1; + + // Decimal point? + if ((e = n.indexOf('.')) > -1) n = n.replace('.', ''); + + // Exponential form? + if ((i = n.search(/e/i)) > 0) { + + // Determine exponent. + if (e < 0) e = i; + e += +n.slice(i + 1); + n = n.substring(0, i); + } else if (e < 0) { + + // Integer. + e = n.length; + } + + nl = n.length; + + // Determine leading zeros. + for (i = 0; i < nl && n.charAt(i) == '0';) ++i; + + if (i == nl) { + + // Zero. + x.c = [x.e = 0]; + } else { + + // Determine trailing zeros. + for (; nl > 0 && n.charAt(--nl) == '0';); + x.e = e - i - 1; + x.c = []; + + // Convert string to array of digits without leading/trailing zeros. + for (e = 0; i <= nl;) x.c[e++] = +n.charAt(i++); + } + + return x; + } + + + /* + * Round Big x to a maximum of sd significant digits using rounding mode rm. + * + * x {Big} The Big to round. + * sd {number} Significant digits: integer, 0 to MAX_DP inclusive. + * rm {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). + * [more] {boolean} Whether the result of division was truncated. + */ + function round(x, sd, rm, more) { + var xc = x.c; + + if (rm === UNDEFINED) rm = x.constructor.RM; + if (rm !== 0 && rm !== 1 && rm !== 2 && rm !== 3) { + throw Error(INVALID_RM); + } + + if (sd < 1) { + more = + rm === 3 && (more || !!xc[0]) || sd === 0 && ( + rm === 1 && xc[0] >= 5 || + rm === 2 && (xc[0] > 5 || xc[0] === 5 && (more || xc[1] !== UNDEFINED)) + ); + + xc.length = 1; + + if (more) { + + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + x.e = x.e - sd + 1; + xc[0] = 1; + } else { + + // Zero. + xc[0] = x.e = 0; + } + } else if (sd < xc.length) { + + // xc[sd] is the digit after the digit that may be rounded up. + more = + rm === 1 && xc[sd] >= 5 || + rm === 2 && (xc[sd] > 5 || xc[sd] === 5 && + (more || xc[sd + 1] !== UNDEFINED || xc[sd - 1] & 1)) || + rm === 3 && (more || !!xc[0]); + + // Remove any digits after the required precision. + xc.length = sd; + + // Round up? + if (more) { + + // Rounding up may mean the previous digit has to be rounded up. + for (; ++xc[--sd] > 9;) { + xc[sd] = 0; + if (sd === 0) { + ++x.e; + xc.unshift(1); + break; + } + } + } + + // Remove trailing zeros. + for (sd = xc.length; !xc[--sd];) xc.pop(); + } + + return x; + } + + + /* + * Return a string representing the value of Big x in normal or exponential notation. + * Handles P.toExponential, P.toFixed, P.toJSON, P.toPrecision, P.toString and P.valueOf. + */ + function stringify(x, doExponential, isNonzero) { + var e = x.e, + s = x.c.join(''), + n = s.length; + + // Exponential notation? + if (doExponential) { + s = s.charAt(0) + (n > 1 ? '.' + s.slice(1) : '') + (e < 0 ? 'e' : 'e+') + e; + + // Normal notation. + } else if (e < 0) { + for (; ++e;) s = '0' + s; + s = '0.' + s; + } else if (e > 0) { + if (++e > n) { + for (e -= n; e--;) s += '0'; + } else if (e < n) { + s = s.slice(0, e) + '.' + s.slice(e); + } + } else if (n > 1) { + s = s.charAt(0) + '.' + s.slice(1); + } + + return x.s < 0 && isNonzero ? '-' + s : s; + } + + + // Prototype/instance methods + + + /* + * Return a new Big whose value is the absolute value of this Big. + */ + P$2.abs = function () { + var x = new this.constructor(this); + x.s = 1; + return x; + }; + + + /* + * Return 1 if the value of this Big is greater than the value of Big y, + * -1 if the value of this Big is less than the value of Big y, or + * 0 if they have the same value. + */ + P$2.cmp = function (y) { + var isneg, + x = this, + xc = x.c, + yc = (y = new x.constructor(y)).c, + i = x.s, + j = y.s, + k = x.e, + l = y.e; + + // Either zero? + if (!xc[0] || !yc[0]) return !xc[0] ? !yc[0] ? 0 : -j : i; + + // Signs differ? + if (i != j) return i; + + isneg = i < 0; + + // Compare exponents. + if (k != l) return k > l ^ isneg ? 1 : -1; + + j = (k = xc.length) < (l = yc.length) ? k : l; + + // Compare digit by digit. + for (i = -1; ++i < j;) { + if (xc[i] != yc[i]) return xc[i] > yc[i] ^ isneg ? 1 : -1; + } + + // Compare lengths. + return k == l ? 0 : k > l ^ isneg ? 1 : -1; + }; + + + /* + * Return a new Big whose value is the value of this Big divided by the value of Big y, rounded, + * if necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM. + */ + P$2.div = function (y) { + var x = this, + Big = x.constructor, + a = x.c, // dividend + b = (y = new Big(y)).c, // divisor + k = x.s == y.s ? 1 : -1, + dp = Big.DP; + + if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { + throw Error(INVALID_DP); + } + + // Divisor is zero? + if (!b[0]) { + throw Error(DIV_BY_ZERO); + } + + // Dividend is 0? Return +-0. + if (!a[0]) { + y.s = k; + y.c = [y.e = 0]; + return y; + } + + var bl, bt, n, cmp, ri, + bz = b.slice(), + ai = bl = b.length, + al = a.length, + r = a.slice(0, bl), // remainder + rl = r.length, + q = y, // quotient + qc = q.c = [], + qi = 0, + p = dp + (q.e = x.e - y.e) + 1; // precision of the result + + q.s = k; + k = p < 0 ? 0 : p; + + // Create version of divisor with leading zero. + bz.unshift(0); + + // Add zeros to make remainder as long as divisor. + for (; rl++ < bl;) r.push(0); + + do { + + // n is how many times the divisor goes into current remainder. + for (n = 0; n < 10; n++) { + + // Compare divisor and remainder. + if (bl != (rl = r.length)) { + cmp = bl > rl ? 1 : -1; + } else { + for (ri = -1, cmp = 0; ++ri < bl;) { + if (b[ri] != r[ri]) { + cmp = b[ri] > r[ri] ? 1 : -1; + break; + } + } + } + + // If divisor < remainder, subtract divisor from remainder. + if (cmp < 0) { + + // Remainder can't be more than 1 digit longer than divisor. + // Equalise lengths using divisor with extra leading zero? + for (bt = rl == bl ? b : bz; rl;) { + if (r[--rl] < bt[rl]) { + ri = rl; + for (; ri && !r[--ri];) r[ri] = 9; + --r[ri]; + r[rl] += 10; + } + r[rl] -= bt[rl]; + } + + for (; !r[0];) r.shift(); + } else { + break; + } + } + + // Add the digit n to the result array. + qc[qi++] = cmp ? n : ++n; + + // Update the remainder. + if (r[0] && cmp) r[rl] = a[ai] || 0; + else r = [a[ai]]; + + } while ((ai++ < al || r[0] !== UNDEFINED) && k--); + + // Leading zero? Do not remove if result is simply zero (qi == 1). + if (!qc[0] && qi != 1) { + + // There can't be more than one zero. + qc.shift(); + q.e--; + p--; + } + + // Round? + if (qi > p) round(q, p, Big.RM, r[0] !== UNDEFINED); + + return q; + }; + + + /* + * Return true if the value of this Big is equal to the value of Big y, otherwise return false. + */ + P$2.eq = function (y) { + return this.cmp(y) === 0; + }; + + + /* + * Return true if the value of this Big is greater than the value of Big y, otherwise return + * false. + */ + P$2.gt = function (y) { + return this.cmp(y) > 0; + }; + + + /* + * Return true if the value of this Big is greater than or equal to the value of Big y, otherwise + * return false. + */ + P$2.gte = function (y) { + return this.cmp(y) > -1; + }; + + + /* + * Return true if the value of this Big is less than the value of Big y, otherwise return false. + */ + P$2.lt = function (y) { + return this.cmp(y) < 0; + }; + + + /* + * Return true if the value of this Big is less than or equal to the value of Big y, otherwise + * return false. + */ + P$2.lte = function (y) { + return this.cmp(y) < 1; + }; + + + /* + * Return a new Big whose value is the value of this Big minus the value of Big y. + */ + P$2.minus = P$2.sub = function (y) { + var i, j, t, xlty, + x = this, + Big = x.constructor, + a = x.s, + b = (y = new Big(y)).s; + + // Signs differ? + if (a != b) { + y.s = -b; + return x.plus(y); + } + + var xc = x.c.slice(), + xe = x.e, + yc = y.c, + ye = y.e; + + // Either zero? + if (!xc[0] || !yc[0]) { + if (yc[0]) { + y.s = -b; + } else if (xc[0]) { + y = new Big(x); + } else { + y.s = 1; + } + return y; + } + + // Determine which is the bigger number. Prepend zeros to equalise exponents. + if (a = xe - ye) { + + if (xlty = a < 0) { + a = -a; + t = xc; + } else { + ye = xe; + t = yc; + } + + t.reverse(); + for (b = a; b--;) t.push(0); + t.reverse(); + } else { + + // Exponents equal. Check digit by digit. + j = ((xlty = xc.length < yc.length) ? xc : yc).length; + + for (a = b = 0; b < j; b++) { + if (xc[b] != yc[b]) { + xlty = xc[b] < yc[b]; + break; + } + } + } + + // x < y? Point xc to the array of the bigger number. + if (xlty) { + t = xc; + xc = yc; + yc = t; + y.s = -y.s; + } + + /* + * Append zeros to xc if shorter. No need to add zeros to yc if shorter as subtraction only + * needs to start at yc.length. + */ + if ((b = (j = yc.length) - (i = xc.length)) > 0) for (; b--;) xc[i++] = 0; + + // Subtract yc from xc. + for (b = i; j > a;) { + if (xc[--j] < yc[j]) { + for (i = j; i && !xc[--i];) xc[i] = 9; + --xc[i]; + xc[j] += 10; + } + + xc[j] -= yc[j]; + } + + // Remove trailing zeros. + for (; xc[--b] === 0;) xc.pop(); + + // Remove leading zeros and adjust exponent accordingly. + for (; xc[0] === 0;) { + xc.shift(); + --ye; + } + + if (!xc[0]) { + + // n - n = +0 + y.s = 1; + + // Result must be zero. + xc = [ye = 0]; + } + + y.c = xc; + y.e = ye; + + return y; + }; + + + /* + * Return a new Big whose value is the value of this Big modulo the value of Big y. + */ + P$2.mod = function (y) { + var ygtx, + x = this, + Big = x.constructor, + a = x.s, + b = (y = new Big(y)).s; + + if (!y.c[0]) { + throw Error(DIV_BY_ZERO); + } + + x.s = y.s = 1; + ygtx = y.cmp(x) == 1; + x.s = a; + y.s = b; + + if (ygtx) return new Big(x); + + a = Big.DP; + b = Big.RM; + Big.DP = Big.RM = 0; + x = x.div(y); + Big.DP = a; + Big.RM = b; + + return this.minus(x.times(y)); + }; + + + /* + * Return a new Big whose value is the value of this Big negated. + */ + P$2.neg = function () { + var x = new this.constructor(this); + x.s = -x.s; + return x; + }; + + + /* + * Return a new Big whose value is the value of this Big plus the value of Big y. + */ + P$2.plus = P$2.add = function (y) { + var e, k, t, + x = this, + Big = x.constructor; + + y = new Big(y); + + // Signs differ? + if (x.s != y.s) { + y.s = -y.s; + return x.minus(y); + } + + var xe = x.e, + xc = x.c, + ye = y.e, + yc = y.c; + + // Either zero? + if (!xc[0] || !yc[0]) { + if (!yc[0]) { + if (xc[0]) { + y = new Big(x); + } else { + y.s = x.s; + } + } + return y; + } + + xc = xc.slice(); + + // Prepend zeros to equalise exponents. + // Note: reverse faster than unshifts. + if (e = xe - ye) { + if (e > 0) { + ye = xe; + t = yc; + } else { + e = -e; + t = xc; + } + + t.reverse(); + for (; e--;) t.push(0); + t.reverse(); + } + + // Point xc to the longer array. + if (xc.length - yc.length < 0) { + t = yc; + yc = xc; + xc = t; + } + + e = yc.length; + + // Only start adding at yc.length - 1 as the further digits of xc can be left as they are. + for (k = 0; e; xc[e] %= 10) k = (xc[--e] = xc[e] + yc[e] + k) / 10 | 0; + + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 + + if (k) { + xc.unshift(k); + ++ye; + } + + // Remove trailing zeros. + for (e = xc.length; xc[--e] === 0;) xc.pop(); + + y.c = xc; + y.e = ye; + + return y; + }; + + + /* + * Return a Big whose value is the value of this Big raised to the power n. + * If n is negative, round to a maximum of Big.DP decimal places using rounding + * mode Big.RM. + * + * n {number} Integer, -MAX_POWER to MAX_POWER inclusive. + */ + P$2.pow = function (n) { + var x = this, + one = new x.constructor('1'), + y = one, + isneg = n < 0; + + if (n !== ~~n || n < -MAX_POWER || n > MAX_POWER) { + throw Error(INVALID + 'exponent'); + } + + if (isneg) n = -n; + + for (;;) { + if (n & 1) y = y.times(x); + n >>= 1; + if (!n) break; + x = x.times(x); + } + + return isneg ? one.div(y) : y; + }; + + + /* + * Return a new Big whose value is the value of this Big rounded to a maximum precision of sd + * significant digits using rounding mode rm, or Big.RM if rm is not specified. + * + * sd {number} Significant digits: integer, 1 to MAX_DP inclusive. + * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). + */ + P$2.prec = function (sd, rm) { + if (sd !== ~~sd || sd < 1 || sd > MAX_DP) { + throw Error(INVALID + 'precision'); + } + return round(new this.constructor(this), sd, rm); + }; + + + /* + * Return a new Big whose value is the value of this Big rounded to a maximum of dp decimal places + * using rounding mode rm, or Big.RM if rm is not specified. + * If dp is negative, round to an integer which is a multiple of 10**-dp. + * If dp is not specified, round to 0 decimal places. + * + * dp? {number} Integer, -MAX_DP to MAX_DP inclusive. + * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). + */ + P$2.round = function (dp, rm) { + if (dp === UNDEFINED) dp = 0; + else if (dp !== ~~dp || dp < -MAX_DP || dp > MAX_DP) { + throw Error(INVALID_DP); + } + return round(new this.constructor(this), dp + this.e + 1, rm); + }; + + + /* + * Return a new Big whose value is the square root of the value of this Big, rounded, if + * necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM. + */ + P$2.sqrt = function () { + var r, c, t, + x = this, + Big = x.constructor, + s = x.s, + e = x.e, + half = new Big('0.5'); + + // Zero? + if (!x.c[0]) return new Big(x); + + // Negative? + if (s < 0) { + throw Error(NAME + 'No square root'); + } + + // Estimate. + s = Math.sqrt(x + ''); + + // Math.sqrt underflow/overflow? + // Re-estimate: pass x coefficient to Math.sqrt as integer, then adjust the result exponent. + if (s === 0 || s === 1 / 0) { + c = x.c.join(''); + if (!(c.length + e & 1)) c += '0'; + s = Math.sqrt(c); + e = ((e + 1) / 2 | 0) - (e < 0 || e & 1); + r = new Big((s == 1 / 0 ? '5e' : (s = s.toExponential()).slice(0, s.indexOf('e') + 1)) + e); + } else { + r = new Big(s + ''); + } + + e = r.e + (Big.DP += 4); + + // Newton-Raphson iteration. + do { + t = r; + r = half.times(t.plus(x.div(t))); + } while (t.c.slice(0, e).join('') !== r.c.slice(0, e).join('')); + + return round(r, (Big.DP -= 4) + r.e + 1, Big.RM); + }; + + + /* + * Return a new Big whose value is the value of this Big times the value of Big y. + */ + P$2.times = P$2.mul = function (y) { + var c, + x = this, + Big = x.constructor, + xc = x.c, + yc = (y = new Big(y)).c, + a = xc.length, + b = yc.length, + i = x.e, + j = y.e; + + // Determine sign of result. + y.s = x.s == y.s ? 1 : -1; + + // Return signed 0 if either 0. + if (!xc[0] || !yc[0]) { + y.c = [y.e = 0]; + return y; + } + + // Initialise exponent of result as x.e + y.e. + y.e = i + j; + + // If array xc has fewer digits than yc, swap xc and yc, and lengths. + if (a < b) { + c = xc; + xc = yc; + yc = c; + j = a; + a = b; + b = j; + } + + // Initialise coefficient array of result with zeros. + for (c = new Array(j = a + b); j--;) c[j] = 0; + + // Multiply. + + // i is initially xc.length. + for (i = b; i--;) { + b = 0; + + // a is yc.length. + for (j = a + i; j > i;) { + + // Current sum of products at this digit position, plus carry. + b = c[j] + yc[i] * xc[j - i - 1] + b; + c[j--] = b % 10; + + // carry + b = b / 10 | 0; + } + + c[j] = b; + } + + // Increment result exponent if there is a final carry, otherwise remove leading zero. + if (b) ++y.e; + else c.shift(); + + // Remove trailing zeros. + for (i = c.length; !c[--i];) c.pop(); + y.c = c; + + return y; + }; + + + /* + * Return a string representing the value of this Big in exponential notation rounded to dp fixed + * decimal places using rounding mode rm, or Big.RM if rm is not specified. + * + * dp? {number} Decimal places: integer, 0 to MAX_DP inclusive. + * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). + */ + P$2.toExponential = function (dp, rm) { + var x = this, + n = x.c[0]; + + if (dp !== UNDEFINED) { + if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { + throw Error(INVALID_DP); + } + x = round(new x.constructor(x), ++dp, rm); + for (; x.c.length < dp;) x.c.push(0); + } + + return stringify(x, true, !!n); + }; + + + /* + * Return a string representing the value of this Big in normal notation rounded to dp fixed + * decimal places using rounding mode rm, or Big.RM if rm is not specified. + * + * dp? {number} Decimal places: integer, 0 to MAX_DP inclusive. + * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). + * + * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. + * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. + */ + P$2.toFixed = function (dp, rm) { + var x = this, + n = x.c[0]; + + if (dp !== UNDEFINED) { + if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { + throw Error(INVALID_DP); + } + x = round(new x.constructor(x), dp + x.e + 1, rm); + + // x.e may have changed if the value is rounded up. + for (dp = dp + x.e + 1; x.c.length < dp;) x.c.push(0); + } + + return stringify(x, false, !!n); + }; + + + /* + * Return a string representing the value of this Big. + * Return exponential notation if this Big has a positive exponent equal to or greater than + * Big.PE, or a negative exponent equal to or less than Big.NE. + * Omit the sign for negative zero. + */ + P$2[Symbol.for('nodejs.util.inspect.custom')] = P$2.toJSON = P$2.toString = function () { + var x = this, + Big = x.constructor; + return stringify(x, x.e <= Big.NE || x.e >= Big.PE, !!x.c[0]); + }; + + + /* + * Return the value of this Big as a primitve number. + */ + P$2.toNumber = function () { + var n = Number(stringify(this, true, true)); + if (this.constructor.strict === true && !this.eq(n.toString())) { + throw Error(NAME + 'Imprecise conversion'); + } + return n; + }; + + + /* + * Return a string representing the value of this Big rounded to sd significant digits using + * rounding mode rm, or Big.RM if rm is not specified. + * Use exponential notation if sd is less than the number of digits necessary to represent + * the integer part of the value in normal notation. + * + * sd {number} Significant digits: integer, 1 to MAX_DP inclusive. + * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). + */ + P$2.toPrecision = function (sd, rm) { + var x = this, + Big = x.constructor, + n = x.c[0]; + + if (sd !== UNDEFINED) { + if (sd !== ~~sd || sd < 1 || sd > MAX_DP) { + throw Error(INVALID + 'precision'); + } + x = round(new Big(x), sd, rm); + for (; x.c.length < sd;) x.c.push(0); + } + + return stringify(x, sd <= x.e || x.e <= Big.NE || x.e >= Big.PE, !!n); + }; + + + /* + * Return a string representing the value of this Big. + * Return exponential notation if this Big has a positive exponent equal to or greater than + * Big.PE, or a negative exponent equal to or less than Big.NE. + * Include the sign for negative zero. + */ + P$2.valueOf = function () { + var x = this, + Big = x.constructor; + if (Big.strict === true) { + throw Error(NAME + 'valueOf disallowed'); + } + return stringify(x, x.e <= Big.NE || x.e >= Big.PE, true); + }; + + + // Export + + var Big = _Big_(); var classnamesExports = {}; @@ -38979,9 +38979,9 @@ }; /*! - Copyright (c) 2018 Jed Watson. - Licensed under the MIT License (MIT), see - http://jedwatson.github.io/classnames + Copyright (c) 2018 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames */ (function (module) { @@ -39010,14 +39010,15 @@ } } } else if (argType === 'object') { - if (arg.toString === Object.prototype.toString) { - for (var key in arg) { - if (hasOwn.call(arg, key) && arg[key]) { - classes.push(key); - } - } - } else { + if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) { classes.push(arg.toString()); + continue; + } + + for (var key in arg) { + if (hasOwn.call(arg, key) && arg[key]) { + classes.push(key); + } } } } @@ -39036,13 +39037,13 @@ var classNames = classnamesExports; - var n$1,l$2,u$1,t$1,o$3,r$1,f$1,e$3={},c$1=[],s$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function a$2(n,l){for(var u in l)n[u]=l[u];return n}function h$1(n){var l=n.parentNode;l&&l.removeChild(n);}function v$1(l,u,i){var t,o,r,f={};for(r in u)"key"==r?t=u[r]:"ref"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n$1.call(arguments,2):i),"function"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return y$1(l,f,t,o,null)}function y$1(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u$1:r};return null!=l$2.vnode&&l$2.vnode(f),f}function p$2(){return {current:null}}function d$1(n){return n.children}function _$1(n,l){this.props=n,this.context=l;}function k$2(n,l){if(null==l)return n.__?k$2(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l0?y$1(_.type,_.props,_.key,null,_.__v):_)){if(_.__=u,_.__b=u.__b+1,null===(p=w[h])||p&&_.key==p.key&&_.type===p.type)w[h]=void 0;else for(v=0;v2&&(f.children=arguments.length>3?n$1.call(arguments,2):i),y$1(l.type,f,t||l.key,o||l.ref,null)}function D$1(n,l){var u={__c:l="__cC"+f$1++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(m$1);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n$1=c$1.slice,l$2={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l;}throw n}},u$1=0,_$1.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=a$2({},this.state),"function"==typeof n&&(n=n(a$2({},u),this.props)),n&&a$2(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),m$1(this));},_$1.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),m$1(this));},_$1.prototype.render=d$1,t$1=[],o$3="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,g$2.__r=0,f$1=0; + var n$1,l$2,u$1,t$1,o$3,r$1,f$1,e$3={},c$1=[],s$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function a$2(n,l){for(var u in l)n[u]=l[u];return n}function h(n){var l=n.parentNode;l&&l.removeChild(n);}function v$1(l,u,i){var t,o,r,f={};for(r in u)"key"==r?t=u[r]:"ref"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n$1.call(arguments,2):i),"function"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return y$1(l,f,t,o,null)}function y$1(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u$1:r};return null!=l$2.vnode&&l$2.vnode(f),f}function d$1(n){return n.children}function _(n,l){this.props=n,this.context=l;}function k$1(n,l){if(null==l)return n.__?k$1(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l0?y$1(_.type,_.props,_.key,null,_.__v):_)){if(_.__=u,_.__b=u.__b+1,null===(p=w[h])||p&&_.key==p.key&&_.type===p.type)w[h]=void 0;else for(v=0;v=i.__.length&&i.__.push({}),i.__[t]}function l$1(n){return o$1=1,p$1(w$1,n)}function p$1(n,r,o){var i=m(t++,2);return i.t=n,i.__c||(i.__=[o?o(r):w$1(void 0,r),function(n){var t=i.t(i.__[0],n);i.__[0]!==t&&(i.__=[t,i.__[1]],i.__c.setState({}));}],i.__c=u),i.__}function y(r,o){var i=m(t++,3);!l$2.__s&&k$1(i.__H,o)&&(i.__=r,i.__H=o,u.__H.__h.push(i));}function h(r,o){var i=m(t++,4);!l$2.__s&&k$1(i.__H,o)&&(i.__=r,i.__H=o,u.__h.push(i));}function s(n){return o$1=5,d(function(){return {current:n}},[])}function _(n,t,u){o$1=6,h(function(){"function"==typeof n?n(t()):n&&(n.current=t());},null==u?u:u.concat(n));}function d(n,u){var r=m(t++,7);return k$1(r.__H,u)&&(r.__=n(),r.__H=u,r.__h=n),r.__}function A$1(n,t){return o$1=8,d(function(){return n},t)}function F$1(n){var r=u.context[n.__c],o=m(t++,9);return o.c=n,r?(null==o.__&&(o.__=!0,r.sub(u)),r.props.value):n.__}function T$1(t,u){l$2.useDebugValue&&l$2.useDebugValue(u?u(t):t);}function x$1(){i$1.forEach(function(t){if(t.__P)try{t.__H.__h.forEach(g$1),t.__H.__h.forEach(j$1),t.__H.__h=[];}catch(u){t.__H.__h=[],l$2.__e(u,t.__v);}}),i$1=[];}l$2.__b=function(n){u=null,c&&c(n);},l$2.__r=function(n){f&&f(n),t=0;var r=(u=n.__c).__H;r&&(r.__h.forEach(g$1),r.__h.forEach(j$1),r.__h=[]);},l$2.diffed=function(t){e$1&&e$1(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i$1.push(o)&&r===l$2.requestAnimationFrame||((r=l$2.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b&&(t=requestAnimationFrame(u));})(x$1)),u=void 0;},l$2.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g$1),t.__h=t.__h.filter(function(n){return !n.__||j$1(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],l$2.__e(r,t.__v);}}),a$1&&a$1(t,u);},l$2.unmount=function(t){v&&v(t);var u=t.__c;if(u&&u.__H)try{u.__H.__.forEach(g$1);}catch(t){l$2.__e(t,u.__v);}};var b="function"==typeof requestAnimationFrame;function g$1(n){var t=u;"function"==typeof n.__c&&n.__c(),u=t;}function j$1(n){var t=u;n.__c=n.__(),u=t;}function k$1(n,t){return !n||n.length!==t.length||t.some(function(t,u){return t!==n[u]})}function w$1(n,t){return "function"==typeof t?t(n):t} + var t,u,r,o$1=0,i$1=[],c=l$2.__b,f=l$2.__r,e$1=l$2.diffed,a$1=l$2.__c,v=l$2.unmount;function m(t,r){l$2.__h&&l$2.__h(u,t,o$1||r),o$1=0;var i=u.__H||(u.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({}),i.__[t]}function l$1(n){return o$1=1,p$1(w$1,n)}function p$1(n,r,o){var i=m(t++,2);return i.t=n,i.__c||(i.__=[o?o(r):w$1(void 0,r),function(n){var t=i.t(i.__[0],n);i.__[0]!==t&&(i.__=[t,i.__[1]],i.__c.setState({}));}],i.__c=u),i.__}function y(r,o){var i=m(t++,3);!l$2.__s&&k(i.__H,o)&&(i.__=r,i.__H=o,u.__H.__h.push(i));}function s(n){return o$1=5,d(function(){return {current:n}},[])}function d(n,u){var r=m(t++,7);return k(r.__H,u)&&(r.__=n(),r.__H=u,r.__h=n),r.__}function A$1(n,t){return o$1=8,d(function(){return n},t)}function F(n){var r=u.context[n.__c],o=m(t++,9);return o.c=n,r?(null==o.__&&(o.__=!0,r.sub(u)),r.props.value):n.__}function x(){i$1.forEach(function(t){if(t.__P)try{t.__H.__h.forEach(g),t.__H.__h.forEach(j$1),t.__H.__h=[];}catch(u){t.__H.__h=[],l$2.__e(u,t.__v);}}),i$1=[];}l$2.__b=function(n){u=null,c&&c(n);},l$2.__r=function(n){f&&f(n),t=0;var r=(u=n.__c).__H;r&&(r.__h.forEach(g),r.__h.forEach(j$1),r.__h=[]);},l$2.diffed=function(t){e$1&&e$1(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i$1.push(o)&&r===l$2.requestAnimationFrame||((r=l$2.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b&&(t=requestAnimationFrame(u));})(x)),u=void 0;},l$2.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g),t.__h=t.__h.filter(function(n){return !n.__||j$1(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],l$2.__e(r,t.__v);}}),a$1&&a$1(t,u);},l$2.unmount=function(t){v&&v(t);var u=t.__c;if(u&&u.__H)try{u.__H.__.forEach(g);}catch(t){l$2.__e(t,u.__v);}};var b="function"==typeof requestAnimationFrame;function g(n){var t=u;"function"==typeof n.__c&&n.__c(),u=t;}function j$1(n){var t=u;n.__c=n.__(),u=t;}function k(n,t){return !n||n.length!==t.length||t.some(function(t,u){return t!==n[u]})}function w$1(n,t){return "function"==typeof t?t(n):t} - function S(n,t){for(var e in t)n[e]=t[e];return n}function C(n,t){for(var e in n)if("__source"!==e&&!(e in t))return !0;for(var r in t)if("__source"!==r&&n[r]!==t[r])return !0;return !1}function E(n){this.props=n;}function g(n,t){function e(n){var e=this.props.ref,r=e==n.ref;return !r&&e&&(e.call?e(null):e.current=null),t?!t(this.props,n)||!r:C(this.props,n)}function r(t){return this.shouldComponentUpdate=e,v$1(n,t)}return r.displayName="Memo("+(n.displayName||n.name)+")",r.prototype.isReactComponent=!0,r.__f=!0,r}(E.prototype=new _$1).isPureReactComponent=!0,E.prototype.shouldComponentUpdate=function(n,t){return C(this.props,n)||C(this.state,t)};var w=l$2.__b;l$2.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),w&&w(n);};var R="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.forward_ref")||3911;function x(n){function t(t,e){var r=S({},t);return delete r.ref,n(r,(e=t.ref||e)&&("object"!=typeof e||"current"in e)?e:null)}return t.$$typeof=R,t.render=t,t.prototype.isReactComponent=t.__f=!0,t.displayName="ForwardRef("+(n.displayName||n.name)+")",t}var N=function(n,t){return null==n?null:A$2(A$2(n).map(t))},k={map:N,forEach:N,count:function(n){return n?A$2(n).length:0},only:function(n){var t=A$2(n);if(1!==t.length)throw "Children.only";return t[0]},toArray:A$2},A=l$2.__e;l$2.__e=function(n,t,e){if(n.then)for(var r,u=t;u=u.__;)if((r=u.__c)&&r.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),r.__c(n,t);A(n,t,e);};var O=l$2.unmount;function L(){this.__u=0,this.t=null,this.__b=null;}function U(n){var t=n.__.__c;return t&&t.__e&&t.__e(n)}function F(n){var t,e,r;function u(u){if(t||(t=n()).then(function(n){e=n.default||n;},function(n){r=n;}),r)throw r;if(!e)throw t;return v$1(e,u)}return u.displayName="Lazy",u.__f=!0,u}function M(){this.u=null,this.o=null;}l$2.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),O&&O(n);},(L.prototype=new _$1).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=U(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l());};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__e){var n=r.state.__e;r.__v.__k[0]=function n(t,e,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)}),t.__c&&t.__c.__P===e&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(n,n.__c.__P,n.__c.__O);}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate();}},f=!0===t.__h;r.__u++||f||r.setState({__e:r.__b=r.__v.__k[0]}),n.then(i,i);},L.prototype.componentWillUnmount=function(){this.t=[];},L.prototype.render=function(n,t){if(this.__b){if(this.__v.__k){var e=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function n(t,e,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach(function(n){"function"==typeof n.__c&&n.__c();}),t.__c.__H=null),null!=(t=S({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=e),t.__c=null),t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)})),t}(this.__b,e,r.__O=r.__P);}this.__b=null;}var u=t.__e&&v$1(d$1,null,n.fallback);return u&&(u.__h=null),[v$1(d$1,null,t.__e?null:n.children),u]};var T=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&("t"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1]>>1,1),t.i.removeChild(n);}}),S$1(v$1(D,{context:t.context},n.__v),t.l)):t.l&&t.componentWillUnmount();}function W(n,t){return v$1(I,{__v:n,i:t})}(M.prototype=new _$1).__e=function(n){var t=this,e=U(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),T(t,n,r)):u();};e?e(o):o();}},M.prototype.render=function(n){this.u=null,this.o=new Map;var t=A$2(n.children);n.revealOrder&&"b"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},M.prototype.componentDidUpdate=M.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){T(n,e,t);});};var j="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,P=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,V=function(n){return ("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};function z(n,t,e){return null==t.__k&&(t.textContent=""),S$1(n,t),"function"==typeof e&&e(),n?n.__c:null}function B(n,t,e){return q$1(n,t),"function"==typeof e&&e(),n?n.__c:null}_$1.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(n){Object.defineProperty(_$1.prototype,n,{configurable:!0,get:function(){return this["UNSAFE_"+n]},set:function(t){Object.defineProperty(this,n,{configurable:!0,writable:!0,value:t});}});});var H=l$2.event;function Z(){}function Y(){return this.cancelBubble}function $(){return this.defaultPrevented}l$2.event=function(n){return H&&(n=H(n)),n.persist=Z,n.isPropagationStopped=Y,n.isDefaultPrevented=$,n.nativeEvent=n};var q,G={configurable:!0,get:function(){return this.class}},J=l$2.vnode;l$2.vnode=function(n){var t=n.type,e=n.props,r=e;if("string"==typeof t){for(var u in r={},e){var o=e[u];"value"===u&&"defaultValue"in e&&null==o||("defaultValue"===u&&"value"in e&&null==e.value?u="value":"download"===u&&!0===o?o="":/ondoubleclick/i.test(u)?u="ondblclick":/^onchange(textarea|input)/i.test(u+t)&&!V(e.type)?u="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(u)?u=u.toLowerCase():P.test(u)?u=u.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===o&&(o=void 0),r[u]=o);}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=A$2(e.children).forEach(function(n){n.props.selected=-1!=r.value.indexOf(n.props.value);})),"select"==t&&null!=r.defaultValue&&(r.value=A$2(e.children).forEach(function(n){n.props.selected=r.multiple?-1!=r.defaultValue.indexOf(n.props.value):r.defaultValue==n.props.value;})),n.props=r;}t&&e.class!=e.className&&(G.enumerable="className"in e,null!=e.className&&(r.class=e.className),Object.defineProperty(r,"className",G)),n.$$typeof=j,J&&J(n);};var K=l$2.__r;l$2.__r=function(n){K&&K(n),q=n.__c;};var Q={ReactCurrentDispatcher:{current:{readContext:function(n){return q.__n[n.__c].props.value}}}};function nn(n){return v$1.bind(null,n)}function tn(n){return !!n&&n.$$typeof===j}function en(n){return tn(n)?B$1.apply(null,arguments):n}function rn(n){return !!n.__k&&(S$1(null,n),!0)}function un(n){return n&&(n.base||1===n.nodeType&&n)||null}var on=function(n,t){return n(t)},ln=function(n,t){return n(t)};var React = {useState:l$1,useReducer:p$1,useEffect:y,useLayoutEffect:h,useRef:s,useImperativeHandle:_,useMemo:d,useCallback:A$1,useContext:F$1,useDebugValue:T$1,version:"17.0.2",Children:k,render:z,hydrate:B,unmountComponentAtNode:rn,createPortal:W,createElement:v$1,createContext:D$1,createFactory:nn,cloneElement:en,createRef:p$2,Fragment:d$1,isValidElement:tn,findDOMNode:un,Component:_$1,PureComponent:E,memo:g,forwardRef:x,flushSync:ln,unstable_batchedUpdates:on,StrictMode:d$1,Suspense:L,SuspenseList:M,lazy:F,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:Q}; + function S(n,t){for(var e in t)n[e]=t[e];return n}function C(n,t){for(var e in n)if("__source"!==e&&!(e in t))return !0;for(var r in t)if("__source"!==r&&n[r]!==t[r])return !0;return !1}function E(n){this.props=n;}(E.prototype=new _).isPureReactComponent=!0,E.prototype.shouldComponentUpdate=function(n,t){return C(this.props,n)||C(this.state,t)};var w=l$2.__b;l$2.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),w&&w(n);};var A=l$2.__e;l$2.__e=function(n,t,e){if(n.then)for(var r,u=t;u=u.__;)if((r=u.__c)&&r.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),r.__c(n,t);A(n,t,e);};var O=l$2.unmount;function L(){this.__u=0,this.t=null,this.__b=null;}function U(n){var t=n.__.__c;return t&&t.__e&&t.__e(n)}function M(){this.u=null,this.o=null;}l$2.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),O&&O(n);},(L.prototype=new _).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=U(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l());};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__e){var n=r.state.__e;r.__v.__k[0]=function n(t,e,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)}),t.__c&&t.__c.__P===e&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(n,n.__c.__P,n.__c.__O);}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate();}},f=!0===t.__h;r.__u++||f||r.setState({__e:r.__b=r.__v.__k[0]}),n.then(i,i);},L.prototype.componentWillUnmount=function(){this.t=[];},L.prototype.render=function(n,t){if(this.__b){if(this.__v.__k){var e=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function n(t,e,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach(function(n){"function"==typeof n.__c&&n.__c();}),t.__c.__H=null),null!=(t=S({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=e),t.__c=null),t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)})),t}(this.__b,e,r.__O=r.__P);}this.__b=null;}var u=t.__e&&v$1(d$1,null,n.fallback);return u&&(u.__h=null),[v$1(d$1,null,t.__e?null:n.children),u]};var T=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&("t"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1]>>1,1),t.i.removeChild(n);}}),S$1(v$1(D,{context:t.context},n.__v),t.l)):t.l&&t.componentWillUnmount();}function W(n,t){return v$1(I,{__v:n,i:t})}(M.prototype=new _).__e=function(n){var t=this,e=U(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),T(t,n,r)):u();};e?e(o):o();}},M.prototype.render=function(n){this.u=null,this.o=new Map;var t=A$2(n.children);n.revealOrder&&"b"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},M.prototype.componentDidUpdate=M.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){T(n,e,t);});};var j="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,P=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,V=function(n){return ("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};_.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(n){Object.defineProperty(_.prototype,n,{configurable:!0,get:function(){return this["UNSAFE_"+n]},set:function(t){Object.defineProperty(this,n,{configurable:!0,writable:!0,value:t});}});});var H=l$2.event;function Z(){}function Y(){return this.cancelBubble}function $(){return this.defaultPrevented}l$2.event=function(n){return H&&(n=H(n)),n.persist=Z,n.isPropagationStopped=Y,n.isDefaultPrevented=$,n.nativeEvent=n};var G={configurable:!0,get:function(){return this.class}},J=l$2.vnode;l$2.vnode=function(n){var t=n.type,e=n.props,r=e;if("string"==typeof t){for(var u in r={},e){var o=e[u];"value"===u&&"defaultValue"in e&&null==o||("defaultValue"===u&&"value"in e&&null==e.value?u="value":"download"===u&&!0===o?o="":/ondoubleclick/i.test(u)?u="ondblclick":/^onchange(textarea|input)/i.test(u+t)&&!V(e.type)?u="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(u)?u=u.toLowerCase():P.test(u)?u=u.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===o&&(o=void 0),r[u]=o);}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=A$2(e.children).forEach(function(n){n.props.selected=-1!=r.value.indexOf(n.props.value);})),"select"==t&&null!=r.defaultValue&&(r.value=A$2(e.children).forEach(function(n){n.props.selected=r.multiple?-1!=r.defaultValue.indexOf(n.props.value):r.defaultValue==n.props.value;})),n.props=r;}t&&e.class!=e.className&&(G.enumerable="className"in e,null!=e.className&&(r.class=e.className),Object.defineProperty(r,"className",G)),n.$$typeof=j,J&&J(n);};var K=l$2.__r;l$2.__r=function(n){K&&K(n),n.__c;}; var HOOKS = [ "onChange", @@ -41599,7 +41600,7 @@ window.flatpickr = flatpickr; } - var e,o={};function n(r,t,e){if(3===r.nodeType){var o="textContent"in r?r.textContent:r.nodeValue||"";if(!1!==n.options.trim){var a=0===t||t===e.length-1;if((!(o=o.match(/^[\s\n]+$/g)&&"all"!==n.options.trim?" ":o.replace(/(^[\s\n]+|[\s\n]+$)/g,"all"===n.options.trim||a?"":" "))||" "===o)&&e.length>1&&a)return null}return o}if(1!==r.nodeType)return null;var p=String(r.nodeName).toLowerCase();if("script"===p&&!n.options.allowScripts)return null;var l,s,u=n.h(p,function(r){var t=r&&r.length;if(!t)return null;for(var e={},o=0;o\n"+r+""):(i="xml",a='\n'+r+"");try{o=(new DOMParser).parseFromString(a,p);}catch(r){n=r;}if(o||"html"!==t||((o=e||(e=function(){if(document.implementation&&document.implementation.createHTMLDocument)return document.implementation.createHTMLDocument("");var r=document.createElement("iframe");return r.style.cssText="position:absolute; left:0; top:-999em; width:1px; height:1px; overflow:hidden;",r.setAttribute("sandbox","allow-forms"),document.body.appendChild(r),r.contentWindow.document}())).open(),o.write(a),o.close()),o){var l=o.getElementsByTagName(i)[0],s=l.firstChild;return r&&!s&&(l.error="Document parse failed."),s&&"parsererror"===String(s.nodeName).toLowerCase()&&(s.removeChild(s.firstChild),s.removeChild(s.lastChild),l.error=s.textContent||s.nodeValue||n||"Unknown error",l.removeChild(s)),l}}(r,t);if(u&&u.error)throw new Error(u.error);var c=u&&u.body||u;l.map=i||p;var m=c&&function(r,t,e,a){return n.visitor=t,n.h=e,n.options=a||o,n(r)}(c,l,a,s);return l.map=null,m&&m.props&&m.props.children||null}(c,u,C,this.map,g);}catch(r){f?f({error:r}):"undefined"!=typeof console&&console.error&&console.error("preact-markup: "+r);}if(!1===i)return s||null;var x=w.hasOwnProperty("className")?"className":"class",b=w[x];return b?b.splice?b.splice(0,0,"markup"):"string"==typeof b?w[x]+=" markup":"object"==typeof b&&(b.markup=!0):w[x]="markup",C("div",w,s||null)},i}(_$1)); + var e,o={};function n(r,t,e){if(3===r.nodeType){var o="textContent"in r?r.textContent:r.nodeValue||"";if(!1!==n.options.trim){var a=0===t||t===e.length-1;if((!(o=o.match(/^[\s\n]+$/g)&&"all"!==n.options.trim?" ":o.replace(/(^[\s\n]+|[\s\n]+$)/g,"all"===n.options.trim||a?"":" "))||" "===o)&&e.length>1&&a)return null}return o}if(1!==r.nodeType)return null;var p=String(r.nodeName).toLowerCase();if("script"===p&&!n.options.allowScripts)return null;var l,s,u=n.h(p,function(r){var t=r&&r.length;if(!t)return null;for(var e={},o=0;o\n"+r+""):(i="xml",a='\n'+r+"");try{o=(new DOMParser).parseFromString(a,p);}catch(r){n=r;}if(o||"html"!==t||((o=e||(e=function(){if(document.implementation&&document.implementation.createHTMLDocument)return document.implementation.createHTMLDocument("");var r=document.createElement("iframe");return r.style.cssText="position:absolute; left:0; top:-999em; width:1px; height:1px; overflow:hidden;",r.setAttribute("sandbox","allow-forms"),document.body.appendChild(r),r.contentWindow.document}())).open(),o.write(a),o.close()),o){var l=o.getElementsByTagName(i)[0],s=l.firstChild;return r&&!s&&(l.error="Document parse failed."),s&&"parsererror"===String(s.nodeName).toLowerCase()&&(s.removeChild(s.firstChild),s.removeChild(s.lastChild),l.error=s.textContent||s.nodeValue||n||"Unknown error",l.removeChild(s)),l}}(r,t);if(u&&u.error)throw new Error(u.error);var c=u&&u.body||u;l.map=i||p;var m=c&&function(r,t,e,a){return n.visitor=t,n.h=e,n.options=a||o,n(r)}(c,l,a,s);return l.map=null,m&&m.props&&m.props.children||null}(c,u,C,this.map,g);}catch(r){f?f({error:r}):"undefined"!=typeof console&&console.error&&console.error("preact-markup: "+r);}if(!1===i)return s||null;var x=w.hasOwnProperty("className")?"className":"class",b=w[x];return b?b.splice?b.splice(0,0,"markup"):"string"==typeof b?w[x]+=" markup":"object"==typeof b&&(b.markup=!0):w[x]="markup",C("div",w,s||null)},i}(_)); const CLASS_PATTERN = /^class[ {]/; @@ -42065,15 +42066,164 @@ return value; } + const getFlavouredFeelVariableNames = (feelString, feelFlavour, options = {}) => { + const { + depth = 0, + specialDepthAccessors = {} + } = options; + if (!['expression', 'unaryTest'].includes(feelFlavour)) return []; + const tree = feelFlavour === 'expression' ? parseExpressions$1(feelString) : parseUnaryTests$1(feelString); + const simpleExpressionTree = _buildSimpleFeelStructureTree(tree, feelString); + return function _unfoldVariables(node) { + if (node.name === 'PathExpression') { + if (Object.keys(specialDepthAccessors).length === 0) { + return depth === 0 ? [_getVariableNameAtPathIndex(node, 0)] : []; + } + + // if using special depth accessors, use a more complex extraction + return Array.from(_smartExtractVariableNames(node, depth, specialDepthAccessors)); + } + if (depth === 0 && node.name === 'VariableName') return [node.variableName]; + + // for any other kind of node, traverse its children and flatten the result + if (node.children) { + return node.children.reduce((acc, child) => { + return acc.concat(_unfoldVariables(child)); + }, []); + } + return []; + }(simpleExpressionTree); + }; + + /** + * Get the variable name at the specified index in a given path expression. + * + * @param {Object} root - The root node of the path expression tree. + * @param {number} index - The index of the variable name to retrieve. + * @returns {string|null} The variable name at the specified index or null if index is out of bounds. + */ + const _getVariableNameAtPathIndex = (root, index) => { + const accessors = _deconstructPathExpression(root); + return accessors[index] || null; + }; + + /** + * Extracts the variables which are required of the external context for a given path expression. + * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context. + * + * @param {Object} node - The root node of the path expression tree. + * @param {number} initialDepth - The depth at which the root node is located in the outer context. + * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context. + * @returns {Set} - A set containing the extracted variable names. + */ + const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => { + // depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression + // we track multiple of these to account for the fact that a path expression may be ambiguous due to special keywords + let accessorDepthInfos = [{ + previous: null, + current: initialDepth - 1 + }]; + const extractedVariables = new Set(); + const nodeAccessors = _deconstructPathExpression(node); + for (let i = 0; i < nodeAccessors.length; i++) { + const currentAccessor = nodeAccessors[i]; + if (currentAccessor in specialDepthAccessors) { + const depthOffsets = specialDepthAccessors[currentAccessor]; + + // if the current accessor is a special keyword, we need to expand the current depth info set + // this is done to account for the ambiguity of keywords like parent, which may be used to access + // the parent of the current node, or a child variable of the same name + accessorDepthInfos = depthOffsets.reduce((accumulator, offset) => { + return [...accumulator, ...accessorDepthInfos.map(depthInfo => ({ + previous: depthInfo.current, + current: depthInfo.current + offset + }))]; + }, []).filter(depthInfo => depthInfo.current >= -1); // discard all depth infos which are out of bounds + } else { + // if the current accessor is not a special keyword, we know it's simply accessing a child + // hence we are now one level deeper in the tree and simply increment + accessorDepthInfos = accessorDepthInfos.map(depthInfo => ({ + previous: depthInfo.current, + current: depthInfo.current + 1 + })); + } + + // finally, we check if for the current accessor, there is a scenario where: + // previous it was at depth -1 (i.e. the root context), and is now at depth 0 (i.e. a variable) + // these are the variables we need to request, so we add them to the set + if (accessorDepthInfos.some(depthInfo => depthInfo.previous === -1 && depthInfo.current === 0)) { + extractedVariables.add(currentAccessor); + } + } + + // we return a set to avoid duplicates + return new Set(extractedVariables); + }; + + /** + * Deconstructs a path expression tree into an array of components. + * + * @param {Object} root - The root node of the path expression tree. + * @returns {Array} An array of components in the path expression, in the correct order. + */ + const _deconstructPathExpression = root => { + let node = root; + let parts = []; + + // Traverse the tree and collect path components + while (node.name === 'PathExpression') { + parts.push(node.children[1].variableName); + node = node.children[0]; + } + + // Add the last component to the array + parts.push(node.variableName); + + // Reverse and return the array to get the correct order + return parts.reverse(); + }; + + /** + * Builds a simplified feel structure tree from the given parse tree and feel string. + * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }` + * + * @param {Object} parseTree - The parse tree generated by a parser. + * @param {string} feelString - The feel string used for parsing. + * @returns {Object} The simplified feel structure tree. + */ + const _buildSimpleFeelStructureTree = (parseTree, feelString) => { + const stack = [{ + children: [] + }]; + parseTree.iterate({ + enter: node => { + const nodeRepresentation = { + name: node.type.name, + children: [] + }; + if (node.type.name === 'VariableName') { + nodeRepresentation.variableName = feelString.slice(node.from, node.to); + } + stack.push(nodeRepresentation); + }, + leave: () => { + const result = stack.pop(); + const parent = stack[stack.length - 1]; + parent.children.push(result); + } + }); + return stack[0].children[0]; + }; + class FeelExpressionLanguage { constructor(eventBus) { this._eventBus = eventBus; } /** - * Determines if the given string is a FEEL expression. + * Determines if the given value is a FEEL expression. * - * @param {string} value + * @param {any} value * @returns {boolean} * */ @@ -42097,12 +42247,10 @@ if (!this.isExpression(expression)) { return []; } - if (type === 'unaryTest') { - return this._getUnaryVariableNames(expression); - } else if (type === 'expression') { - return this._getExpressionVariableNames(expression); + if (!['unaryTest', 'expression'].includes(type)) { + throw new Error('Unknown expression type: ' + type); } - throw new Error('Unknown expression type: ' + options.type); + return getFlavouredFeelVariableNames(expression, type); } /** @@ -42130,37 +42278,52 @@ return null; } } - _getExpressionVariableNames(expression) { - const tree = parseExpressions$1(expression); - const cursor = tree.cursor(); - const variables = new Set(); - do { - const node = cursor.node; - if (node.type.name === 'VariableName') { - variables.add(expression.slice(node.from, node.to)); - } - } while (cursor.next()); - return Array.from(variables); - } - _getUnaryVariableNames(unaryTest) { - const tree = parseUnaryTests$1(unaryTest); - const cursor = tree.cursor(); - const variables = new Set(); - do { - const node = cursor.node; - if (node.type.name === 'VariableName') { - variables.add(unaryTest.slice(node.from, node.to)); - } - } while (cursor.next()); - return Array.from(variables); - } } FeelExpressionLanguage.$inject = ['eventBus']; class FeelersTemplating { constructor() {} + + /** + * Determines if the given value is a feelers template. + * + * @param {any} value + * @returns {boolean} + * + */ isTemplate(value) { - return isString$3(value) && (value.startsWith('=') || /{{/.test(value)); + return isString$3(value) && (value.startsWith('=') || /{{.*?}}/.test(value)); + } + + /** + * Retrieve variable names from a given feelers template. + * + * @param {string} template + * + * @returns {string[]} + */ + getVariableNames(template) { + if (!this.isTemplate(template)) { + return []; + } + const expressions = this._extractExpressionsWithDepth(template); + + // defines special accessors, and the change(s) in depth they could imply (e.g. parent can be used to access the parent context (depth - 1) or a child variable named parent (depth + 1) + const specialDepthAccessors = { + parent: [-1, 1], + _parent_: [-1], + this: [0, 1], + _this_: [0] + }; + return expressions.reduce((variables, { + expression, + depth + }) => { + return variables.concat(getFlavouredFeelVariableNames(expression, 'expression', { + depth, + specialDepthAccessors + })); + }, []); } /** @@ -42187,6 +42350,50 @@ buildDebugString }); } + + /** + * @typedef {Object} ExpressionWithDepth + * @property {number} depth - The depth of the expression in the syntax tree. + * @property {string} expression - The extracted expression + */ + + /** + * Extracts all feel expressions in the template along with their depth in the syntax tree. + * The depth is incremented for child expressions of loops to account for context drilling. + * @name extractExpressionsWithDepth + * @param {string} template - A feelers template string. + * @returns {Array} An array of objects, each containing the depth and the extracted expression. + * + * @example + * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}."; + * const extractedExpressions = _extractExpressionsWithDepth(template); + */ + _extractExpressionsWithDepth(template) { + // build simplified feelers syntax tree + const parseTree = parser.parse(template); + const tree = buildSimpleTree(parseTree, template); + return function _traverse(n, depth = 0) { + if (['Feel', 'FeelBlock'].includes(n.name)) { + return [{ + depth, + expression: n.content + }]; + } + if (n.name === 'LoopSpanner') { + const loopExpression = n.children[0].content; + const childResults = n.children.slice(1).reduce((acc, child) => { + return acc.concat(_traverse(child, depth + 1)); + }, []); + return [{ + depth, + expression: loopExpression + }, ...childResults]; + } + return n.children.reduce((acc, child) => { + return acc.concat(_traverse(child, depth)); + }, []); + }(tree); + } } FeelersTemplating.$inject = []; @@ -42320,6 +42527,30 @@ var DEFAULT_PRIORITY = 1000; var slice = Array.prototype.slice; + /** + * @typedef { { + * stopPropagation(): void; + * preventDefault(): void; + * cancelBubble: boolean; + * defaultPrevented: boolean; + * returnValue: any; + * } } Event + */ + + /** + * @template E + * + * @typedef { (event: E & Event, ...any) => any } EventBusEventCallback + */ + + /** + * @typedef { { + * priority: number; + * next: EventBusListener | null; + * callback: EventBusEventCallback; + * } } EventBusListener + */ + /** * A general purpose event bus. * @@ -42404,6 +42635,9 @@ * ``` */ function EventBus() { + /** + * @type { Record } + */ this._listeners = {}; // cleanup on destroy on lowest priority to allow @@ -42423,10 +42657,12 @@ * * Returning anything but `undefined` from a listener will stop the listener propagation. * - * @param {string|Array} events - * @param {number} [priority=1000] the priority in which this listener is called, larger is higher - * @param {Function} callback - * @param {Object} [that] Pass context (`this`) to the callback + * @template T + * + * @param {string|string[]} events to subscribe to + * @param {number} [priority=1000] listen priority + * @param {EventBusEventCallback} callback + * @param {any} [that] callback context */ EventBus.prototype.on = function (events, priority, callback, that) { events = isArray$3(events) ? events : [events]; @@ -42458,14 +42694,16 @@ }; /** - * Register an event listener that is executed only once. + * Register an event listener that is called only once. + * + * @template T * - * @param {string} event the event name to register for - * @param {number} [priority=1000] the priority in which this listener is called, larger is higher - * @param {Function} callback the callback to execute - * @param {Object} [that] Pass context (`this`) to the callback + * @param {string|string[]} events to subscribe to + * @param {number} [priority=1000] the listen priority + * @param {EventBusEventCallback} callback + * @param {any} [that] callback context */ - EventBus.prototype.once = function (event, priority, callback, that) { + EventBus.prototype.once = function (events, priority, callback, that) { var self = this; if (isFunction(priority)) { that = callback; @@ -42478,7 +42716,7 @@ function wrappedCallback() { wrappedCallback.__isTomb = true; var result = callback.apply(that, arguments); - self.off(event, wrappedCallback); + self.off(events, wrappedCallback); return result; } @@ -42486,7 +42724,7 @@ // bound callbacks via {@link #off} using the original // callback wrappedCallback[FN_REF] = callback; - this.on(event, priority, wrappedCallback); + this.on(events, priority, wrappedCallback); }; /** @@ -42494,8 +42732,8 @@ * * If no callback is given, all listeners for a given event name are being removed. * - * @param {string|Array} events - * @param {Function} [callback] + * @param {string|string[]} events + * @param {EventBusEventCallback} [callback] */ EventBus.prototype.off = function (events, callback) { events = isArray$3(events) ? events : [events]; @@ -42506,11 +42744,11 @@ }; /** - * Create an EventBus event. + * Create an event recognized be the event bus. * - * @param {Object} data + * @param {Object} data Event data. * - * @return {Object} event, recognized by the eventBus + * @return {Event} An event that will be recognized by the event bus. */ EventBus.prototype.createEvent = function (data) { var event = new InternalEvent(); @@ -42519,10 +42757,11 @@ }; /** - * Fires a named event. + * Fires an event. * * @example * + * ```javascript * // fire event by name * events.fire('foo'); * @@ -42540,13 +42779,13 @@ * }); * * events.fire({ type: 'foo' }, 'I am bar!'); + * ``` * - * @param {string} [name] the optional event name - * @param {Object} [event] the event object - * @param {...Object} additional arguments to be passed to the callback functions + * @param {string} [type] event type + * @param {Object} [data] event or event data + * @param {...any} [args] additional arguments the callback will be called with. * - * @return {boolean} the events return value, if specified or false if the - * default action was prevented by listeners + * @return {any} The return value. Will be set to `false` if the default was prevented. */ EventBus.prototype.fire = function (type, data) { var event, firstListener, returnValue, args; @@ -42598,6 +42837,14 @@ } return returnValue; }; + + /** + * Handle an error by firing an event. + * + * @param {Error} error The error to be handled. + * + * @return {boolean} Whether the error was handled. + */ EventBus.prototype.handleError = function (error) { return this.fire('error', { error: error @@ -42606,6 +42853,14 @@ EventBus.prototype._destroy = function () { this._listeners = {}; }; + + /** + * @param {Event} event + * @param {any[]} args + * @param {EventBusListener} listener + * + * @return {any} + */ EventBus.prototype._invokeListeners = function (event, args, listener) { var returnValue; while (listener) { @@ -42618,6 +42873,14 @@ } return returnValue; }; + + /** + * @param {Event} event + * @param {any[]} args + * @param {EventBusListener} listener + * + * @return {any} + */ EventBus.prototype._invokeListener = function (event, args, listener) { var returnValue; if (listener.callback.__isTomb) { @@ -42646,7 +42909,7 @@ return returnValue; }; - /* + /** * Add new listener with a certain priority to the list * of listeners (for the given event). * @@ -42660,7 +42923,7 @@ * * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ] * * @param {string} event - * @param {Object} listener { priority, callback } + * @param {EventBusListener} listener */ EventBus.prototype._addListener = function (event, newListener) { var listener = this._getListeners(event), @@ -42691,9 +42954,20 @@ // add new listener to back previousListener.next = newListener; }; + + /** + * @param {string} name + * + * @return {EventBusListener} + */ EventBus.prototype._getListeners = function (name) { return this._listeners[name]; }; + + /** + * @param {string} name + * @param {EventBusListener} listener + */ EventBus.prototype._setListeners = function (name, listener) { this._listeners[name] = listener; }; @@ -42741,9 +43015,9 @@ * Invoke function. Be fast... * * @param {Function} fn - * @param {Array} args + * @param {any[]} args * - * @return {Any} + * @return {any} */ function invokeFunction(fn, args) { return fn.apply(null, args); @@ -42776,7 +43050,13 @@ const EMAIL_PATTERN = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; const PHONE_PATTERN = /(\+|00)(297|93|244|1264|358|355|376|971|54|374|1684|1268|61|43|994|257|32|229|226|880|359|973|1242|387|590|375|501|1441|591|55|1246|673|975|267|236|1|61|41|56|86|225|237|243|242|682|57|269|238|506|53|5999|61|1345|357|420|49|253|1767|45|1809|1829|1849|213|593|20|291|212|34|372|251|358|679|500|33|298|691|241|44|995|44|233|350|224|590|220|245|240|30|1473|299|502|594|1671|592|852|504|385|509|36|62|44|91|246|353|98|964|354|972|39|1876|44|962|81|76|77|254|996|855|686|1869|82|383|965|856|961|231|218|1758|423|94|266|370|352|371|853|590|212|377|373|261|960|52|692|389|223|356|95|382|976|1670|258|222|1664|596|230|265|60|262|264|687|227|672|234|505|683|31|47|977|674|64|968|92|507|64|51|63|680|675|48|1787|1939|850|351|595|970|689|974|262|40|7|250|966|249|221|65|500|4779|677|232|503|378|252|508|381|211|239|597|421|386|46|268|1721|248|963|1649|235|228|66|992|690|993|670|676|1868|216|90|688|886|255|256|380|598|1|998|3906698|379|1784|58|1284|1340|84|678|681|685|967|27|260|263)(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\d{4,20}$/; + const VALIDATE_FEEL_PROPERTIES = ['min', 'max', 'minLength', 'maxLength']; class Validator { + constructor(expressionLanguage, conditionChecker, form) { + this._expressionLanguage = expressionLanguage; + this._conditionChecker = conditionChecker; + this._form = form; + } validateField(field, value) { const { type, @@ -42809,34 +43089,76 @@ if (!validate) { return errors; } - if (validate.pattern && value && !new RegExp(validate.pattern).test(value)) { - errors = [...errors, `Field must match pattern ${validate.pattern}.`]; + const evaluatedValidation = evaluateFEELValues(validate, this._expressionLanguage, this._conditionChecker, this._form); + if (evaluatedValidation.pattern && value && !new RegExp(evaluatedValidation.pattern).test(value)) { + errors = [...errors, `Field must match pattern ${evaluatedValidation.pattern}.`]; } - if (validate.required && (isNil(value) || value === '')) { - errors = [...errors, 'Field is required.']; + if (evaluatedValidation.required) { + const isUncheckedCheckbox = type === 'checkbox' && value === false; + const isUnsetValue = isNil(value) || value === ''; + const isEmptyMultiselect = Array.isArray(value) && value.length === 0; + if (isUncheckedCheckbox || isUnsetValue || isEmptyMultiselect) { + errors = [...errors, 'Field is required.']; + } } - if ('min' in validate && (value || value === 0) && value < validate.min) { - errors = [...errors, `Field must have minimum value of ${validate.min}.`]; + if ('min' in evaluatedValidation && (value || value === 0) && value < evaluatedValidation.min) { + errors = [...errors, `Field must have minimum value of ${evaluatedValidation.min}.`]; } - if ('max' in validate && (value || value === 0) && value > validate.max) { - errors = [...errors, `Field must have maximum value of ${validate.max}.`]; + if ('max' in evaluatedValidation && (value || value === 0) && value > evaluatedValidation.max) { + errors = [...errors, `Field must have maximum value of ${evaluatedValidation.max}.`]; } - if ('minLength' in validate && value && value.trim().length < validate.minLength) { - errors = [...errors, `Field must have minimum length of ${validate.minLength}.`]; + if ('minLength' in evaluatedValidation && value && value.trim().length < evaluatedValidation.minLength) { + errors = [...errors, `Field must have minimum length of ${evaluatedValidation.minLength}.`]; } - if ('maxLength' in validate && value && value.trim().length > validate.maxLength) { - errors = [...errors, `Field must have maximum length of ${validate.maxLength}.`]; + if ('maxLength' in evaluatedValidation && value && value.trim().length > evaluatedValidation.maxLength) { + errors = [...errors, `Field must have maximum length of ${evaluatedValidation.maxLength}.`]; } - if ('validationType' in validate && value && validate.validationType === 'phone' && !PHONE_PATTERN.test(value)) { + if ('validationType' in evaluatedValidation && value && evaluatedValidation.validationType === 'phone' && !PHONE_PATTERN.test(value)) { errors = [...errors, 'Field must be a valid international phone number. (e.g. +4930664040900)']; } - if ('validationType' in validate && value && validate.validationType === 'email' && !EMAIL_PATTERN.test(value)) { + if ('validationType' in evaluatedValidation && value && evaluatedValidation.validationType === 'email' && !EMAIL_PATTERN.test(value)) { errors = [...errors, 'Field must be a valid email.']; } return errors; } } - Validator.$inject = []; + Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form']; + + // helpers ////////// + + /** + * Helper function to evaluate optional FEEL validation values. + */ + function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form) { + const evaluatedValidate = { + ...validate + }; + VALIDATE_FEEL_PROPERTIES.forEach(property => { + const path = property.split('.'); + const value = get(evaluatedValidate, path); + + // mirroring FEEL evaluation of our hooks + if (!expressionLanguage || !expressionLanguage.isExpression(value)) { + return value; + } + const { + initialData, + data + } = form._getState(); + const newData = conditionChecker ? conditionChecker.applyConditions(data, data) : data; + const filteredData = { + ...initialData, + ...newData + }; + const evaluatedValue = expressionLanguage.evaluate(value, filteredData); + + // replace validate property with evaluated value + if (evaluatedValue) { + set(evaluatedValidate, path, evaluatedValue); + } + }); + return evaluatedValidate; + } class FormFieldRegistry { constructor(eventBus) { @@ -43065,7 +43387,8 @@ return container; } - const EXPRESSION_PROPERTIES = ['alt', 'source', 'text']; + const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression']; + const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text']; function findErrors(errors, path) { return errors[pathStringify(path)]; } @@ -43105,7 +43428,7 @@ * * @return {string[]} */ - function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLanguage(null)) { + function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLanguage(null), templating = new FeelersTemplating()) { if (!schema.components) { return []; } @@ -43113,8 +43436,7 @@ const { key, valuesKey, - type, - conditional + type } = component; if (['button'].includes(type)) { return variables; @@ -43125,14 +43447,8 @@ if (valuesKey) { variables = [...variables, valuesKey]; } - if (conditional && conditional.hide) { - const conditionVariables = expressionLanguage.getVariableNames(conditional.hide, { - type: 'unaryTest' - }); - variables = [...variables, ...conditionVariables]; - } EXPRESSION_PROPERTIES.forEach(prop => { - const property = component[prop]; + const property = get(component, prop.split('.')); if (property && expressionLanguage.isExpression(property)) { const expressionVariables = expressionLanguage.getVariableNames(property, { type: 'expression' @@ -43140,6 +43456,13 @@ variables = [...variables, ...expressionVariables]; } }); + TEMPLATE_PROPERTIES.forEach(prop => { + const property = get(component, prop.split('.')); + if (property && !expressionLanguage.isExpression(property) && templating.isTemplate(property)) { + const templateVariables = templating.getVariableNames(property); + variables = [...variables, ...templateVariables]; + } + }); return variables; }, []); @@ -43262,16 +43585,18 @@ // if unavailable - get empty value from form field if (_path) { - const fieldImplementation = this._formFields.get(type); + const { + config: fieldConfig + } = this._formFields.get(type); let valueData = get(data, _path); - if (!isUndefined$1(valueData) && fieldImplementation.sanitizeValue) { - valueData = fieldImplementation.sanitizeValue({ + if (!isUndefined$1(valueData) && fieldConfig.sanitizeValue) { + valueData = fieldConfig.sanitizeValue({ formField, data, value: valueData }); } - const initializedFieldValue = !isUndefined$1(valueData) ? valueData : !isUndefined$1(defaultValue) ? defaultValue : fieldImplementation.emptyValue; + const initializedFieldValue = !isUndefined$1(valueData) ? valueData : !isUndefined$1(defaultValue) ? defaultValue : fieldConfig.emptyValue; initializedData = { ...initializedData, [_path[0]]: initializedFieldValue @@ -43289,14 +43614,16 @@ function formFieldClasses(type, { errors = [], - disabled = false + disabled = false, + readonly = false } = {}) { if (!type) { throw new Error('type required'); } return classNames('fjs-form-field', `fjs-form-field-${type}`, { 'fjs-has-errors': errors.length > 0, - 'fjs-disabled': disabled + 'fjs-disabled': disabled, + 'fjs-readonly': readonly }); } function gridColumnClasses(formField) { @@ -43336,14 +43663,16 @@ }) }); } - Button.create = (options = {}) => ({ - action: 'submit', - ...options - }); - Button.type = type$b; - Button.label = 'Button'; - Button.keyed = true; - Button.group = 'action'; + Button.config = { + type: type$b, + keyed: true, + label: 'Button', + group: 'action', + create: (options = {}) => ({ + action: 'submit', + ...options + }) + }; const FormRenderContext = D$1({ Empty: props => { @@ -43392,28 +43721,177 @@ }); var FormContext$1 = FormContext; + function useService(type, strict) { + const { + getService + } = F(FormContext$1); + return getService(type, strict); + } + + /** + * Returns the conditionally filtered data of a form reactively. + * Memoised to minimize re-renders + * + */ + function useFilteredFormData() { + const { + initialData, + data + } = useService('form')._getState(); + const conditionChecker = useService('conditionChecker', false); + return d(() => { + const newData = conditionChecker ? conditionChecker.applyConditions(data, data) : data; + return { + ...initialData, + ...newData + }; + }, [conditionChecker, data, initialData]); + } + + /** + * Evaluate if condition is met reactively based on the conditionChecker and form data. + * + * @param {string | undefined} condition + * + * @returns {boolean} true if condition is met or no condition or condition checker exists + */ + function useCondition(condition) { + const conditionChecker = useService('conditionChecker', false); + const filteredData = useFilteredFormData(); + return d(() => { + return conditionChecker ? conditionChecker.check(condition, filteredData) : null; + }, [conditionChecker, condition, filteredData]); + } + + /** + * Evaluate a string reactively based on the expressionLanguage and form data. + * If the string is not an expression, it is returned as is. + * Memoised to minimize re-renders. + * + * @param {string} value + * + */ + function useExpressionEvaluation(value) { + const formData = useFilteredFormData(); + const expressionLanguage = useService('expressionLanguage'); + return d(() => { + if (expressionLanguage && expressionLanguage.isExpression(value)) { + return expressionLanguage.evaluate(value, formData); + } + return value; + }, [expressionLanguage, formData, value]); + } + + function useKeyDownAction(targetKey, action, listenerElement = window) { + function downHandler({ + key + }) { + if (key === targetKey) { + action(); + } + } + y(() => { + listenerElement.addEventListener('keydown', downHandler); + return () => { + listenerElement.removeEventListener('keydown', downHandler); + }; + }); + } + + /** + * Retrieve readonly value of a form field, given it can be an + * expression optionally or configured globally. + * + * @typedef { import('../../types').FormProperties } FormProperties + * + * @param {any} formField + * @param {FormProperties} properties + * + * @returns {boolean} + */ + function useReadonly(formField, properties = {}) { + const expressionLanguage = useService('expressionLanguage'); + const conditionChecker = useService('conditionChecker', false); + const filteredData = useFilteredFormData(); + const { + readonly + } = formField; + if (properties.readOnly) { + return true; + } + if (expressionLanguage && expressionLanguage.isExpression(readonly)) { + return conditionChecker ? conditionChecker.check(readonly, filteredData) : false; + } + return readonly || false; + } + + /** + * Template a string reactively based on form data. If the string is not a template, it is returned as is. + * Memoised to minimize re-renders + * + * @param {string} value + * @param {Object} options + * @param {boolean} [options.debug = false] + * @param {boolean} [options.strict = false] + * @param {Function} [options.buildDebugString] + * + */ + function useTemplateEvaluation(value, options) { + const filteredData = useFilteredFormData(); + const templating = useService('templating'); + return d(() => { + if (templating && templating.isTemplate(value)) { + return templating.evaluate(value, filteredData, options); + } + return value; + }, [filteredData, templating, value, options]); + } + + /** + * Template a string reactively based on form data. If the string is not a template, it is returned as is. + * If the string contains multiple lines, only the first line is returned. + * Memoised to minimize re-renders + * + * @param {string} value + * @param {Object} [options] + * @param {boolean} [options.debug = false] + * @param {boolean} [options.strict = false] + * @param {Function} [options.buildDebugString] + * + */ + function useSingleLineTemplateEvaluation(value, options = {}) { + const evaluatedTemplate = useTemplateEvaluation(value, options); + return d(() => evaluatedTemplate && evaluatedTemplate.split('\n')[0], [evaluatedTemplate]); + } + function Description(props) { const { description } = props; - if (!description) { + const evaluatedDescription = useSingleLineTemplateEvaluation(description || '', { + debug: true + }); + if (!evaluatedDescription) { return null; } return e$2("div", { class: "fjs-form-field-description", - children: description + children: evaluatedDescription }); } function Errors(props) { const { - errors + errors, + id } = props; if (!errors.length) { return null; } return e$2("div", { class: "fjs-form-field-error", + "aria-live": "polite", + id: id, children: e$2("ul", { children: errors.map(error => { return e$2("li", { @@ -43431,12 +43909,15 @@ collapseOnEmpty = true, required = false } = props; + const evaluatedLabel = useSingleLineTemplateEvaluation(label || '', { + debug: true + }); return e$2("label", { for: id, class: classNames('fjs-form-field-label', { 'fjs-incollapsible-label': !collapseOnEmpty }, props['class']), - children: [props.children, label || '', required && e$2("span", { + children: [props.children, evaluatedLabel, required && e$2("span", { class: "fjs-asterix", children: "*" })] @@ -43449,13 +43930,18 @@ disabled, errors = [], field, + readonly, value = false } = props; const { description, id, - label + label, + validate = {} } = field; + const { + required + } = validate; const onChange = ({ target }) => { @@ -43466,44 +43952,51 @@ }; const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); + const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; return e$2("div", { class: classNames(formFieldClasses(type$a, { errors, - disabled + disabled, + readonly }), { 'fjs-checked': value }), children: [e$2(Label, { id: prefixId(id, formId), label: label, - required: false, + required: required, children: e$2("input", { checked: value, class: "fjs-input", disabled: disabled, + readOnly: readonly, id: prefixId(id, formId), type: "checkbox", - onChange: onChange + onChange: onChange, + "aria-describedby": errorMessageId }) }), e$2(Description, { description: description }), e$2(Errors, { - errors: errors + errors: errors, + id: errorMessageId })] }); } - Checkbox.create = (options = {}) => ({ - ...options - }); - Checkbox.type = type$a; - Checkbox.label = 'Checkbox'; - Checkbox.keyed = true; - Checkbox.emptyValue = false; - Checkbox.sanitizeValue = ({ - value - }) => value === true; - Checkbox.group = 'selection'; + Checkbox.config = { + type: type$a, + keyed: true, + label: 'Checkbox', + group: 'selection', + emptyValue: false, + sanitizeValue: ({ + value + }) => value === true, + create: (options = {}) => ({ + ...options + }) + }; // parses the options data from the provided form field and form data function getValuesData(formField, formData) { @@ -43551,13 +44044,6 @@ return value || value === 0 || value === false; } - function useService(type, strict) { - const { - getService - } = F$1(FormContext$1); - return getService(type, strict); - } - /** * @enum { String } */ @@ -43581,6 +44067,7 @@ */ function useValuesAsync (field) { const { + valuesExpression, valuesKey, values: staticValues } = field; @@ -43590,6 +44077,11 @@ state: LOAD_STATES.LOADING }); const initialData = useService('form')._getState().initialData; + const evaluatedValues = d(() => { + if (valuesExpression) { + return useExpressionEvaluation(valuesExpression); + } + }, [valuesExpression]); y(() => { let values = []; @@ -43599,11 +44091,14 @@ if (keyedValues && Array.isArray(keyedValues)) { values = keyedValues; } - } - // static values - else if (staticValues !== undefined) { + // static values + } else if (staticValues !== undefined) { values = Array.isArray(staticValues) ? staticValues : []; + + // expression + } else if (evaluatedValues && Array.isArray(evaluatedValues)) { + values = evaluatedValues; } else { setValuesGetter(buildErrorState('No values source defined in the form definition')); return; @@ -43839,13 +44334,18 @@ disabled, errors = [], field, + readonly, value = [] } = props; const { description, id, - label + label, + validate = {} } = field; + const { + required + } = validate; const toggleCheckbox = v => { let newValue = [...value]; if (!newValue.includes(v)) { @@ -43864,14 +44364,17 @@ } = useValuesAsync(field); const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); + const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; return e$2("div", { class: classNames(formFieldClasses(type$9, { errors, - disabled + disabled, + readonly })), children: [e$2(Label, { - label: label + label: label, + required: required }), loadState == LOAD_STATES.LOADED && options.map((v, index) => { return e$2(Label, { id: prefixId(`${id}-${index}`, formId), @@ -43884,131 +44387,44 @@ checked: value.includes(v.value), class: "fjs-input", disabled: disabled, + readOnly: readonly, id: prefixId(`${id}-${index}`, formId), type: "checkbox", - onClick: () => toggleCheckbox(v.value) + onClick: () => toggleCheckbox(v.value), + "aria-describedby": errorMessageId }) }, `${id}-${index}`); }), e$2(Description, { description: description }), e$2(Errors, { - errors: errors + errors: errors, + id: errorMessageId })] }); } - Checklist.create = (options = {}) => { - const defaults = {}; - - // provide default values if valuesKey isn't set - if (!options.valuesKey) { - defaults.values = [{ - label: 'Value', - value: 'value' - }]; - } - return { - ...defaults, - ...options - }; - }; - Checklist.type = type$9; - Checklist.label = 'Checklist'; - Checklist.keyed = true; - Checklist.emptyValue = []; - Checklist.sanitizeValue = sanitizeMultiSelectValue; - Checklist.group = 'selection'; - - /** - * Returns the conditionally filtered data of a form reactively. - * Memoised to minimize re-renders - * - */ - function useFilteredFormData() { - const { - initialData, - data - } = useService('form')._getState(); - const conditionChecker = useService('conditionChecker', false); - return d(() => { - const newData = conditionChecker ? conditionChecker.applyConditions(data, data) : data; + Checklist.config = { + type: type$9, + keyed: true, + label: 'Checklist', + group: 'selection', + emptyValue: [], + sanitizeValue: sanitizeMultiSelectValue, + create: (options = {}) => { + const defaults = {}; + + // provide default values if valuesKey isn't set + if (!options.valuesKey) { + defaults.values = [{ + label: 'Value', + value: 'value' + }]; + } return { - ...initialData, - ...newData + ...defaults, + ...options }; - }, [conditionChecker, data, initialData]); - } - - /** - * Evaluate if condition is met reactively based on the conditionChecker and form data. - * - * @param {string | undefined} condition - * - * @returns {boolean} true if condition is met or no condition or condition checker exists - */ - function useCondition(condition) { - const conditionChecker = useService('conditionChecker', false); - const filteredData = useFilteredFormData(); - return d(() => { - return conditionChecker ? conditionChecker.check(condition, filteredData) : null; - }, [conditionChecker, condition, filteredData]); - } - - /** - * Evaluate a string reactively based on the expressionLanguage and form data. - * If the string is not an expression, it is returned as is. - * Memoised to minimize re-renders. - * - * @param {string} value - * - */ - function useExpressionEvaluation(value) { - const formData = useFilteredFormData(); - const expressionLanguage = useService('expressionLanguage'); - return d(() => { - if (expressionLanguage && expressionLanguage.isExpression(value)) { - return expressionLanguage.evaluate(value, formData); - } - return value; - }, [expressionLanguage, formData, value]); - } - - function useKeyDownAction(targetKey, action, listenerElement = window) { - function downHandler({ - key - }) { - if (key === targetKey) { - action(); - } } - y(() => { - listenerElement.addEventListener('keydown', downHandler); - return () => { - listenerElement.removeEventListener('keydown', downHandler); - }; - }); - } - - /** - * Template a string reactively based on form data. If the string is not a template, it is returned as is. - * Memoised to minimize re-renders - * - * @param {string} value - * @param {Object} options - * @param {boolean} [options.debug = false] - * @param {boolean} [options.strict = false] - * @param {Function} [options.buildDebugString] - * - */ - function useTemplateEvaluation(value, options) { - const filteredData = useFilteredFormData(); - const templating = useService('templating'); - return d(() => { - if (templating.isTemplate(value)) { - return templating.evaluate(value, filteredData, options); - } - return value; - }, [filteredData, templating, value, options]); - } + }; const noop$1 = () => false; function FormField(props) { @@ -44016,9 +44432,6 @@ field, onChange } = props; - const { - _path - } = field; const formFields = useService('formFields'), form = useService('form'); const { @@ -44030,14 +44443,17 @@ Element, Empty, Column - } = F$1(FormRenderContext$1); + } = F(FormRenderContext$1); const FormFieldComponent = formFields.get(field.type); if (!FormFieldComponent) { throw new Error(`cannot render field <${field.type}>`); } - const value = get(data, _path); - const fieldErrors = findErrors(errors, _path); - const disabled = properties.readOnly || field.disabled || false; + const value = get(data, field._path); + const fieldErrors = findErrors(errors, field._path); + const readonly = useReadonly(field, properties); + + // add precedence: global readonly > form field disabled + const disabled = !properties.readOnly && (properties.disabled || field.disabled || false); const hidden = useCondition(field.conditional && field.conditional.hide || null); if (hidden) { return e$2(Empty, {}); @@ -44052,7 +44468,8 @@ ...props, disabled: disabled, errors: fieldErrors, - onChange: disabled ? noop$1 : onChange, + onChange: disabled || readonly ? noop$1 : onChange, + readonly: readonly, value: value }) }) @@ -44064,7 +44481,7 @@ Children, Empty, Row - } = F$1(FormRenderContext$1); + } = F(FormRenderContext$1); const { field } = props; @@ -44103,58 +44520,63 @@ }), components.length ? null : e$2(Empty, {})] }); } - Default.create = (options = {}) => ({ - components: [], - ...options - }); - Default.type = 'default'; - Default.keyed = false; - Default.label = null; - Default.group = null; + Default.config = { + type: 'default', + keyed: false, + label: null, + group: null, + create: (options = {}) => ({ + components: [], + ...options + }) + }; + var _path$g; function _extends$j() { _extends$j = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$j.apply(this, arguments); } - var CalendarIcon = (({ - styles = {}, - ...props - }) => /*#__PURE__*/React.createElement("svg", _extends$j({ - width: "14", - height: "15", - viewBox: "0 0 28 30", - fill: "none", - xmlns: "http://www.w3.org/2000/svg" - }, props), /*#__PURE__*/React.createElement("path", { - fillRule: "evenodd", - clipRule: "evenodd", - fill: "currentColor", - d: "M19 2H9V0H7v2H2a2 2 0 00-2 2v24a2 2 0 002 2h24a2 2 0 002-2V4a2 2 0 00-2-2h-5V0h-2v2zM7 7V4H2v5h24V4h-5v3h-2V4H9v3H7zm-5 4v17h24V11H2z" - }))); + var SvgCalendar = function SvgCalendar(props) { + return /*#__PURE__*/v$1("svg", _extends$j({ + xmlns: "http://www.w3.org/2000/svg", + width: 14, + height: 15, + fill: "none", + viewBox: "0 0 28 30" + }, props), _path$g || (_path$g = /*#__PURE__*/v$1("path", { + fill: "currentColor", + fillRule: "evenodd", + d: "M19 2H9V0H7v2H2a2 2 0 0 0-2 2v24a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2h-5V0h-2v2ZM7 7V4H2v5h24V4h-5v3h-2V4H9v3H7Zm-5 4v17h24V11H2Z", + clipRule: "evenodd" + }))); + }; + var CalendarIcon = SvgCalendar; function InputAdorner(props) { const { - pre = null, - post = null, + pre, + post, rootRef, inputRef, children, disabled, + readonly, hasErrors } = props; const onAdornmentClick = () => inputRef && inputRef.current && inputRef.current.focus(); return e$2("div", { class: classNames('fjs-input-group', { - 'fjs-disabled': disabled + 'fjs-disabled': disabled, + 'fjs-readonly': readonly }, { 'hasErrors': hasErrors }), ref: rootRef, - children: [pre !== null && e$2("span", { + children: [pre && e$2("span", { class: "fjs-input-adornment border-right border-radius-left", onClick: onAdornmentClick, children: [" ", isString$3(pre) ? e$2("span", { class: "fjs-input-adornment-text", children: pre }) : pre, " "] - }), children, post !== null && e$2("span", { + }), children, post && e$2("span", { class: "fjs-input-adornment border-left border-radius-right", onClick: onAdornmentClick, children: [" ", isString$3(post) ? e$2("span", { @@ -44175,6 +44597,7 @@ disabled, disallowPassedDates, date, + readonly, setDate } = props; const dateInputRef = s(); @@ -44254,9 +44677,9 @@ } }, [flatpickrInstance, isInputDirty]); const onInputFocus = A$1(e => { - if (!flatpickrInstance || focusScopeRef.current.contains(e.relatedTarget)) return; + if (!flatpickrInstance || focusScopeRef.current.contains(e.relatedTarget) || readonly) return; flatpickrInstance.open(); - }, [flatpickrInstance]); + }, [flatpickrInstance, readonly]); // simulate an enter press on blur to make sure the date value is submitted in all scenarios const onInputBlur = A$1(e => { @@ -44275,6 +44698,7 @@ }), e$2(InputAdorner, { pre: e$2(CalendarIcon, {}), disabled: disabled, + readonly: readonly, rootRef: focusScopeRef, inputRef: dateInputRef, children: e$2("div", { @@ -44286,41 +44710,44 @@ ref: dateInputRef, type: "text", id: fullId, - class: 'fjs-input', + class: "fjs-input", disabled: disabled, + readOnly: readonly, placeholder: "mm/dd/yyyy", autoComplete: "off", onFocus: onInputFocus, onKeyDown: onInputKeyDown, - onMouseDown: e => !flatpickrInstance.isOpen && flatpickrInstance.open(), + onMouseDown: () => !flatpickrInstance.isOpen && !readonly && flatpickrInstance.open(), onBlur: onInputBlur, - onInput: e => setIsInputDirty(true), - "data-input": true + onInput: () => setIsInputDirty(true), + "data-input": true, + "aria-describedby": props['aria-describedby'] }) }) })] }); } + var _path$f, _path2$3; function _extends$i() { _extends$i = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$i.apply(this, arguments); } - var ClockIcon = (({ - styles = {}, - ...props - }) => /*#__PURE__*/React.createElement("svg", _extends$i({ - width: "16", - height: "16", - viewBox: "0 0 28 29", - fill: "none", - xmlns: "http://www.w3.org/2000/svg" - }, props), /*#__PURE__*/React.createElement("path", { - fill: "currentColor", - d: "M13 14.41L18.59 20 20 18.59l-5-5.01V5h-2v9.41z" - }), /*#__PURE__*/React.createElement("path", { - fillRule: "evenodd", - clipRule: "evenodd", - fill: "currentColor", - d: "M6.222 25.64A14 14 0 1021.778 2.36 14 14 0 006.222 25.64zM7.333 4.023a12 12 0 1113.334 19.955A12 12 0 017.333 4.022z" - }))); + var SvgClock = function SvgClock(props) { + return /*#__PURE__*/v$1("svg", _extends$i({ + xmlns: "http://www.w3.org/2000/svg", + width: 16, + height: 16, + fill: "none", + viewBox: "0 0 28 29" + }, props), _path$f || (_path$f = /*#__PURE__*/v$1("path", { + fill: "currentColor", + d: "M13 14.41 18.59 20 20 18.59l-5-5.01V5h-2v9.41Z" + })), _path2$3 || (_path2$3 = /*#__PURE__*/v$1("path", { + fill: "currentColor", + fillRule: "evenodd", + d: "M6.222 25.64A14 14 0 1 0 21.778 2.36 14 14 0 0 0 6.222 25.64ZM7.333 4.023a12 12 0 1 1 13.334 19.955A12 12 0 0 1 7.333 4.022Z", + clipRule: "evenodd" + }))); + }; + var ClockIcon = SvgClock; const DEFAULT_LABEL_GETTER = value => value; const NOOP = () => {}; @@ -44425,14 +44852,22 @@ formId, required, disabled, + readonly, use24h = false, timeInterval, time, setTime } = props; + const safeTimeInterval = d(() => { + const allowedIntervals = [1, 5, 10, 15, 30, 60]; + if (allowedIntervals.includes(timeInterval)) { + return timeInterval; + } + return 15; + }, [timeInterval]); const timeInputRef = s(); const [dropdownIsOpen, setDropdownIsOpen] = l$1(false); - const useDropdown = d(() => timeInterval !== 1, [timeInterval]); + const useDropdown = d(() => safeTimeInterval !== 1, [safeTimeInterval]); const [rawValue, setRawValue] = l$1(''); // populates values from source @@ -44441,12 +44876,12 @@ setRawValue(''); return; } - const intervalAdjustedTime = time - time % timeInterval; + const intervalAdjustedTime = time - time % safeTimeInterval; setRawValue(formatTime(use24h, intervalAdjustedTime)); if (intervalAdjustedTime != time) { setTime(intervalAdjustedTime); } - }, [time, setTime, use24h, timeInterval]); + }, [time, setTime, use24h, safeTimeInterval]); const propagateRawToMinute = A$1(newRawValue => { const localRawValue = newRawValue || rawValue; @@ -44465,34 +44900,34 @@ } // Enforce the minutes to match the timeInterval - const correctedMinutes = minutes - minutes % timeInterval; + const correctedMinutes = minutes - minutes % safeTimeInterval; // Enforce the raw text to be formatted properly setRawValue(formatTime(use24h, correctedMinutes)); setTime(correctedMinutes); - }, [rawValue, timeInterval, use24h, setTime]); + }, [rawValue, safeTimeInterval, use24h, setTime]); const timeOptions = d(() => { const minutesInDay = 24 * 60; - const intervalCount = Math.floor(minutesInDay / timeInterval); - return [...Array(intervalCount).keys()].map(intervalIndex => formatTime(use24h, intervalIndex * timeInterval)); - }, [timeInterval, use24h]); + const intervalCount = Math.floor(minutesInDay / safeTimeInterval); + return [...Array(intervalCount).keys()].map(intervalIndex => formatTime(use24h, intervalIndex * safeTimeInterval)); + }, [safeTimeInterval, use24h]); const initialFocusIndex = d(() => { // if there are no options, there will not be any focusing - if (!timeOptions || !timeInterval) return null; + if (!timeOptions || !safeTimeInterval) return null; // if there is a set minute value, we focus it in the dropdown - if (time) return time / timeInterval; + if (time) return time / safeTimeInterval; const cacheTime = parseInputTime(rawValue); // if there is a valid value in the input cache, we try and focus close to it if (cacheTime) { - const flooredCacheTime = cacheTime - cacheTime % timeInterval; - return flooredCacheTime / timeInterval; + const flooredCacheTime = cacheTime - cacheTime % safeTimeInterval; + return flooredCacheTime / safeTimeInterval; } // If there is no set value, simply focus the middle of the dropdown (12:00) return Math.floor(timeOptions.length / 2); - }, [rawValue, time, timeInterval, timeOptions]); + }, [rawValue, time, safeTimeInterval, timeOptions]); const onInputKeyDown = e => { switch (e.key) { case 'ArrowUp': @@ -44530,6 +44965,7 @@ pre: e$2(ClockIcon, {}), inputRef: timeInputRef, disabled: disabled, + readonly: readonly, children: e$2("div", { class: "fjs-timepicker fjs-timepicker-anchor", children: [e$2("input", { @@ -44539,10 +44975,11 @@ class: "fjs-input", value: rawValue, disabled: disabled, + readOnly: readonly, placeholder: use24h ? 'hh:mm' : 'hh:mm ?m', autoComplete: "off", - onFocus: () => useDropdown && setDropdownIsOpen(true), - onClick: () => useDropdown && setDropdownIsOpen(true) + onFocus: () => !readonly && useDropdown && setDropdownIsOpen(true), + onClick: () => !readonly && useDropdown && setDropdownIsOpen(true) // @ts-ignore , @@ -44552,7 +44989,8 @@ }, onBlur: onInputBlur, onKeyDown: onInputKeyDown, - "data-input": true + "data-input": true, + "aria-describedby": props['aria-describedby'] }), dropdownIsOpen && e$2(DropdownList, { values: timeOptions, height: 150, @@ -44572,6 +45010,7 @@ errors = [], field, onChange, + readonly, value = '' } = props; const { @@ -44591,7 +45030,7 @@ } = validate; const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); const getNullDateTime = () => ({ date: new Date(Date.parse(null)), time: null @@ -44688,6 +45127,7 @@ time }); }, []); + const errorMessageId = allErrors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; const datePickerProps = { id, label: dateLabel, @@ -44697,7 +45137,9 @@ disabled, disallowPassedDates, date: dateTime.date, - setDate + readonly, + setDate, + 'aria-describedby': errorMessageId }; const timePickerProps = { id, @@ -44706,15 +45148,18 @@ formId, required, disabled, + readonly, use24h, timeInterval, time: dateTime.time, - setTime + setTime, + 'aria-describedby': errorMessageId }; return e$2("div", { class: formFieldClasses(type$8, { errors: allErrors, - disabled + disabled, + readonly }), children: [e$2("div", { class: classNames('fjs-vertical-group'), @@ -44728,25 +45173,28 @@ }), e$2(Description, { description: description }), e$2(Errors, { - errors: allErrors + errors: allErrors, + id: errorMessageId })] }); } - Datetime.create = (options = {}) => { - const defaults = {}; - set(defaults, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES.DATE); - set(defaults, DATE_LABEL_PATH, 'Date'); - return { - ...defaults, - ...options - }; + Datetime.config = { + type: type$8, + keyed: true, + label: 'Date time', + group: 'basic-input', + emptyValue: null, + sanitizeValue: sanitizeDateTimePickerValue, + create: (options = {}) => { + const defaults = {}; + set(defaults, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES.DATE); + set(defaults, DATE_LABEL_PATH, 'Date'); + return { + ...defaults, + ...options + }; + } }; - Datetime.type = type$8; - Datetime.keyed = true; - Datetime.emptyValue = null; - Datetime.sanitizeValue = sanitizeDateTimePickerValue; - Datetime.label = 'Date time'; - Datetime.group = 'basic-input'; /** * This file must not be changed or exchanged. @@ -44790,7 +45238,7 @@ href: "https://bpmn.io", target: "_blank", rel: "noopener", - style: "margin: 15px 20px 15px 10px; align-self: center; color: #404040", + style: "margin: 15px 20px 15px 10px; align-self: center; color: var(--cds-icon-primary, #404040)", children: e$2(Logo, {}) }), e$2("span", { children: ["Web-based tooling for BPMN, DMN, and forms powered by ", e$2("a", { @@ -44813,7 +45261,7 @@ rel: "noopener", class: "fjs-powered-by-link", title: "Powered by bpmn.io", - style: "color: #404040", + style: "color: var(--cds-text-primary, #404040)", onClick: props.onClick, children: e$2(Logo, {}) }) @@ -44841,8 +45289,12 @@ function FormComponent(props) { const form = useService('form'); const { - schema + schema, + properties } = form._getState(); + const { + ariaLabel + } = properties; const { onSubmit = noop, onReset = noop, @@ -44860,6 +45312,7 @@ class: "fjs-form", onSubmit: handleSubmit, onReset: handleReset, + "aria-label": ariaLabel, noValidate: true, children: [e$2(FormField, { field: schema, @@ -44870,7 +45323,7 @@ const NODE_TYPE_TEXT = 3, NODE_TYPE_ELEMENT = 1; - const ALLOWED_NODES = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'em', 'a', 'p', 'div', 'ul', 'ol', 'li', 'hr', 'blockquote', 'img', 'pre', 'code', 'br', 'strong']; + const ALLOWED_NODES = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'em', 'a', 'p', 'div', 'ul', 'ol', 'li', 'hr', 'blockquote', 'img', 'pre', 'code', 'br', 'strong', 'table', 'thead', 'tbody', 'tr', 'th', 'td']; const ALLOWED_ATTRIBUTES = ['align', 'alt', 'class', 'href', 'id', 'name', 'rel', 'target', 'src']; const ALLOWED_URI_PATTERN = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i; // eslint-disable-line no-useless-escape const ALLOWED_IMAGE_SRC_PATTERN = /^(https?|data):.*/i; // eslint-disable-line no-useless-escape @@ -44996,34 +45449,45 @@ } function _extends$h() { _extends$h = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$h.apply(this, arguments); } - var ImagePlaceholder = (({ - styles = {}, - ...props - }) => /*#__PURE__*/React.createElement("svg", _extends$h({ - width: "64", - height: "64", - viewBox: "0 0 1280 1280", - xmlns: "http://www.w3.org/2000/svg", - fillRule: "evenodd", - clipRule: "evenodd", - strokeLinejoin: "round", - strokeMiterlimit: "2" - }, props), /*#__PURE__*/React.createElement("path", { - fill: "#e5e9ed", - d: "M0 0h1280v1280H0z" - }), /*#__PURE__*/React.createElement("path", { - d: "M910 410H370v470h540V410zm-57.333 57.333v355.334H427.333V467.333h425.334z", - fill: "#cad3db" - }), /*#__PURE__*/React.createElement("path", { - d: "M810 770H480v-60l100-170 130 170 100-65v125z", - fill: "#cad3db" - }), /*#__PURE__*/React.createElement("circle", { - cx: "750", - cy: "550", - r: "50", - fill: "#cad3db", - transform: "translate(10 10)" - }))); + var SvgImagePlaceholder = function SvgImagePlaceholder(props) { + return /*#__PURE__*/v$1("svg", _extends$h({ + xmlns: "http://www.w3.org/2000/svg", + xmlSpace: "preserve", + width: 64, + height: 64, + style: { + fillRule: "evenodd", + clipRule: "evenodd", + strokeLinejoin: "round", + strokeMiterlimit: 2 + }, + viewBox: "0 0 1280 1280" + }, props), /*#__PURE__*/v$1("path", { + d: "M0 0h1280v1280H0z", + style: { + fill: "#e5e9ed" + } + }), /*#__PURE__*/v$1("path", { + d: "M910 410H370v470h540V410Zm-57.333 57.333v355.334H427.333V467.333h425.334Z", + style: { + fill: "#cad3db" + } + }), /*#__PURE__*/v$1("path", { + d: "M810 770H480v-60l100-170 130 170 100-65v125Z", + style: { + fill: "#cad3db" + } + }), /*#__PURE__*/v$1("circle", { + cx: 750, + cy: 550, + r: 50, + style: { + fill: "#cad3db" + }, + transform: "translate(10 10)" + })); + }; + var ImagePlaceholder = SvgImagePlaceholder; const type$7 = 'image'; function Image(props) { @@ -45035,12 +45499,16 @@ id, source } = field; - const evaluatedImageSource = useExpressionEvaluation(source); + const evaluatedImageSource = useSingleLineTemplateEvaluation(source, { + debug: true + }); const safeSource = d(() => sanitizeImageSource(evaluatedImageSource), [evaluatedImageSource]); - const altText = useExpressionEvaluation(alt); + const altText = useSingleLineTemplateEvaluation(alt, { + debug: true + }); const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); return e$2("div", { class: formFieldClasses(type$7), children: e$2("div", { @@ -45059,47 +45527,69 @@ }) }); } - Image.create = (options = {}) => ({ - ...options - }); - Image.type = type$7; - Image.keyed = false; - Image.label = 'Image view'; - Image.group = 'presentation'; + Image.config = { + type: type$7, + keyed: false, + label: 'Image view', + group: 'presentation', + create: (options = {}) => ({ + ...options + }) + }; + + function TemplatedInputAdorner(props) { + const { + pre, + post + } = props; + const evaluatedPre = useSingleLineTemplateEvaluation(pre, { + debug: true + }); + const evaluatedPost = useSingleLineTemplateEvaluation(post, { + debug: true + }); + return e$2(InputAdorner, { + ...props, + pre: evaluatedPre, + post: evaluatedPost + }); + } + var _path$e; function _extends$g() { _extends$g = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$g.apply(this, arguments); } - var AngelDownIcon = (({ - styles = {}, - ...props - }) => /*#__PURE__*/React.createElement("svg", _extends$g({ - xmlns: "http://www.w3.org/2000/svg", - width: "8", - height: "8" - }, props), /*#__PURE__*/React.createElement("path", { - fillRule: "evenodd", - clipRule: "evenodd", - fill: "currentColor", - stroke: "currentColor", - strokeWidth: ".5", - d: "M7.75 1.336L4 6.125.258 1.335 0 1.54l4 5.125L8 1.54zm0 0" - }))); + var SvgAngelDown = function SvgAngelDown(props) { + return /*#__PURE__*/v$1("svg", _extends$g({ + xmlns: "http://www.w3.org/2000/svg", + width: 8, + height: 8 + }, props), _path$e || (_path$e = /*#__PURE__*/v$1("path", { + fill: "currentColor", + fillRule: "evenodd", + stroke: "currentColor", + strokeWidth: 0.5, + d: "M7.75 1.336 4 6.125.258 1.335 0 1.54l4 5.125L8 1.54Zm0 0", + clipRule: "evenodd" + }))); + }; + var AngelDownIcon = SvgAngelDown; + var _path$d; function _extends$f() { _extends$f = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$f.apply(this, arguments); } - var AngelUpIcon = (({ - styles = {}, - ...props - }) => /*#__PURE__*/React.createElement("svg", _extends$f({ - xmlns: "http://www.w3.org/2000/svg", - width: "8", - height: "8" - }, props), /*#__PURE__*/React.createElement("path", { - fillRule: "evenodd", - clipRule: "evenodd", - fill: "currentColor", - stroke: "currentColor", - strokeWidth: ".5", - d: "M7.75 6.664L4 1.875.258 6.665 0 6.46l4-5.125L8 6.46zm0 0" - }))); + var SvgAngelUp = function SvgAngelUp(props) { + return /*#__PURE__*/v$1("svg", _extends$f({ + xmlns: "http://www.w3.org/2000/svg", + width: 8, + height: 8 + }, props), _path$d || (_path$d = /*#__PURE__*/v$1("path", { + fill: "currentColor", + fillRule: "evenodd", + stroke: "currentColor", + strokeWidth: 0.5, + d: "M7.75 6.664 4 1.875.258 6.665 0 6.46l4-5.125L8 6.46Zm0 0", + clipRule: "evenodd" + }))); + }; + var AngelUpIcon = SvgAngelUp; const type$6 = 'number'; function Numberfield(props) { @@ -45108,6 +45598,7 @@ errors = [], field, value, + readonly, onChange } = props; const { @@ -45132,10 +45623,10 @@ // checks whether the value currently in the form data is practically different from the one in the input field cache // this allows us to guarantee the field always displays valid form data, but without auto-simplifying values like 1.000 to 1 - const cacheValueMatchesState = d(() => Numberfield.sanitizeValue({ + const cacheValueMatchesState = d(() => Numberfield.config.sanitizeValue({ value, formField: field - }) === Numberfield.sanitizeValue({ + }) === Numberfield.config.sanitizeValue({ value: stringValueCache, formField: field }), [stringValueCache, value, field]); @@ -45180,6 +45671,9 @@ }); }, [field, onChange, serializeToString]); const increment = () => { + if (readonly) { + return; + } const base = isValidNumber(value) ? Big(value) : Big(0); const stepFlooredValue = base.minus(base.mod(arrowIncrementValue)); @@ -45187,6 +45681,9 @@ setValue(stepFlooredValue.plus(arrowIncrementValue).toFixed()); }; const decrement = () => { + if (readonly) { + return; + } const base = isValidNumber(value) ? Big(value) : Big(0); const offset = base.mod(arrowIncrementValue); if (offset.cmp(0) === 0) { @@ -45228,23 +45725,27 @@ }; const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); + const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; return e$2("div", { class: formFieldClasses(type$6, { errors, - disabled + disabled, + readonly }), children: [e$2(Label, { id: prefixId(id, formId), label: label, required: required - }), e$2(InputAdorner, { + }), e$2(TemplatedInputAdorner, { disabled: disabled, + readonly: readonly, pre: prefixAdorner, post: suffixAdorner, children: e$2("div", { class: classNames('fjs-vertical-group', { - 'fjs-disabled': disabled + 'fjs-disabled': disabled, + 'fjs-readonly': readonly }, { 'hasErrors': errors.length }), @@ -45252,6 +45753,7 @@ ref: inputRef, class: "fjs-input", disabled: disabled, + readOnly: readonly, id: prefixId(id, formId), onKeyDown: onKeyDown, onKeyPress: onKeyPress @@ -45262,10 +45764,12 @@ type: "text", autoComplete: "off", step: arrowIncrementValue, - value: displayValue + value: displayValue, + "aria-describedby": errorMessageId }), e$2("div", { class: classNames('fjs-number-arrow-container', { - 'fjs-disabled': disabled + 'fjs-disabled': disabled, + 'fjs-readonly': readonly }), children: [e$2("button", { class: "fjs-number-arrow-up", @@ -45289,31 +45793,34 @@ }), e$2(Description, { description: description }), e$2(Errors, { - errors: errors + errors: errors, + id: errorMessageId })] }); } - Numberfield.create = (options = {}) => ({ - ...options - }); - Numberfield.sanitizeValue = ({ - value, - formField - }) => { - // null state is allowed - if (isNullEquivalentValue(value)) return null; - - // if data cannot be parsed as a valid number, go into invalid NaN state - if (!isValidNumber(value)) return 'NaN'; - - // otherwise parse to formatting type - return formField.serializeToString ? value.toString() : Number(value); + Numberfield.config = { + type: type$6, + keyed: true, + label: 'Number', + group: 'basic-input', + emptyValue: null, + sanitizeValue: ({ + value, + formField + }) => { + // null state is allowed + if (isNullEquivalentValue(value)) return null; + + // if data cannot be parsed as a valid number, go into invalid NaN state + if (!isValidNumber(value)) return 'NaN'; + + // otherwise parse to formatting type + return formField.serializeToString ? value.toString() : Number(value); + }, + create: (options = {}) => ({ + ...options + }) }; - Numberfield.type = type$6; - Numberfield.keyed = true; - Numberfield.label = 'Number'; - Numberfield.emptyValue = null; - Numberfield.group = 'basic-input'; const type$5 = 'radio'; function Radio(props) { @@ -45321,6 +45828,7 @@ disabled, errors = [], field, + readonly, value } = props; const { @@ -45344,11 +45852,13 @@ } = useValuesAsync(field); const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); + const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; return e$2("div", { class: formFieldClasses(type$5, { errors, - disabled + disabled, + readonly }), children: [e$2(Label, { label: label, @@ -45365,56 +45875,62 @@ checked: option.value === value, class: "fjs-input", disabled: disabled, + readOnly: readonly, id: prefixId(`${id}-${index}`, formId), type: "radio", - onClick: () => onChange(option.value) + onClick: () => onChange(option.value), + "aria-describedby": errorMessageId }) }, `${id}-${index}`); }), e$2(Description, { description: description }), e$2(Errors, { - errors: errors + errors: errors, + id: errorMessageId })] }); } - Radio.create = function (options = {}) { - const defaults = {}; - - // provide default values if valuesKey isn't set - if (!options.valuesKey) { - defaults.values = [{ - label: 'Value', - value: 'value' - }]; + Radio.config = { + type: type$5, + keyed: true, + label: 'Radio', + group: 'selection', + emptyValue: null, + sanitizeValue: sanitizeSingleSelectValue, + create: (options = {}) => { + const defaults = {}; + + // provide default values if valuesKey isn't set + if (!options.valuesKey) { + defaults.values = [{ + label: 'Value', + value: 'value' + }]; + } + return { + ...defaults, + ...options + }; } - return { - ...defaults, - ...options - }; }; - Radio.type = type$5; - Radio.label = 'Radio'; - Radio.keyed = true; - Radio.emptyValue = null; - Radio.sanitizeValue = sanitizeSingleSelectValue; - Radio.group = 'selection'; + var _path$c; function _extends$e() { _extends$e = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$e.apply(this, arguments); } - var XMarkIcon = (({ - styles = {}, - ...props - }) => /*#__PURE__*/React.createElement("svg", _extends$e({ - xmlns: "http://www.w3.org/2000/svg", - width: "8", - height: "8" - }, props), /*#__PURE__*/React.createElement("path", { - fillRule: "evenodd", - clipRule: "evenodd", - fill: "currentColor", - stroke: "currentColor", - strokeWidth: ".5", - d: "M4 3.766L7.43.336l.234.234L4.234 4l3.43 3.43-.234.234L4 4.234.57 7.664.336 7.43 3.766 4 .336.57.57.336zm0 0" - }))); + var SvgXMark = function SvgXMark(props) { + return /*#__PURE__*/v$1("svg", _extends$e({ + xmlns: "http://www.w3.org/2000/svg", + width: 8, + height: 8 + }, props), _path$c || (_path$c = /*#__PURE__*/v$1("path", { + fill: "currentColor", + fillRule: "evenodd", + stroke: "currentColor", + strokeWidth: 0.5, + d: "M4 3.766 7.43.336l.234.234L4.234 4l3.43 3.43-.234.234L4 4.234.57 7.664.336 7.43 3.766 4 .336.57.57.336Zm0 0", + clipRule: "evenodd" + }))); + }; + var XMarkIcon = SvgXMark; function SearchableSelect(props) { const { @@ -45422,11 +45938,12 @@ disabled, errors, field, + readonly, value } = props; const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); const [filter, setFilter] = l$1(''); const [isDropdownExpanded, setIsDropdownExpanded] = l$1(false); const [shouldApplyFilter, setShouldApplyFilter] = l$1(true); @@ -45494,11 +46011,11 @@ }, [isDropdownExpanded, isEscapeClosed]); const displayState = d(() => { const ds = {}; - ds.componentReady = !disabled && loadState === LOAD_STATES.LOADED; + ds.componentReady = !disabled && !readonly && loadState === LOAD_STATES.LOADED; ds.displayCross = ds.componentReady && value !== null && value !== undefined; - ds.displayDropdown = !disabled && isDropdownExpanded && !isEscapeClosed; + ds.displayDropdown = !disabled && !readonly && isDropdownExpanded && !isEscapeClosed; return ds; - }, [disabled, isDropdownExpanded, isEscapeClosed, loadState, value]); + }, [disabled, isDropdownExpanded, isEscapeClosed, loadState, readonly, value]); const onAngelMouseDown = A$1(e => { setIsEscapeClose(false); setIsDropdownExpanded(!isDropdownExpanded); @@ -45510,12 +46027,14 @@ children: [e$2("div", { id: prefixId(`${id}`, formId), class: classNames('fjs-input-group', { - 'disabled': disabled + 'disabled': disabled, + 'readonly': readonly }, { 'hasErrors': errors.length }), children: [e$2("input", { disabled: disabled, + readOnly: readonly, class: "fjs-input", ref: searchbarRef, id: prefixId(`${id}-search`, formId), @@ -45537,7 +46056,8 @@ onBlur: () => { setIsDropdownExpanded(false); setFilter(valueLabel); - } + }, + "aria-describedby": props['aria-describedby'] }), displayState.displayCross && e$2("span", { class: "fjs-select-cross", onMouseDown: e => { @@ -45571,11 +46091,12 @@ disabled, errors, field, + readonly, value } = props; const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); const [isDropdownExpanded, setIsDropdownExpanded] = l$1(false); const selectRef = s(); const { @@ -45596,9 +46117,9 @@ }, [field, props]); const displayState = d(() => { const ds = {}; - ds.componentReady = !disabled && loadState === LOAD_STATES.LOADED; + ds.componentReady = !disabled && !readonly && loadState === LOAD_STATES.LOADED; ds.displayCross = ds.componentReady && value !== null && value !== undefined; - ds.displayDropdown = !disabled && isDropdownExpanded; + ds.displayDropdown = !disabled && !readonly && isDropdownExpanded; return ds; }, [disabled, isDropdownExpanded, loadState, value]); const onMouseDown = A$1(e => { @@ -45617,20 +46138,27 @@ ref: selectRef, id: prefixId(`${id}`, formId), class: classNames('fjs-input-group', { - 'disabled': disabled + disabled, + readonly }, { 'hasErrors': errors.length }), onFocus: () => setIsDropdownExpanded(true), onBlur: () => setIsDropdownExpanded(false), - onMouseDown: e => onMouseDown(e), - tabIndex: disabled ? undefined : 0, + onMouseDown: onMouseDown, children: [e$2("div", { class: classNames('fjs-select-display', { 'fjs-select-placeholder': !value }), id: prefixId(`${id}-display`, formId), children: valueLabel || 'Select' + }), !disabled && e$2("input", { + id: prefixId(`${id}-search`, formId), + class: "fjs-select-hidden-input", + value: valueLabel, + onFocus: () => !readonly && setIsDropdownExpanded(true), + onBlur: () => !readonly && setIsDropdownExpanded(false), + "aria-describedby": props['aria-describedby'] }), displayState.displayCross && e$2("span", { class: "fjs-select-cross", onMouseDown: e => { @@ -45665,6 +46193,7 @@ errors = [], field, onChange, + readonly, value } = props; const { @@ -45679,22 +46208,32 @@ } = validate; const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); + const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; const selectProps = d(() => ({ id, disabled, errors, field, value, - onChange - }), [disabled, errors, field, id, value, onChange]); + onChange, + readonly, + 'aria-describedby': errorMessageId + }), [disabled, errors, field, id, value, onChange, readonly, errorMessageId]); return e$2("div", { class: formFieldClasses(type$4, { errors, - disabled + disabled, + readonly }), + onKeyDown: event => { + if (event.key === 'Enter') { + event.preventDefault(); + event.stopPropagation(); + } + }, children: [e$2(Label, { - id: prefixId(id, formId), + id: prefixId(`${id}-search`, formId), label: label, required: required }), searchable ? e$2(SearchableSelect, { @@ -45704,31 +46243,34 @@ }), e$2(Description, { description: description }), e$2(Errors, { - errors: errors + errors: errors, + id: errorMessageId })] }); } - Select.create = (options = {}) => { - const defaults = {}; - - // provide default values if valuesKey isn't set - if (!options.valuesKey) { - defaults.values = [{ - label: 'Value', - value: 'value' - }]; + Select.config = { + type: type$4, + keyed: true, + label: 'Select', + group: 'selection', + emptyValue: null, + sanitizeValue: sanitizeSingleSelectValue, + create: (options = {}) => { + const defaults = {}; + + // provide default values if valuesKey isn't set + if (!options.valuesKey) { + defaults.values = [{ + label: 'Value', + value: 'value' + }]; + } + return { + ...defaults, + ...options + }; } - return { - ...defaults, - ...options - }; }; - Select.type = type$4; - Select.label = 'Select'; - Select.keyed = true; - Select.emptyValue = null; - Select.sanitizeValue = sanitizeSingleSelectValue; - Select.group = 'selection'; const type$3 = 'taglist'; function Taglist(props) { @@ -45736,16 +46278,22 @@ disabled, errors = [], field, + readonly, value: values = [] } = props; const { description, id, - label + label, + validate = {} } = field; + const { + required + } = validate; const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); + const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; const [filter, setFilter] = l$1(''); const [filteredOptions, setFilteredOptions] = l$1([]); const [isDropdownExpanded, setIsDropdownExpanded] = l$1(false); @@ -45821,6 +46369,10 @@ break; } }; + const onBlur = () => { + setIsDropdownExpanded(false); + setFilter(''); + }; const onTagRemoveClick = (event, value) => { const { target @@ -45837,27 +46389,37 @@ return e$2("div", { class: formFieldClasses(type$3, { errors, - disabled + disabled, + readonly }), + onKeyDown: event => { + if (event.key === 'Enter') { + event.stopPropagation(); + event.preventDefault(); + } + }, children: [e$2(Label, { label: label, + required: required, id: prefixId(`${id}-search`, formId) }), e$2("div", { class: classNames('fjs-taglist', { - 'fjs-disabled': disabled + 'fjs-disabled': disabled, + 'fjs-readonly': readonly }), children: [loadState === LOAD_STATES.LOADED && e$2("div", { class: "fjs-taglist-tags", children: values.map(v => { return e$2("div", { class: classNames('fjs-taglist-tag', { - 'fjs-disabled': disabled + 'fjs-disabled': disabled, + 'fjs-readonly': readonly }), onMouseDown: e => e.preventDefault(), children: [e$2("span", { class: "fjs-taglist-tag-label", children: valueToOptionMap[v] ? valueToOptionMap[v].label : `unexpected value{${v}}` - }), !disabled && e$2("button", { + }), !disabled && !readonly && e$2("button", { type: "button", title: "Remove tag", class: "fjs-taglist-tag-remove", @@ -45868,21 +46430,22 @@ }) }), e$2("input", { disabled: disabled, + readOnly: readonly, class: "fjs-taglist-input", ref: searchbarRef, id: prefixId(`${id}-search`, formId), onChange: onFilterChange, type: "text", value: filter, - placeholder: disabled ? '' : 'Search', + placeholder: disabled || readonly ? undefined : 'Search', autoComplete: "off", - onKeyDown: e => onInputKeyDown(e), + onKeyDown: onInputKeyDown, onMouseDown: () => setIsEscapeClose(false), - onFocus: () => setIsDropdownExpanded(true), + onFocus: () => !readonly && setIsDropdownExpanded(true), onBlur: () => { - setIsDropdownExpanded(false); - setFilter(''); - } + !readonly && onBlur(); + }, + "aria-describedby": errorMessageId })] }), e$2("div", { class: "fjs-taglist-anchor", @@ -45896,34 +46459,41 @@ }), e$2(Description, { description: description }), e$2(Errors, { - errors: errors + errors: errors, + id: errorMessageId })] }); } - Taglist.create = (options = {}) => { - const defaults = {}; - - // provide default values if valuesKey isn't set - if (!options.valuesKey) { - defaults.values = [{ - label: 'Value', - value: 'value' - }]; + Taglist.config = { + type: type$3, + keyed: true, + label: 'Tag list', + group: 'selection', + emptyValue: [], + sanitizeValue: sanitizeMultiSelectValue, + create: (options = {}) => { + const defaults = {}; + + // provide default values if valuesKey isn't set + if (!options.valuesKey) { + defaults.values = [{ + label: 'Value', + value: 'value' + }]; + } + return { + ...defaults, + ...options + }; } - return { - ...defaults, - ...options - }; }; - Taglist.type = type$3; - Taglist.label = 'Tag list'; - Taglist.keyed = true; - Taglist.emptyValue = []; - Taglist.sanitizeValue = sanitizeMultiSelectValue; - Taglist.group = 'selection'; const type$2 = 'text'; function Text(props) { + const form = useService('form'); + const { + textLinkTarget + } = form._getState().properties; const { field, disableLinks @@ -45945,9 +46515,20 @@ const html = markdownRenderer.render(markdown); return sanitizeHTML(html); }, [markdownRenderer, markdown]); - const componentOverrides = d(() => disableLinks ? { - 'a': DisabledLink - } : {}, [disableLinks]); + const OverridenTargetLink = d(() => BuildOverridenTargetLink(textLinkTarget), [textLinkTarget]); + const componentOverrides = d(() => { + if (disableLinks) { + return { + 'a': DisabledLink + }; + } + if (textLinkTarget) { + return { + 'a': OverridenTargetLink + }; + } + return {}; + }, [disableLinks, OverridenTargetLink, textLinkTarget]); return e$2("div", { class: formFieldClasses(type$2), children: e$2(Markup, { @@ -45957,21 +46538,35 @@ }) }); } - Text.create = (options = {}) => ({ - text: '# Text', - ...options - }); - Text.type = type$2; - Text.keyed = false; - Text.group = 'presentation'; - Text.label = 'Text view'; + Text.config = { + type: type$2, + keyed: false, + label: 'Text view', + group: 'presentation', + create: (options = {}) => ({ + text: '# Text', + ...options + }) + }; + function BuildOverridenTargetLink(target) { + return function ({ + children, + ...rest + }) { + return e$2("a", { + ...rest, + target: target, + children: children + }); + }; + } function DisabledLink({ - href, - children + children, + ...rest }) { return e$2("a", { + ...rest, class: "fjs-disabled-link", - href: href, tabIndex: -1, children: children }); @@ -45983,6 +46578,7 @@ disabled, errors = [], field, + readonly, value = '' } = props; const { @@ -46009,46 +46605,64 @@ }; const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); + const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; return e$2("div", { class: formFieldClasses(type$1, { errors, - disabled + disabled, + readonly }), children: [e$2(Label, { id: prefixId(id, formId), label: label, required: required - }), e$2(InputAdorner, { + }), e$2(TemplatedInputAdorner, { disabled: disabled, + readonly: readonly, pre: prefixAdorner, post: suffixAdorner, children: e$2("input", { class: "fjs-input", disabled: disabled, + readOnly: readonly, id: prefixId(id, formId), onInput: onChange, type: "text", - value: value + value: value, + "aria-describedby": errorMessageId }) }), e$2(Description, { description: description }), e$2(Errors, { - errors: errors + errors: errors, + id: errorMessageId })] }); } - Textfield.create = (options = {}) => ({ - ...options - }); - Textfield.type = type$1; - Textfield.label = 'Text field'; - Textfield.keyed = true; - Textfield.emptyValue = ''; - Textfield.sanitizeValue = ({ - value - }) => isArray$3(value) || isObject(value) ? '' : String(value); - Textfield.group = 'basic-input'; + Textfield.config = { + type: type$1, + keyed: true, + label: 'Text field', + group: 'basic-input', + emptyValue: '', + sanitizeValue: ({ + value + }) => { + if (isArray$3(value) || isObject(value)) { + return ''; + } + + // sanitize newlines to spaces + if (typeof value === 'string') { + return value.replace(/[\r\n\t]/g, ' '); + } + return String(value); + }, + create: (options = {}) => ({ + ...options + }) + }; const type = 'textarea'; function Textarea(props) { @@ -46056,6 +46670,7 @@ disabled, errors = [], field, + readonly, value = '' } = props; const { @@ -46094,11 +46709,13 @@ }, [autoSizeTextarea, value]); const { formId - } = F$1(FormContext$1); + } = F(FormContext$1); + const errorMessageId = errors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`; return e$2("div", { class: formFieldClasses(type, { errors, - disabled + disabled, + readonly }), children: [e$2(Label, { id: prefixId(id, formId), @@ -46107,28 +46724,33 @@ }), e$2("textarea", { class: "fjs-textarea", disabled: disabled, + readonly: readonly, id: prefixId(id, formId), onInput: onInput, value: value, - ref: textareaRef + ref: textareaRef, + "aria-describedby": errorMessageId }), e$2(Description, { description: description }), e$2(Errors, { - errors: errors + errors: errors, + id: errorMessageId })] }); } - Textarea.create = (options = {}) => ({ - ...options - }); - Textarea.type = type; - Textarea.label = 'Text area'; - Textarea.keyed = true; - Textarea.emptyValue = ''; - Textarea.sanitizeValue = ({ - value - }) => isArray$3(value) || isObject(value) ? '' : String(value); - Textarea.group = 'basic-input'; + Textarea.config = { + type, + keyed: true, + label: 'Text area', + group: 'basic-input', + emptyValue: '', + sanitizeValue: ({ + value + }) => isArray$3(value) || isObject(value) ? '' : String(value), + create: (options = {}) => ({ + ...options + }) + }; const formFields = [Button, Checkbox, Checklist, Default, Image, Numberfield, Datetime, Radio, Select, Taglist, Text, Textfield, Textarea]; @@ -46136,7 +46758,7 @@ constructor() { this._formFields = {}; formFields.forEach(formField => { - this.register(formField.type, formField); + this.register(formField.config.type, formField); }); } register(type, formField) { @@ -46213,55 +46835,55 @@ validator: ['type', Validator] }; - /** - * @typedef { import('./types').Injector } Injector - * @typedef { import('./types').Data } Data - * @typedef { import('./types').Errors } Errors - * @typedef { import('./types').Schema } Schema - * @typedef { import('./types').FormProperties } FormProperties - * @typedef { import('./types').FormProperty } FormProperty - * @typedef { import('./types').FormEvent } FormEvent - * @typedef { import('./types').FormOptions } FormOptions - * - * @typedef { { - * data: Data, - * initialData: Data, - * errors: Errors, - * properties: FormProperties, - * schema: Schema - * } } State - * - * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority - * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority - * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType + /** + * @typedef { import('./types').Injector } Injector + * @typedef { import('./types').Data } Data + * @typedef { import('./types').Errors } Errors + * @typedef { import('./types').Schema } Schema + * @typedef { import('./types').FormProperties } FormProperties + * @typedef { import('./types').FormProperty } FormProperty + * @typedef { import('./types').FormEvent } FormEvent + * @typedef { import('./types').FormOptions } FormOptions + * + * @typedef { { + * data: Data, + * initialData: Data, + * errors: Errors, + * properties: FormProperties, + * schema: Schema + * } } State + * + * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority + * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority + * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType */ const ids = new Ids([32, 36, 1]); - /** - * The form. + /** + * The form. */ class Form { - /** - * @constructor - * @param {FormOptions} options + /** + * @constructor + * @param {FormOptions} options */ constructor(options = {}) { - /** - * @public - * @type {OnEventType} + /** + * @public + * @type {OnEventType} */ this.on = this._onEvent; - /** - * @public - * @type {String} + /** + * @public + * @type {String} */ this._id = ids.next(); - /** - * @private - * @type {Element} + /** + * @private + * @type {Element} */ this._container = createFormContainer(); const { @@ -46270,9 +46892,9 @@ properties = {} } = options; - /** - * @private - * @type {State} + /** + * @private + * @type {State} */ this._state = { initialData: null, @@ -46296,9 +46918,9 @@ this._emit('form.clear'); } - /** - * Destroy the form, removing it from DOM, - * if attached. + /** + * Destroy the form, removing it from DOM, + * if attached. */ destroy() { // destroy form services @@ -46309,13 +46931,13 @@ this._detach(false); } - /** - * Open a form schema with the given initial data. - * - * @param {Schema} schema - * @param {Data} [data] - * - * @return Promise<{ warnings: Array }> + /** + * Open a form schema with the given initial data. + * + * @param {Schema} schema + * @param {Data} [data] + * + * @return Promise<{ warnings: Array }> */ importSchema(schema, data = {}) { return new Promise((resolve, reject) => { @@ -46348,16 +46970,16 @@ }); } - /** - * Submit the form, triggering all field validations. - * - * @returns { { data: Data, errors: Errors } } + /** + * Submit the form, triggering all field validations. + * + * @returns { { data: Data, errors: Errors } } */ submit() { const { properties } = this._getState(); - if (properties.readOnly) { + if (properties.readOnly || properties.disabled) { throw new Error('form is read-only'); } const data = this._getSubmitData(); @@ -46378,8 +47000,8 @@ }); } - /** - * @returns {Errors} + /** + * @returns {Errors} */ validate() { const formFieldRegistry = this.get('formFieldRegistry'), @@ -46405,8 +47027,8 @@ return errors; } - /** - * @param {Element|string} parentNode + /** + * @param {Element|string} parentNode */ attachTo(parentNode) { if (!parentNode) { @@ -46424,10 +47046,10 @@ this._detach(); } - /** - * @private - * - * @param {boolean} [emit] + /** + * @private + * + * @param {boolean} [emit] */ _detach(emit = true) { const container = this._container, @@ -46441,9 +47063,9 @@ parentNode.removeChild(container); } - /** - * @param {FormProperty} property - * @param {any} value + /** + * @param {FormProperty} property + * @param {any} value */ setProperty(property, value) { const properties = set(this._getState().properties, [property], value); @@ -46452,21 +47074,21 @@ }); } - /** - * @param {FormEvent} type - * @param {Function} handler + /** + * @param {FormEvent} type + * @param {Function} handler */ off(type, handler) { this.get('eventBus').off(type, handler); } - /** - * @private - * - * @param {FormOptions} options - * @param {Element} container - * - * @returns {Injector} + /** + * @private + * + * @param {FormOptions} options + * @param {Element} container + * + * @returns {Injector} */ _createInjector(options, container) { const { @@ -46485,17 +47107,17 @@ }, core, ...modules, ...additionalModules]); } - /** - * @private + /** + * @private */ _emit(type, data) { this.get('eventBus').fire(type, data); } - /** - * @internal - * - * @param { { add?: boolean, field: any, remove?: number, value?: any } } update + /** + * @internal + * + * @param { { add?: boolean, field: any, remove?: number, value?: any } } update */ _update(update) { const { @@ -46519,15 +47141,15 @@ }); } - /** - * @internal + /** + * @internal */ _getState() { return this._state; } - /** - * @internal + /** + * @internal */ _setState(state) { this._state = { @@ -46537,22 +47159,22 @@ this._emit('changed', this._getState()); } - /** - * @internal + /** + * @internal */ _getModules() { return [ExpressionLanguageModule, MarkdownModule]; } - /** - * @internal + /** + * @internal */ _onEvent(type, priority, handler) { this.get('eventBus').on(type, priority, handler); } - /** - * @internal + /** + * @internal */ _getSubmitData() { const formFieldRegistry = this.get('formFieldRegistry'); @@ -46577,8 +47199,8 @@ return filteredSubmitData; } - /** - * @internal + /** + * @internal */ _applyConditions(toFilter, data) { const conditionChecker = this.get('conditionChecker'); @@ -46586,18 +47208,18 @@ } } - const schemaVersion = 8; + const schemaVersion = 9; - /** - * @typedef { import('./types').CreateFormOptions } CreateFormOptions + /** + * @typedef { import('./types').CreateFormOptions } CreateFormOptions */ - /** - * Create a form. - * - * @param {CreateFormOptions} options - * - * @return {Promise
} + /** + * Create a form. + * + * @param {CreateFormOptions} options + * + * @return {Promise} */ function createForm(options) { const {