@icure/form 1.1.0 → 1.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/common/field-with-options.d.ts +9 -0
- package/components/common/field-with-options.js +50 -0
- package/components/common/field-with-options.js.map +1 -0
- package/components/common/field.d.ts +46 -0
- package/components/common/field.js +107 -0
- package/components/common/field.js.map +1 -0
- package/components/common/index.d.ts +1 -0
- package/components/{iqr-form-loader → common}/index.js +1 -3
- package/components/common/index.js.map +1 -0
- package/components/{iqr-text-field → common}/styles/paths.d.ts +3 -0
- package/components/{iqr-text-field → common}/styles/paths.js +28 -5
- package/components/common/styles/paths.js.map +1 -0
- package/components/common/utils.d.ts +8 -0
- package/components/common/utils.js +42 -0
- package/components/common/utils.js.map +1 -0
- package/components/icure-button-group/index.d.ts +12 -0
- package/components/icure-button-group/index.js +1140 -0
- package/components/icure-button-group/index.js.map +1 -0
- package/components/icure-date-picker/index.d.ts +16 -0
- package/components/icure-date-picker/index.js +1140 -0
- package/components/icure-date-picker/index.js.map +1 -0
- package/components/icure-dropdown-field/index.d.ts +16 -0
- package/components/icure-dropdown-field/index.js +1153 -0
- package/components/icure-dropdown-field/index.js.map +1 -0
- package/components/icure-form/fields/button-group/checkbox.d.ts +6 -0
- package/components/icure-form/fields/button-group/checkbox.js +61 -0
- package/components/icure-form/fields/button-group/checkbox.js.map +1 -0
- package/components/icure-form/fields/button-group/index.d.ts +2 -0
- package/components/icure-form/fields/button-group/index.js +19 -0
- package/components/icure-form/fields/button-group/index.js.map +1 -0
- package/components/icure-form/fields/button-group/radio-button.d.ts +6 -0
- package/components/icure-form/fields/button-group/radio-button.js +61 -0
- package/components/icure-form/fields/button-group/radio-button.js.map +1 -0
- package/components/icure-form/fields/date-picker/date-picker.d.ts +4 -0
- package/components/icure-form/fields/date-picker/date-picker.js +29 -0
- package/components/icure-form/fields/date-picker/date-picker.js.map +1 -0
- package/components/icure-form/fields/date-picker/date-time-picker.d.ts +4 -0
- package/components/icure-form/fields/date-picker/date-time-picker.js +29 -0
- package/components/icure-form/fields/date-picker/date-time-picker.js.map +1 -0
- package/components/icure-form/fields/date-picker/index.d.ts +3 -0
- package/components/icure-form/fields/date-picker/index.js +20 -0
- package/components/icure-form/fields/date-picker/index.js.map +1 -0
- package/components/icure-form/fields/date-picker/time-picker.d.ts +4 -0
- package/components/icure-form/fields/date-picker/time-picker.js +29 -0
- package/components/icure-form/fields/date-picker/time-picker.js.map +1 -0
- package/components/icure-form/fields/dropdown/dropdown-field.d.ts +11 -0
- package/components/icure-form/fields/dropdown/dropdown-field.js +65 -0
- package/components/icure-form/fields/dropdown/dropdown-field.js.map +1 -0
- package/components/icure-form/fields/dropdown/index.d.ts +1 -0
- package/components/icure-form/fields/dropdown/index.js +18 -0
- package/components/icure-form/fields/dropdown/index.js.map +1 -0
- package/components/icure-form/fields/index.d.ts +9 -0
- package/components/icure-form/fields/index.js +26 -0
- package/components/icure-form/fields/index.js.map +1 -0
- package/components/icure-form/fields/items-list-field/index.d.ts +1 -0
- package/components/icure-form/fields/items-list-field/index.js +18 -0
- package/components/icure-form/fields/items-list-field/index.js.map +1 -0
- package/components/icure-form/fields/items-list-field/items-list-field.d.ts +6 -0
- package/components/icure-form/fields/items-list-field/items-list-field.js +49 -0
- package/components/icure-form/fields/items-list-field/items-list-field.js.map +1 -0
- package/components/icure-form/fields/label/index.d.ts +1 -0
- package/components/icure-form/fields/label/index.js +18 -0
- package/components/icure-form/fields/label/index.js.map +1 -0
- package/components/{iqr-form/fields/multipleChoice.d.ts → icure-form/fields/label/label.d.ts} +5 -4
- package/components/{iqr-form/fields/multipleChoice.js → icure-form/fields/label/label.js} +18 -15
- package/components/icure-form/fields/label/label.js.map +1 -0
- package/components/icure-form/fields/measure-field/index.d.ts +1 -0
- package/components/icure-form/fields/measure-field/index.js +18 -0
- package/components/icure-form/fields/measure-field/index.js.map +1 -0
- package/components/icure-form/fields/measure-field/measure-field.d.ts +4 -0
- package/components/icure-form/fields/measure-field/measure-field.js +31 -0
- package/components/icure-form/fields/measure-field/measure-field.js.map +1 -0
- package/components/icure-form/fields/number-field/index.d.ts +1 -0
- package/components/icure-form/fields/number-field/index.js +18 -0
- package/components/icure-form/fields/number-field/index.js.map +1 -0
- package/components/icure-form/fields/number-field/number-field.d.ts +4 -0
- package/components/icure-form/fields/number-field/number-field.js +29 -0
- package/components/icure-form/fields/number-field/number-field.js.map +1 -0
- package/components/icure-form/fields/text-field/index.d.ts +1 -0
- package/components/icure-form/fields/text-field/index.js +18 -0
- package/components/icure-form/fields/text-field/index.js.map +1 -0
- package/components/icure-form/fields/text-field/text-field.d.ts +28 -0
- package/components/icure-form/fields/text-field/text-field.js +123 -0
- package/components/icure-form/fields/text-field/text-field.js.map +1 -0
- package/components/icure-form/fields/token-field/index.d.ts +1 -0
- package/components/icure-form/fields/token-field/index.js +18 -0
- package/components/icure-form/fields/token-field/index.js.map +1 -0
- package/components/icure-form/fields/token-field/token-field.d.ts +6 -0
- package/components/{iqr-form/fields/datePicker.js → icure-form/fields/token-field/token-field.js} +26 -34
- package/components/icure-form/fields/token-field/token-field.js.map +1 -0
- package/components/icure-form/fields/utils/index.d.ts +11 -0
- package/components/icure-form/fields/utils/index.js +48 -0
- package/components/icure-form/fields/utils/index.js.map +1 -0
- package/components/icure-form/index.d.ts +23 -0
- package/components/icure-form/index.js +1127 -0
- package/components/icure-form/index.js.map +1 -0
- package/components/icure-form/renderer/form/form-selection-button.d.ts +9 -0
- package/components/icure-form/renderer/form/form-selection-button.js +108 -0
- package/components/icure-form/renderer/form/form-selection-button.js.map +1 -0
- package/components/icure-form/renderer/form/form.d.ts +3 -0
- package/components/icure-form/renderer/form/form.js +399 -0
- package/components/icure-form/renderer/form/form.js.map +1 -0
- package/components/icure-form/renderer/index.d.ts +11 -0
- package/components/icure-form/renderer/index.js.map +1 -0
- package/components/icure-label/index.d.ts +8 -0
- package/components/icure-label/index.js +1072 -0
- package/components/icure-label/index.js.map +1 -0
- package/components/icure-text-field/index.d.ts +69 -0
- package/components/icure-text-field/index.js +1739 -0
- package/components/icure-text-field/index.js.map +1 -0
- package/components/icure-text-field/plugin/caret-fix-plugin.js.map +1 -0
- package/components/{iqr-text-field → icure-text-field}/plugin/has-content-class-plugin.d.ts +1 -1
- package/components/icure-text-field/plugin/has-content-class-plugin.js.map +1 -0
- package/components/icure-text-field/plugin/mask-plugin.js.map +1 -0
- package/components/icure-text-field/plugin/regexp-plugin.js.map +1 -0
- package/components/icure-text-field/prosemirror-commands.js.map +1 -0
- package/components/{iqr-text-field → icure-text-field}/prosemirror-utils.d.ts +1 -1
- package/components/icure-text-field/prosemirror-utils.js.map +1 -0
- package/components/icure-text-field/schema/common-marks.js.map +1 -0
- package/components/{iqr-text-field → icure-text-field}/schema/date-time-schema.d.ts +3 -3
- package/components/icure-text-field/schema/date-time-schema.js.map +1 -0
- package/components/{iqr-text-field → icure-text-field}/schema/decimal-schema.d.ts +1 -1
- package/components/icure-text-field/schema/decimal-schema.js.map +1 -0
- package/components/icure-text-field/schema/index.d.ts +6 -0
- package/components/{iqr-text-field → icure-text-field}/schema/index.js +6 -3
- package/components/icure-text-field/schema/index.js.map +1 -0
- package/components/icure-text-field/schema/items-list-schema.d.ts +3 -0
- package/components/icure-text-field/schema/items-list-schema.js +28 -0
- package/components/icure-text-field/schema/items-list-schema.js.map +1 -0
- package/components/icure-text-field/schema/items-list.d.ts +3 -0
- package/components/icure-text-field/schema/items-list.js +31 -0
- package/components/icure-text-field/schema/items-list.js.map +1 -0
- package/components/{iqr-text-field → icure-text-field}/schema/markdown-schema.d.ts +3 -3
- package/components/icure-text-field/schema/markdown-schema.js.map +1 -0
- package/components/icure-text-field/schema/measure-schema.d.ts +7 -0
- package/components/icure-text-field/schema/measure-schema.js +81 -0
- package/components/icure-text-field/schema/measure-schema.js.map +1 -0
- package/components/{iqr-text-field → icure-text-field}/schema/token-schema.d.ts +1 -1
- package/components/{iqr-text-field → icure-text-field}/schema/token-schema.js +3 -6
- package/components/icure-text-field/schema/token-schema.js.map +1 -0
- package/components/icure-text-field/schema/utils.js.map +1 -0
- package/components/icure-text-field/selection-companion.js.map +1 -0
- package/components/{iqr-text-field → icure-text-field}/suggestion-palette.d.ts +1 -6
- package/components/icure-text-field/suggestion-palette.js.map +1 -0
- package/components/index.d.ts +5 -2
- package/components/index.js +5 -2
- package/components/index.js.map +1 -1
- package/components/model/index.d.ts +782 -0
- package/components/model/index.js +632 -0
- package/components/model/index.js.map +1 -0
- package/components/themes/default/index.d.ts +1 -0
- package/components/themes/default/index.js +28 -0
- package/components/themes/default/index.js.map +1 -0
- package/components/themes/ehr-lite/index.d.ts +1 -0
- package/components/themes/ehr-lite/index.js +321 -0
- package/components/themes/ehr-lite/index.js.map +1 -0
- package/components/themes/kendo/index.d.ts +1 -0
- package/components/themes/kendo/index.js +285 -0
- package/components/themes/kendo/index.js.map +1 -0
- package/conversion/ckmeans-grouping.d.ts +4 -0
- package/conversion/ckmeans-grouping.js +53 -0
- package/conversion/ckmeans-grouping.js.map +1 -0
- package/conversion/ckmeans.d.ts +44 -0
- package/conversion/ckmeans.js +287 -0
- package/conversion/ckmeans.js.map +1 -0
- package/conversion/icure-convert.d.ts +3 -0
- package/conversion/icure-convert.js +165 -0
- package/conversion/icure-convert.js.map +1 -0
- package/generic/index.d.ts +1 -0
- package/generic/index.js +18 -0
- package/generic/index.js.map +1 -0
- package/generic/model.d.ts +39 -0
- package/{components/iqr-form-loader/models.js → generic/model.js} +1 -1
- package/generic/model.js.map +1 -0
- package/icure/form-values-container.d.ts +83 -0
- package/icure/form-values-container.js +445 -0
- package/icure/form-values-container.js.map +1 -0
- package/icure/index.d.ts +2 -0
- package/icure/index.js +19 -0
- package/icure/index.js.map +1 -0
- package/icure/model.d.ts +10 -0
- package/icure/model.js +3 -0
- package/icure/model.js.map +1 -0
- package/package.json +21 -16
- package/utils/code-utils.d.ts +18 -0
- package/utils/code-utils.js +36 -0
- package/utils/code-utils.js.map +1 -0
- package/utils/fields-values-provider.d.ts +18 -0
- package/utils/fields-values-provider.js +50 -0
- package/utils/fields-values-provider.js.map +1 -0
- package/utils/form-value-container.d.ts +3 -0
- package/utils/form-value-container.js +45 -0
- package/utils/form-value-container.js.map +1 -0
- package/utils/icure-utils.d.ts +8 -11
- package/utils/icure-utils.js +47 -48
- package/utils/icure-utils.js.map +1 -1
- package/utils/interpreter.d.ts +4 -0
- package/utils/interpreter.js +52 -0
- package/utils/interpreter.js.map +1 -0
- package/utils/languages.d.ts +3 -1
- package/utils/languages.js +4 -4
- package/utils/languages.js.map +1 -1
- package/utils/markdown.d.ts +8 -0
- package/utils/markdown.js +58 -0
- package/utils/markdown.js.map +1 -0
- package/utils/primitive.d.ts +7 -0
- package/utils/primitive.js +123 -0
- package/utils/primitive.js.map +1 -0
- package/components/iqr-form/fields/datePicker.d.ts +0 -10
- package/components/iqr-form/fields/datePicker.js.map +0 -1
- package/components/iqr-form/fields/dateTimePicker.d.ts +0 -10
- package/components/iqr-form/fields/dateTimePicker.js +0 -49
- package/components/iqr-form/fields/dateTimePicker.js.map +0 -1
- package/components/iqr-form/fields/measureField.d.ts +0 -8
- package/components/iqr-form/fields/measureField.js +0 -44
- package/components/iqr-form/fields/measureField.js.map +0 -1
- package/components/iqr-form/fields/multipleChoice.js.map +0 -1
- package/components/iqr-form/fields/numberField.d.ts +0 -8
- package/components/iqr-form/fields/numberField.js +0 -44
- package/components/iqr-form/fields/numberField.js.map +0 -1
- package/components/iqr-form/fields/textfield.d.ts +0 -1
- package/components/iqr-form/fields/textfield.js +0 -143
- package/components/iqr-form/fields/textfield.js.map +0 -1
- package/components/iqr-form/fields/timePicker.d.ts +0 -10
- package/components/iqr-form/fields/timePicker.js +0 -49
- package/components/iqr-form/fields/timePicker.js.map +0 -1
- package/components/iqr-form/index.d.ts +0 -7
- package/components/iqr-form/index.js +0 -147
- package/components/iqr-form/index.js.map +0 -1
- package/components/iqr-form/legacy/Content.d.ts +0 -28
- package/components/iqr-form/legacy/Content.js +0 -30
- package/components/iqr-form/legacy/Content.js.map +0 -1
- package/components/iqr-form/legacy/Data.d.ts +0 -14
- package/components/iqr-form/legacy/Data.js +0 -21
- package/components/iqr-form/legacy/Data.js.map +0 -1
- package/components/iqr-form/legacy/Editor.d.ts +0 -34
- package/components/iqr-form/legacy/Editor.js +0 -19
- package/components/iqr-form/legacy/Editor.js.map +0 -1
- package/components/iqr-form/legacy/FormColumn.d.ts +0 -18
- package/components/iqr-form/legacy/FormColumn.js +0 -10
- package/components/iqr-form/legacy/FormColumn.js.map +0 -1
- package/components/iqr-form/legacy/FormDataOption.d.ts +0 -16
- package/components/iqr-form/legacy/FormDataOption.js +0 -21
- package/components/iqr-form/legacy/FormDataOption.js.map +0 -1
- package/components/iqr-form/legacy/FormLayout.d.ts +0 -25
- package/components/iqr-form/legacy/FormLayout.js +0 -10
- package/components/iqr-form/legacy/FormLayout.js.map +0 -1
- package/components/iqr-form/legacy/FormLayoutData.d.ts +0 -42
- package/components/iqr-form/legacy/FormLayoutData.js +0 -10
- package/components/iqr-form/legacy/FormLayoutData.js.map +0 -1
- package/components/iqr-form/legacy/FormPlanning.d.ts +0 -22
- package/components/iqr-form/legacy/FormPlanning.js +0 -21
- package/components/iqr-form/legacy/FormPlanning.js.map +0 -1
- package/components/iqr-form/legacy/FormSection.d.ts +0 -19
- package/components/iqr-form/legacy/FormSection.js +0 -10
- package/components/iqr-form/legacy/FormSection.js.map +0 -1
- package/components/iqr-form/legacy/Formula.d.ts +0 -27
- package/components/iqr-form/legacy/Formula.js +0 -32
- package/components/iqr-form/legacy/Formula.js.map +0 -1
- package/components/iqr-form/legacy/GuiCode.d.ts +0 -16
- package/components/iqr-form/legacy/GuiCode.js +0 -21
- package/components/iqr-form/legacy/GuiCode.js.map +0 -1
- package/components/iqr-form/legacy/GuiCodeType.d.ts +0 -15
- package/components/iqr-form/legacy/GuiCodeType.js +0 -21
- package/components/iqr-form/legacy/GuiCodeType.js.map +0 -1
- package/components/iqr-form/legacy/Suggest.d.ts +0 -19
- package/components/iqr-form/legacy/Suggest.js +0 -21
- package/components/iqr-form/legacy/Suggest.js.map +0 -1
- package/components/iqr-form/legacy/Tag.d.ts +0 -16
- package/components/iqr-form/legacy/Tag.js +0 -21
- package/components/iqr-form/legacy/Tag.js.map +0 -1
- package/components/iqr-form/model/index.d.ts +0 -96
- package/components/iqr-form/model/index.js +0 -120
- package/components/iqr-form/model/index.js.map +0 -1
- package/components/iqr-form/renderer/cards.d.ts +0 -2
- package/components/iqr-form/renderer/cards.js +0 -55
- package/components/iqr-form/renderer/cards.js.map +0 -1
- package/components/iqr-form/renderer/form.d.ts +0 -2
- package/components/iqr-form/renderer/form.js +0 -93
- package/components/iqr-form/renderer/form.js.map +0 -1
- package/components/iqr-form/renderer/index.d.ts +0 -6
- package/components/iqr-form/renderer/index.js.map +0 -1
- package/components/iqr-form/utils.d.ts +0 -5
- package/components/iqr-form/utils.js +0 -91
- package/components/iqr-form/utils.js.map +0 -1
- package/components/iqr-form-loader/fieldsValuesProviders.d.ts +0 -13
- package/components/iqr-form-loader/fieldsValuesProviders.js +0 -49
- package/components/iqr-form-loader/fieldsValuesProviders.js.map +0 -1
- package/components/iqr-form-loader/formValuesContainer.d.ts +0 -33
- package/components/iqr-form-loader/formValuesContainer.js +0 -111
- package/components/iqr-form-loader/formValuesContainer.js.map +0 -1
- package/components/iqr-form-loader/index.d.ts +0 -3
- package/components/iqr-form-loader/index.js.map +0 -1
- package/components/iqr-form-loader/models.d.ts +0 -14
- package/components/iqr-form-loader/models.js.map +0 -1
- package/components/iqr-text-field/index.d.ts +0 -26
- package/components/iqr-text-field/index.js +0 -1242
- package/components/iqr-text-field/index.js.map +0 -1
- package/components/iqr-text-field/plugin/caret-fix-plugin.js.map +0 -1
- package/components/iqr-text-field/plugin/has-content-class-plugin.js.map +0 -1
- package/components/iqr-text-field/plugin/mask-plugin.js.map +0 -1
- package/components/iqr-text-field/plugin/regexp-plugin.js.map +0 -1
- package/components/iqr-text-field/prosemirror-commands.js.map +0 -1
- package/components/iqr-text-field/prosemirror-utils.js.map +0 -1
- package/components/iqr-text-field/schema/common-marks.js.map +0 -1
- package/components/iqr-text-field/schema/date-time-schema.js.map +0 -1
- package/components/iqr-text-field/schema/decimal-schema.js.map +0 -1
- package/components/iqr-text-field/schema/index.d.ts +0 -11
- package/components/iqr-text-field/schema/index.js.map +0 -1
- package/components/iqr-text-field/schema/markdown-schema.js.map +0 -1
- package/components/iqr-text-field/schema/measure-schema.d.ts +0 -3
- package/components/iqr-text-field/schema/measure-schema.js +0 -36
- package/components/iqr-text-field/schema/measure-schema.js.map +0 -1
- package/components/iqr-text-field/schema/token-schema.js.map +0 -1
- package/components/iqr-text-field/schema/utils.js.map +0 -1
- package/components/iqr-text-field/selection-companion.js.map +0 -1
- package/components/iqr-text-field/styles/paths.js.map +0 -1
- package/components/iqr-text-field/suggestion-palette.js.map +0 -1
- /package/components/{iqr-form → icure-form}/renderer/index.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/plugin/caret-fix-plugin.d.ts +0 -0
- /package/components/{iqr-text-field → icure-text-field}/plugin/caret-fix-plugin.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/plugin/has-content-class-plugin.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/plugin/mask-plugin.d.ts +0 -0
- /package/components/{iqr-text-field → icure-text-field}/plugin/mask-plugin.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/plugin/regexp-plugin.d.ts +0 -0
- /package/components/{iqr-text-field → icure-text-field}/plugin/regexp-plugin.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/prosemirror-commands.d.ts +0 -0
- /package/components/{iqr-text-field → icure-text-field}/prosemirror-commands.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/prosemirror-utils.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/schema/common-marks.d.ts +0 -0
- /package/components/{iqr-text-field → icure-text-field}/schema/common-marks.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/schema/date-time-schema.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/schema/decimal-schema.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/schema/markdown-schema.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/schema/utils.d.ts +0 -0
- /package/components/{iqr-text-field → icure-text-field}/schema/utils.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/selection-companion.d.ts +0 -0
- /package/components/{iqr-text-field → icure-text-field}/selection-companion.js +0 -0
- /package/components/{iqr-text-field → icure-text-field}/suggestion-palette.js +0 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* For a sorted input, counting the number of unique values
|
|
5
|
+
* is possible in constant time and constant memory. This is
|
|
6
|
+
* a simple implementation of the algorithm.
|
|
7
|
+
*
|
|
8
|
+
* Values are compared with `===`, so objects and non-primitive objects
|
|
9
|
+
* are not handled in any special way.
|
|
10
|
+
*
|
|
11
|
+
* @param {Array<*>} x an array of any kind of value
|
|
12
|
+
* @returns {number} count of unique values
|
|
13
|
+
* @example
|
|
14
|
+
* uniqueCountSorted([1, 2, 3]); // => 3
|
|
15
|
+
* uniqueCountSorted([1, 1, 1]); // => 1
|
|
16
|
+
*/
|
|
17
|
+
function uniqueCountSorted(x) {
|
|
18
|
+
let uniqueValueCount = 0, lastSeenValue = undefined;
|
|
19
|
+
for (let i = 0; i < x.length; i++) {
|
|
20
|
+
if (i === 0 || x[i] !== lastSeenValue) {
|
|
21
|
+
lastSeenValue = x[i];
|
|
22
|
+
uniqueValueCount++;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return uniqueValueCount;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Sort an array of numbers by their numeric value, ensuring that the
|
|
29
|
+
* array is not changed in place.
|
|
30
|
+
*
|
|
31
|
+
* This is necessary because the default behavior of .sort
|
|
32
|
+
* in JavaScript is to sort arrays as string values
|
|
33
|
+
*
|
|
34
|
+
* [1, 10, 12, 102, 20].sort()
|
|
35
|
+
* // output
|
|
36
|
+
* [1, 10, 102, 12, 20]
|
|
37
|
+
*
|
|
38
|
+
* @param {Array<number>} x input array
|
|
39
|
+
* @return {Array<number>} sorted array
|
|
40
|
+
* @private
|
|
41
|
+
* @example
|
|
42
|
+
* numericSort([3, 2, 1]) // => [1, 2, 3]
|
|
43
|
+
*/
|
|
44
|
+
function numericSort(x) {
|
|
45
|
+
return (x
|
|
46
|
+
// ensure the array is not changed in-place
|
|
47
|
+
.slice()
|
|
48
|
+
// comparator function that treats input as numeric
|
|
49
|
+
.sort(function (a, b) {
|
|
50
|
+
return a - b;
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a new column x row matrix.
|
|
55
|
+
*
|
|
56
|
+
* @private
|
|
57
|
+
* @param {number} span
|
|
58
|
+
* @param {number} rows
|
|
59
|
+
* @return {Array<Array<number>>} matrix
|
|
60
|
+
* @example
|
|
61
|
+
* makeMatrix(10, 10);
|
|
62
|
+
*/
|
|
63
|
+
function makeMatrix(span, rows) {
|
|
64
|
+
const matrix = [];
|
|
65
|
+
for (let i = 0; i < span; i++) {
|
|
66
|
+
const column = [];
|
|
67
|
+
for (let j = 0; j < rows; j++) {
|
|
68
|
+
column.push(0);
|
|
69
|
+
}
|
|
70
|
+
matrix.push(column);
|
|
71
|
+
}
|
|
72
|
+
return matrix;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Generates incrementally computed values based on the sums and sums of
|
|
76
|
+
* squares for the data array
|
|
77
|
+
*
|
|
78
|
+
* @private
|
|
79
|
+
* @param {number} j
|
|
80
|
+
* @param {number} i
|
|
81
|
+
* @param {Array<number>} sums
|
|
82
|
+
* @param {Array<number>} sumsOfSquares
|
|
83
|
+
* @return {number}
|
|
84
|
+
* @example
|
|
85
|
+
* ssq(0, 1, [-1, 0, 2], [1, 1, 5]);
|
|
86
|
+
*/
|
|
87
|
+
function ssq(j, i, sums, sumsOfSquares) {
|
|
88
|
+
let sji; // s(j, i)
|
|
89
|
+
if (j > 0) {
|
|
90
|
+
const muji = (sums[i] - sums[j - 1]) / (i - j + 1); // mu(j, i)
|
|
91
|
+
sji = sumsOfSquares[i] - sumsOfSquares[j - 1] - (i - j + 1) * muji * muji;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
sji = sumsOfSquares[i] - (sums[i] * sums[i]) / (i + 1);
|
|
95
|
+
}
|
|
96
|
+
if (sji < 0) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
return sji;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Function that recursively divides and conquers computations
|
|
103
|
+
* for cluster j
|
|
104
|
+
*
|
|
105
|
+
* @private
|
|
106
|
+
* @param {number} iMin Minimum index in cluster to be computed
|
|
107
|
+
* @param {number} iMax Maximum index in cluster to be computed
|
|
108
|
+
* @param {number} cluster Index of the cluster currently being computed
|
|
109
|
+
* @param {Array<Array<number>>} matrix
|
|
110
|
+
* @param {Array<Array<number>>} backtrackMatrix
|
|
111
|
+
* @param {Array<number>} sums
|
|
112
|
+
* @param {Array<number>} sumsOfSquares
|
|
113
|
+
*/
|
|
114
|
+
function fillMatrixColumn(iMin, iMax, cluster, matrix, backtrackMatrix, sums, sumsOfSquares) {
|
|
115
|
+
if (iMin > iMax) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Start at midpoint between iMin and iMax
|
|
119
|
+
const i = Math.floor((iMin + iMax) / 2);
|
|
120
|
+
matrix[cluster][i] = matrix[cluster - 1][i - 1];
|
|
121
|
+
backtrackMatrix[cluster][i] = i;
|
|
122
|
+
let jlow = cluster; // the lower end for j
|
|
123
|
+
if (iMin > cluster) {
|
|
124
|
+
jlow = Math.max(jlow, backtrackMatrix[cluster][iMin - 1] || 0);
|
|
125
|
+
}
|
|
126
|
+
jlow = Math.max(jlow, backtrackMatrix[cluster - 1][i] || 0);
|
|
127
|
+
let jhigh = i - 1; // the upper end for j
|
|
128
|
+
if (iMax < matrix[0].length - 1) {
|
|
129
|
+
jhigh = Math.min(jhigh, backtrackMatrix[cluster][iMax + 1] || 0);
|
|
130
|
+
}
|
|
131
|
+
let sji;
|
|
132
|
+
let sjlowi;
|
|
133
|
+
let ssqjlow;
|
|
134
|
+
let ssqj;
|
|
135
|
+
for (let j = jhigh; j >= jlow; --j) {
|
|
136
|
+
sji = ssq(j, i, sums, sumsOfSquares);
|
|
137
|
+
if (sji + matrix[cluster - 1][jlow - 1] >= matrix[cluster][i]) {
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
// Examine the lower bound of the cluster border
|
|
141
|
+
sjlowi = ssq(jlow, i, sums, sumsOfSquares);
|
|
142
|
+
ssqjlow = sjlowi + matrix[cluster - 1][jlow - 1];
|
|
143
|
+
if (ssqjlow < matrix[cluster][i]) {
|
|
144
|
+
// Shrink the lower bound
|
|
145
|
+
matrix[cluster][i] = ssqjlow;
|
|
146
|
+
backtrackMatrix[cluster][i] = jlow;
|
|
147
|
+
}
|
|
148
|
+
jlow++;
|
|
149
|
+
ssqj = sji + matrix[cluster - 1][j - 1];
|
|
150
|
+
if (ssqj < matrix[cluster][i]) {
|
|
151
|
+
matrix[cluster][i] = ssqj;
|
|
152
|
+
backtrackMatrix[cluster][i] = j;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
fillMatrixColumn(iMin, i - 1, cluster, matrix, backtrackMatrix, sums, sumsOfSquares);
|
|
156
|
+
fillMatrixColumn(i + 1, iMax, cluster, matrix, backtrackMatrix, sums, sumsOfSquares);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Initializes the main matrices used in Ckmeans and kicks
|
|
160
|
+
* off the divide and conquer cluster computation strategy
|
|
161
|
+
*
|
|
162
|
+
* @private
|
|
163
|
+
* @param {Array<number>} data sorted array of values
|
|
164
|
+
* @param {Array<Array<number>>} matrix
|
|
165
|
+
* @param {Array<Array<number>>} backtrackMatrix
|
|
166
|
+
*/
|
|
167
|
+
function fillMatrices(data, matrix, backtrackMatrix) {
|
|
168
|
+
const nValues = matrix[0].length;
|
|
169
|
+
// Shift values by the median to improve numeric stability
|
|
170
|
+
const shift = data[Math.floor(nValues / 2)];
|
|
171
|
+
// Cumulative sum and cumulative sum of squares for all values in data array
|
|
172
|
+
const sums = [];
|
|
173
|
+
const sumsOfSquares = [];
|
|
174
|
+
// Initialize first column in matrix & backtrackMatrix
|
|
175
|
+
for (let i = 0, shiftedValue; i < nValues; ++i) {
|
|
176
|
+
shiftedValue = data[i] - shift;
|
|
177
|
+
if (i === 0) {
|
|
178
|
+
sums.push(shiftedValue);
|
|
179
|
+
sumsOfSquares.push(shiftedValue * shiftedValue);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
sums.push(sums[i - 1] + shiftedValue);
|
|
183
|
+
sumsOfSquares.push(sumsOfSquares[i - 1] + shiftedValue * shiftedValue);
|
|
184
|
+
}
|
|
185
|
+
// Initialize for cluster = 0
|
|
186
|
+
matrix[0][i] = ssq(0, i, sums, sumsOfSquares);
|
|
187
|
+
backtrackMatrix[0][i] = 0;
|
|
188
|
+
}
|
|
189
|
+
// Initialize the rest of the span
|
|
190
|
+
let iMin;
|
|
191
|
+
for (let cluster = 1; cluster < matrix.length; ++cluster) {
|
|
192
|
+
if (cluster < matrix.length - 1) {
|
|
193
|
+
iMin = cluster;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// No need to compute matrix[K-1][0] ... matrix[K-1][N-2]
|
|
197
|
+
iMin = nValues - 1;
|
|
198
|
+
}
|
|
199
|
+
fillMatrixColumn(iMin, nValues - 1, cluster, matrix, backtrackMatrix, sums, sumsOfSquares);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Ckmeans clustering is an improvement on heuristic-based clustering
|
|
204
|
+
* approaches like Jenks. The algorithm was developed in
|
|
205
|
+
* [Haizhou Wang and Mingzhou Song](http://journal.r-project.org/archive/2011-2/RJournal_2011-2_Wang+Song.pdf)
|
|
206
|
+
* as a [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming) approach
|
|
207
|
+
* to the problem of clustering numeric data into groups with the least
|
|
208
|
+
* within-group sum-of-squared-deviations.
|
|
209
|
+
*
|
|
210
|
+
* Minimizing the difference within groups - what Wang & Song refer to as
|
|
211
|
+
* `withinss`, or within sum-of-squares, means that groups are optimally
|
|
212
|
+
* homogenous within and the data is split into representative groups.
|
|
213
|
+
* This is very useful for visualization, where you may want to represent
|
|
214
|
+
* a continuous variable in discrete color or style groups. This function
|
|
215
|
+
* can provide groups that emphasize differences between data.
|
|
216
|
+
*
|
|
217
|
+
* Being a dynamic approach, this algorithm is based on two matrices that
|
|
218
|
+
* store incrementally-computed values for squared deviations and backtracking
|
|
219
|
+
* indexes.
|
|
220
|
+
*
|
|
221
|
+
* This implementation is based on Ckmeans 3.4.6, which introduced a new divide
|
|
222
|
+
* and conquer approach that improved runtime from O(kn^2) to O(kn log(n)).
|
|
223
|
+
*
|
|
224
|
+
* Unlike the [original implementation](https://cran.r-project.org/web/packages/Ckmeans.1d.dp/index.html),
|
|
225
|
+
* this implementation does not include any code to automatically determine
|
|
226
|
+
* the optimal number of clusters: this information needs to be explicitly
|
|
227
|
+
* provided.
|
|
228
|
+
*
|
|
229
|
+
* ### References
|
|
230
|
+
* _Ckmeans.1d.dp: Optimal k-means Clustering in One Dimension by Dynamic
|
|
231
|
+
* Programming_ Haizhou Wang and Mingzhou Song ISSN 2073-4859
|
|
232
|
+
*
|
|
233
|
+
* from The R Journal Vol. 3/2, December 2011
|
|
234
|
+
* @param {Array<number>} x input data, as an array of number values
|
|
235
|
+
* @param {number} nClusters number of desired classes. This cannot be
|
|
236
|
+
* greater than the number of values in the data array.
|
|
237
|
+
* @returns {Array<Array<number>>} clustered input
|
|
238
|
+
* @throws {Error} if the number of requested clusters is higher than the size of the data
|
|
239
|
+
* @example
|
|
240
|
+
* ckmeans([-1, 2, -1, 2, 4, 5, 6, -1, 2, -1], 3);
|
|
241
|
+
* // The input, clustered into groups of similar numbers.
|
|
242
|
+
* //= [[-1, -1, -1, -1], [2, 2, 2], [4, 5, 6]]);
|
|
243
|
+
*/
|
|
244
|
+
const ckmeans = (x, nClusters) => {
|
|
245
|
+
if (nClusters > x.length) {
|
|
246
|
+
throw new Error('cannot generate more classes than there are data values');
|
|
247
|
+
}
|
|
248
|
+
const sorted = numericSort(x);
|
|
249
|
+
// we'll use this as the maximum number of clusters
|
|
250
|
+
const uniqueCount = uniqueCountSorted(sorted);
|
|
251
|
+
// if all of the input values are identical, there's one cluster
|
|
252
|
+
// with all of the input in it.
|
|
253
|
+
if (uniqueCount === 1) {
|
|
254
|
+
return [sorted];
|
|
255
|
+
}
|
|
256
|
+
// named 'S' originally
|
|
257
|
+
const matrix = makeMatrix(nClusters, sorted.length);
|
|
258
|
+
// named 'J' originally
|
|
259
|
+
const backtrackMatrix = makeMatrix(nClusters, sorted.length);
|
|
260
|
+
// This is a dynamic programming way to solve the problem of minimizing
|
|
261
|
+
// within-cluster sum of squares. It's similar to linear regression
|
|
262
|
+
// in this way, and this calculation incrementally computes the
|
|
263
|
+
// sum of squares that are later read.
|
|
264
|
+
fillMatrices(sorted, matrix, backtrackMatrix);
|
|
265
|
+
// The real work of Ckmeans clustering happens in the matrix generation:
|
|
266
|
+
// the generated matrices encode all possible clustering combinations, and
|
|
267
|
+
// once they're generated we can solve for the best clustering groups
|
|
268
|
+
// very quickly.
|
|
269
|
+
const clusters = [];
|
|
270
|
+
let clusterRight = backtrackMatrix[0].length - 1;
|
|
271
|
+
// Backtrack the clusters from the dynamic programming matrix. This
|
|
272
|
+
// starts at the bottom-right corner of the matrix (if the top-left is 0, 0),
|
|
273
|
+
// and moves the cluster target with the loop.
|
|
274
|
+
for (let cluster = backtrackMatrix.length - 1; cluster >= 0; cluster--) {
|
|
275
|
+
const clusterLeft = backtrackMatrix[cluster][clusterRight];
|
|
276
|
+
// fill the cluster from the sorted input by taking a slice of the
|
|
277
|
+
// array. the backtrack matrix makes this easy - it stores the
|
|
278
|
+
// indexes where the cluster should start and end.
|
|
279
|
+
clusters[cluster] = sorted.slice(clusterLeft, clusterRight + 1);
|
|
280
|
+
if (cluster > 0) {
|
|
281
|
+
clusterRight = clusterLeft - 1;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return clusters;
|
|
285
|
+
};
|
|
286
|
+
exports.default = ckmeans;
|
|
287
|
+
//# sourceMappingURL=ckmeans.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ckmeans.js","sourceRoot":"","sources":["../../tmp/conversion/ckmeans.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * For a sorted input, counting the number of unique values\n * is possible in constant time and constant memory. This is\n * a simple implementation of the algorithm.\n *\n * Values are compared with `===`, so objects and non-primitive objects\n * are not handled in any special way.\n *\n * @param {Array<*>} x an array of any kind of value\n * @returns {number} count of unique values\n * @example\n * uniqueCountSorted([1, 2, 3]); // => 3\n * uniqueCountSorted([1, 1, 1]); // => 1\n */\nfunction uniqueCountSorted(x: any[]) {\n\tlet uniqueValueCount = 0,\n\t\tlastSeenValue = undefined\n\tfor (let i = 0; i < x.length; i++) {\n\t\tif (i === 0 || x[i] !== lastSeenValue) {\n\t\t\tlastSeenValue = x[i]\n\t\t\tuniqueValueCount++\n\t\t}\n\t}\n\treturn uniqueValueCount\n}\n\n/**\n * Sort an array of numbers by their numeric value, ensuring that the\n * array is not changed in place.\n *\n * This is necessary because the default behavior of .sort\n * in JavaScript is to sort arrays as string values\n *\n * [1, 10, 12, 102, 20].sort()\n * // output\n * [1, 10, 102, 12, 20]\n *\n * @param {Array<number>} x input array\n * @return {Array<number>} sorted array\n * @private\n * @example\n * numericSort([3, 2, 1]) // => [1, 2, 3]\n */\nfunction numericSort(x: number[]): number[] {\n\treturn (\n\t\tx\n\t\t\t// ensure the array is not changed in-place\n\t\t\t.slice()\n\t\t\t// comparator function that treats input as numeric\n\t\t\t.sort(function (a, b) {\n\t\t\t\treturn a - b\n\t\t\t})\n\t)\n}\n\n/**\n * Create a new column x row matrix.\n *\n * @private\n * @param {number} span\n * @param {number} rows\n * @return {Array<Array<number>>} matrix\n * @example\n * makeMatrix(10, 10);\n */\nfunction makeMatrix(span: number, rows: number) {\n\tconst matrix = []\n\tfor (let i = 0; i < span; i++) {\n\t\tconst column = []\n\t\tfor (let j = 0; j < rows; j++) {\n\t\t\tcolumn.push(0)\n\t\t}\n\t\tmatrix.push(column)\n\t}\n\treturn matrix\n}\n\n/**\n * Generates incrementally computed values based on the sums and sums of\n * squares for the data array\n *\n * @private\n * @param {number} j\n * @param {number} i\n * @param {Array<number>} sums\n * @param {Array<number>} sumsOfSquares\n * @return {number}\n * @example\n * ssq(0, 1, [-1, 0, 2], [1, 1, 5]);\n */\nfunction ssq(j: number, i: number, sums: number[], sumsOfSquares: number[]) {\n\tlet sji // s(j, i)\n\tif (j > 0) {\n\t\tconst muji = (sums[i] - sums[j - 1]) / (i - j + 1) // mu(j, i)\n\t\tsji = sumsOfSquares[i] - sumsOfSquares[j - 1] - (i - j + 1) * muji * muji\n\t} else {\n\t\tsji = sumsOfSquares[i] - (sums[i] * sums[i]) / (i + 1)\n\t}\n\tif (sji < 0) {\n\t\treturn 0\n\t}\n\treturn sji\n}\n\n/**\n * Function that recursively divides and conquers computations\n * for cluster j\n *\n * @private\n * @param {number} iMin Minimum index in cluster to be computed\n * @param {number} iMax Maximum index in cluster to be computed\n * @param {number} cluster Index of the cluster currently being computed\n * @param {Array<Array<number>>} matrix\n * @param {Array<Array<number>>} backtrackMatrix\n * @param {Array<number>} sums\n * @param {Array<number>} sumsOfSquares\n */\nfunction fillMatrixColumn(iMin: number, iMax: number, cluster: number, matrix: number[][], backtrackMatrix: number[][], sums: number[], sumsOfSquares: number[]) {\n\tif (iMin > iMax) {\n\t\treturn\n\t}\n\n\t// Start at midpoint between iMin and iMax\n\tconst i = Math.floor((iMin + iMax) / 2)\n\n\tmatrix[cluster][i] = matrix[cluster - 1][i - 1]\n\tbacktrackMatrix[cluster][i] = i\n\n\tlet jlow = cluster // the lower end for j\n\n\tif (iMin > cluster) {\n\t\tjlow = Math.max(jlow, backtrackMatrix[cluster][iMin - 1] || 0)\n\t}\n\tjlow = Math.max(jlow, backtrackMatrix[cluster - 1][i] || 0)\n\n\tlet jhigh = i - 1 // the upper end for j\n\tif (iMax < matrix[0].length - 1) {\n\t\tjhigh = Math.min(jhigh, backtrackMatrix[cluster][iMax + 1] || 0)\n\t}\n\n\tlet sji\n\tlet sjlowi\n\tlet ssqjlow\n\tlet ssqj\n\tfor (let j = jhigh; j >= jlow; --j) {\n\t\tsji = ssq(j, i, sums, sumsOfSquares)\n\n\t\tif (sji + matrix[cluster - 1][jlow - 1] >= matrix[cluster][i]) {\n\t\t\tbreak\n\t\t}\n\n\t\t// Examine the lower bound of the cluster border\n\t\tsjlowi = ssq(jlow, i, sums, sumsOfSquares)\n\n\t\tssqjlow = sjlowi + matrix[cluster - 1][jlow - 1]\n\n\t\tif (ssqjlow < matrix[cluster][i]) {\n\t\t\t// Shrink the lower bound\n\t\t\tmatrix[cluster][i] = ssqjlow\n\t\t\tbacktrackMatrix[cluster][i] = jlow\n\t\t}\n\t\tjlow++\n\n\t\tssqj = sji + matrix[cluster - 1][j - 1]\n\t\tif (ssqj < matrix[cluster][i]) {\n\t\t\tmatrix[cluster][i] = ssqj\n\t\t\tbacktrackMatrix[cluster][i] = j\n\t\t}\n\t}\n\n\tfillMatrixColumn(iMin, i - 1, cluster, matrix, backtrackMatrix, sums, sumsOfSquares)\n\tfillMatrixColumn(i + 1, iMax, cluster, matrix, backtrackMatrix, sums, sumsOfSquares)\n}\n\n/**\n * Initializes the main matrices used in Ckmeans and kicks\n * off the divide and conquer cluster computation strategy\n *\n * @private\n * @param {Array<number>} data sorted array of values\n * @param {Array<Array<number>>} matrix\n * @param {Array<Array<number>>} backtrackMatrix\n */\nfunction fillMatrices(data: number[], matrix: number[][], backtrackMatrix: number[][]) {\n\tconst nValues = matrix[0].length\n\n\t// Shift values by the median to improve numeric stability\n\tconst shift = data[Math.floor(nValues / 2)]\n\n\t// Cumulative sum and cumulative sum of squares for all values in data array\n\tconst sums = [] as number[]\n\tconst sumsOfSquares = [] as number[]\n\n\t// Initialize first column in matrix & backtrackMatrix\n\tfor (let i = 0, shiftedValue; i < nValues; ++i) {\n\t\tshiftedValue = data[i] - shift\n\t\tif (i === 0) {\n\t\t\tsums.push(shiftedValue)\n\t\t\tsumsOfSquares.push(shiftedValue * shiftedValue)\n\t\t} else {\n\t\t\tsums.push(sums[i - 1] + shiftedValue)\n\t\t\tsumsOfSquares.push(sumsOfSquares[i - 1] + shiftedValue * shiftedValue)\n\t\t}\n\n\t\t// Initialize for cluster = 0\n\t\tmatrix[0][i] = ssq(0, i, sums, sumsOfSquares)\n\t\tbacktrackMatrix[0][i] = 0\n\t}\n\n\t// Initialize the rest of the span\n\tlet iMin\n\tfor (let cluster = 1; cluster < matrix.length; ++cluster) {\n\t\tif (cluster < matrix.length - 1) {\n\t\t\tiMin = cluster\n\t\t} else {\n\t\t\t// No need to compute matrix[K-1][0] ... matrix[K-1][N-2]\n\t\t\tiMin = nValues - 1\n\t\t}\n\n\t\tfillMatrixColumn(iMin, nValues - 1, cluster, matrix, backtrackMatrix, sums, sumsOfSquares)\n\t}\n}\n\n/**\n * Ckmeans clustering is an improvement on heuristic-based clustering\n * approaches like Jenks. The algorithm was developed in\n * [Haizhou Wang and Mingzhou Song](http://journal.r-project.org/archive/2011-2/RJournal_2011-2_Wang+Song.pdf)\n * as a [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming) approach\n * to the problem of clustering numeric data into groups with the least\n * within-group sum-of-squared-deviations.\n *\n * Minimizing the difference within groups - what Wang & Song refer to as\n * `withinss`, or within sum-of-squares, means that groups are optimally\n * homogenous within and the data is split into representative groups.\n * This is very useful for visualization, where you may want to represent\n * a continuous variable in discrete color or style groups. This function\n * can provide groups that emphasize differences between data.\n *\n * Being a dynamic approach, this algorithm is based on two matrices that\n * store incrementally-computed values for squared deviations and backtracking\n * indexes.\n *\n * This implementation is based on Ckmeans 3.4.6, which introduced a new divide\n * and conquer approach that improved runtime from O(kn^2) to O(kn log(n)).\n *\n * Unlike the [original implementation](https://cran.r-project.org/web/packages/Ckmeans.1d.dp/index.html),\n * this implementation does not include any code to automatically determine\n * the optimal number of clusters: this information needs to be explicitly\n * provided.\n *\n * ### References\n * _Ckmeans.1d.dp: Optimal k-means Clustering in One Dimension by Dynamic\n * Programming_ Haizhou Wang and Mingzhou Song ISSN 2073-4859\n *\n * from The R Journal Vol. 3/2, December 2011\n * @param {Array<number>} x input data, as an array of number values\n * @param {number} nClusters number of desired classes. This cannot be\n * greater than the number of values in the data array.\n * @returns {Array<Array<number>>} clustered input\n * @throws {Error} if the number of requested clusters is higher than the size of the data\n * @example\n * ckmeans([-1, 2, -1, 2, 4, 5, 6, -1, 2, -1], 3);\n * // The input, clustered into groups of similar numbers.\n * //= [[-1, -1, -1, -1], [2, 2, 2], [4, 5, 6]]);\n */\nconst ckmeans = (x: number[], nClusters: number): number[][] => {\n\tif (nClusters > x.length) {\n\t\tthrow new Error('cannot generate more classes than there are data values')\n\t}\n\n\tconst sorted = numericSort(x)\n\t// we'll use this as the maximum number of clusters\n\tconst uniqueCount = uniqueCountSorted(sorted)\n\n\t// if all of the input values are identical, there's one cluster\n\t// with all of the input in it.\n\tif (uniqueCount === 1) {\n\t\treturn [sorted]\n\t}\n\n\t// named 'S' originally\n\tconst matrix = makeMatrix(nClusters, sorted.length)\n\t// named 'J' originally\n\tconst backtrackMatrix = makeMatrix(nClusters, sorted.length)\n\n\t// This is a dynamic programming way to solve the problem of minimizing\n\t// within-cluster sum of squares. It's similar to linear regression\n\t// in this way, and this calculation incrementally computes the\n\t// sum of squares that are later read.\n\tfillMatrices(sorted, matrix, backtrackMatrix)\n\n\t// The real work of Ckmeans clustering happens in the matrix generation:\n\t// the generated matrices encode all possible clustering combinations, and\n\t// once they're generated we can solve for the best clustering groups\n\t// very quickly.\n\tconst clusters = []\n\tlet clusterRight = backtrackMatrix[0].length - 1\n\n\t// Backtrack the clusters from the dynamic programming matrix. This\n\t// starts at the bottom-right corner of the matrix (if the top-left is 0, 0),\n\t// and moves the cluster target with the loop.\n\tfor (let cluster = backtrackMatrix.length - 1; cluster >= 0; cluster--) {\n\t\tconst clusterLeft = backtrackMatrix[cluster][clusterRight]\n\n\t\t// fill the cluster from the sorted input by taking a slice of the\n\t\t// array. the backtrack matrix makes this easy - it stores the\n\t\t// indexes where the cluster should start and end.\n\t\tclusters[cluster] = sorted.slice(clusterLeft, clusterRight + 1)\n\n\t\tif (cluster > 0) {\n\t\t\tclusterRight = clusterLeft - 1\n\t\t}\n\t}\n\n\treturn clusters\n}\n\nexport default ckmeans\n"]}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertLegacy = void 0;
|
|
4
|
+
const model_1 = require("../components/model");
|
|
5
|
+
const ckmeans_grouping_1 = require("./ckmeans-grouping");
|
|
6
|
+
function convertLegacy(form, formsLibrary) {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
const TOTAL_COLUMNS = 24;
|
|
9
|
+
const makeTextField = (formData, width, height) => { var _a; return new model_1.TextField((_a = formData.name) !== null && _a !== void 0 ? _a : '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined }); };
|
|
10
|
+
const makeItemsListField = (formData, width, height) => { var _a; return new model_1.ItemsListField((_a = formData.name) !== null && _a !== void 0 ? _a : '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined }); };
|
|
11
|
+
const makeTokenField = (formData, width, height) => { var _a; return new model_1.TokenField((_a = formData.name) !== null && _a !== void 0 ? _a : '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined }); };
|
|
12
|
+
const makeCheckBox = (formData, width, height) => { var _a, _b; return new model_1.CheckBox((_a = formData.name) !== null && _a !== void 0 ? _a : '', { shortLabel: formData.label, options: { [(_b = formData.label) !== null && _b !== void 0 ? _b : '']: formData.label }, span: width, rowSpan: height > 1 ? height : undefined }); };
|
|
13
|
+
const makeMeasureField = (formData, width, height) => { var _a; return new model_1.MeasureField((_a = formData.name) !== null && _a !== void 0 ? _a : '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined }); };
|
|
14
|
+
const makeNumberField = (formData, width, height) => { var _a; return new model_1.NumberField((_a = formData.name) !== null && _a !== void 0 ? _a : '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined }); };
|
|
15
|
+
const makeDateTimeField = (formData, width, height) => {
|
|
16
|
+
var _a, _b, _c;
|
|
17
|
+
return ((_a = formData.editor) === null || _a === void 0 ? void 0 : _a.displayTime)
|
|
18
|
+
? new model_1.DateTimePicker((_b = formData.name) !== null && _b !== void 0 ? _b : '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })
|
|
19
|
+
: new model_1.DatePicker((_c = formData.name) !== null && _c !== void 0 ? _c : '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined });
|
|
20
|
+
};
|
|
21
|
+
const makeDropdownField = (formData, width, height) => {
|
|
22
|
+
var _a, _b, _c;
|
|
23
|
+
return new model_1.DropdownField((_a = formData.name) !== null && _a !== void 0 ? _a : '', {
|
|
24
|
+
shortLabel: formData.label,
|
|
25
|
+
span: width,
|
|
26
|
+
options: ((_b = formData.editor) === null || _b === void 0 ? void 0 : _b.menuOptions)
|
|
27
|
+
? (_c = formData.editor) === null || _c === void 0 ? void 0 : _c.menuOptions.reduce((acc, v) => (Object.assign(Object.assign({}, acc), { [`LEGACY|${v}|1`]: v })), {})
|
|
28
|
+
: undefined,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
const makeSubForm = (formData, width, height) => {
|
|
32
|
+
var _a, _b, _c;
|
|
33
|
+
const subForms = (_b = (_a = formData.editor) === null || _a === void 0 ? void 0 : _a.optionalFormGuids) === null || _b === void 0 ? void 0 : _b.map((guid) => {
|
|
34
|
+
const subForm = formsLibrary.find((it) => it.guid === guid);
|
|
35
|
+
if (!subForm) {
|
|
36
|
+
throw new Error(`Cannot find subform ${guid}`);
|
|
37
|
+
}
|
|
38
|
+
return convertLegacy(subForm, formsLibrary);
|
|
39
|
+
});
|
|
40
|
+
return new model_1.Subform((_c = formData.name) !== null && _c !== void 0 ? _c : '', subForms.reduce((acc, sf) => (Object.assign(Object.assign({}, acc), { [sf.form]: sf })), {}), {
|
|
41
|
+
shortLabel: formData.label,
|
|
42
|
+
span: width,
|
|
43
|
+
rowSpan: height,
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const makeActionButton = (formData, width, height) => { var _a; return new model_1.ActionButton((_a = formData.name) !== null && _a !== void 0 ? _a : '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined }); };
|
|
47
|
+
// noinspection UnnecessaryLocalVariableJS
|
|
48
|
+
const translated = new model_1.Form((_a = (form.group ? `${form.group}/${form.name}` : form.name)) !== null && _a !== void 0 ? _a : 'Unknown', ((_b = form.sections) !== null && _b !== void 0 ? _b : []).map((section) => {
|
|
49
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
50
|
+
const fld = ((_a = section.formColumns) !== null && _a !== void 0 ? _a : []).flatMap((column) => { var _a; return (_a = column.formDataList) !== null && _a !== void 0 ? _a : []; });
|
|
51
|
+
const sortedList = fld.sort((a, b) => { var _a, _b, _c, _d; return ((_b = (_a = a.editor) === null || _a === void 0 ? void 0 : _a.top) !== null && _b !== void 0 ? _b : 0) - ((_d = (_c = b.editor) === null || _c === void 0 ? void 0 : _c.top) !== null && _d !== void 0 ? _d : 0); });
|
|
52
|
+
const rowClusters = (0, ckmeans_grouping_1.cluster)(fld.map((f) => { var _a, _b; return (_b = (_a = f.editor) === null || _a === void 0 ? void 0 : _a.top) !== null && _b !== void 0 ? _b : 0; }), 5, 16);
|
|
53
|
+
const rows = rowClusters.clusters;
|
|
54
|
+
const intraCentroids = rowClusters.centroids.map((v, idx, centroids) => (idx > 0 ? v - centroids[idx - 1] : 0)).filter((x) => x > 0);
|
|
55
|
+
const meanHeightWithOutliers = intraCentroids.reduce((sum, v) => v + sum, 0) / intraCentroids.length;
|
|
56
|
+
const intraCentroidsWithoutOutliers = intraCentroids.filter((x) => x < meanHeightWithOutliers * 2);
|
|
57
|
+
const meanHeight = intraCentroidsWithoutOutliers.reduce((sum, v) => v + sum, 0) / intraCentroidsWithoutOutliers.length;
|
|
58
|
+
const formDataClusters = sortedList
|
|
59
|
+
.reduce((cs, fd) => {
|
|
60
|
+
cs[rows.findIndex((c) => { var _a, _b; return c.includes((_b = (_a = fd.editor) === null || _a === void 0 ? void 0 : _a.top) !== null && _b !== void 0 ? _b : 0); })].push(fd);
|
|
61
|
+
return cs;
|
|
62
|
+
}, new Array(rows.length).fill(null).map(() => []))
|
|
63
|
+
.map((c) => c.sort((a, b) => { var _a, _b, _c, _d; return ((_b = (_a = a.editor) === null || _a === void 0 ? void 0 : _a.left) !== null && _b !== void 0 ? _b : 0) - ((_d = (_c = b.editor) === null || _c === void 0 ? void 0 : _c.left) !== null && _d !== void 0 ? _d : 0); }));
|
|
64
|
+
const leftMostField = sortedList.filter((f) => !f.subForm).reduce((a, b) => { var _a, _b, _c, _d; return (((_b = (_a = a.editor) === null || _a === void 0 ? void 0 : _a.left) !== null && _b !== void 0 ? _b : 0) < ((_d = (_c = b.editor) === null || _c === void 0 ? void 0 : _c.left) !== null && _d !== void 0 ? _d : 0) ? a : b); });
|
|
65
|
+
const rightMostField = sortedList
|
|
66
|
+
.filter((f) => !f.subForm)
|
|
67
|
+
.reduce((a, b) => { var _a, _b, _c, _d, _e, _f, _g, _h; return (((_b = (_a = a.editor) === null || _a === void 0 ? void 0 : _a.left) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = a.editor) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : 0) < ((_f = (_e = b.editor) === null || _e === void 0 ? void 0 : _e.left) !== null && _f !== void 0 ? _f : 0) + ((_h = (_g = b.editor) === null || _g === void 0 ? void 0 : _g.width) !== null && _h !== void 0 ? _h : 0) ? b : a); });
|
|
68
|
+
const leftSide = (_c = (_b = leftMostField.editor) === null || _b === void 0 ? void 0 : _b.left) !== null && _c !== void 0 ? _c : 0;
|
|
69
|
+
const formWidth = ((_e = (_d = rightMostField === null || rightMostField === void 0 ? void 0 : rightMostField.editor) === null || _d === void 0 ? void 0 : _d.left) !== null && _e !== void 0 ? _e : 0) + ((_g = (_f = rightMostField === null || rightMostField === void 0 ? void 0 : rightMostField.editor) === null || _f === void 0 ? void 0 : _f.width) !== null && _g !== void 0 ? _g : 1024) - leftSide;
|
|
70
|
+
const interColumnsDistance = formWidth / TOTAL_COLUMNS;
|
|
71
|
+
const columns = (0, ckmeans_grouping_1.cluster)(fld.map((f) => { var _a, _b, _c, _d; return ((_b = (_a = f.editor) === null || _a === void 0 ? void 0 : _a.left) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = f.editor) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : 0) - leftSide; }), formWidth / (TOTAL_COLUMNS * 2), Math.ceil((formWidth !== null && formWidth !== void 0 ? formWidth : 1024) / (TOTAL_COLUMNS * 4)), Math.max(Math.min(TOTAL_COLUMNS, fld.length / 2), 1));
|
|
72
|
+
const columnsWidth = columns.centroids.map((v, idx, t) => { var _a; return v - ((_a = t[idx - 1]) !== null && _a !== void 0 ? _a : 0); });
|
|
73
|
+
const acc = columnsWidth.map(() => 1);
|
|
74
|
+
while (acc.reduce((s, v) => s + v, 0) < TOTAL_COLUMNS) {
|
|
75
|
+
const idx = acc.reduce((s, size, idx) => {
|
|
76
|
+
const diff = size * interColumnsDistance - columnsWidth[idx];
|
|
77
|
+
return diff < 0 && -diff > s[1] ? [idx, -diff] : s;
|
|
78
|
+
}, [undefined, 0]);
|
|
79
|
+
const selected = idx[0];
|
|
80
|
+
if (selected === undefined) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
acc[selected]++;
|
|
84
|
+
}
|
|
85
|
+
// noinspection UnnecessaryLocalVariableJS
|
|
86
|
+
const columnsRoundedWidth = acc;
|
|
87
|
+
const columnsAccumulatedWidth = columnsRoundedWidth.reduce((acc, v) => { var _a; return [...acc, ((_a = acc[acc.length - 1]) !== null && _a !== void 0 ? _a : 0) + v]; }, []);
|
|
88
|
+
const columnsAccumulatedWidthWithInterColumns = columnsAccumulatedWidth.map((v) => v * interColumnsDistance);
|
|
89
|
+
return new model_1.Section('Main', formDataClusters.flatMap((formDataRow) => {
|
|
90
|
+
const cols = formDataRow
|
|
91
|
+
.map((formData) => {
|
|
92
|
+
return columnsAccumulatedWidth[columnsAccumulatedWidthWithInterColumns.reduce(([idx, min], x, n) => {
|
|
93
|
+
var _a, _b, _c, _d;
|
|
94
|
+
const right = ((_b = (_a = formData.editor) === null || _a === void 0 ? void 0 : _a.left) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = formData.editor) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : 0) - leftSide;
|
|
95
|
+
return Math.abs(x - right) < min ? [n, Math.abs(x - right)] : [idx, min];
|
|
96
|
+
}, [0, 99999])[0]];
|
|
97
|
+
})
|
|
98
|
+
.map((x, idx, cols) => {
|
|
99
|
+
var _a, _b;
|
|
100
|
+
//Try to solve inverted positions in columns by adding or removing one column
|
|
101
|
+
const prev = (_a = cols[idx - 1]) !== null && _a !== void 0 ? _a : 0;
|
|
102
|
+
const next = (_b = cols[idx + 1]) !== null && _b !== void 0 ? _b : TOTAL_COLUMNS;
|
|
103
|
+
return x > prev + 1 && x >= next - 1 ? x - 1 : x === prev ? x + 1 : x;
|
|
104
|
+
});
|
|
105
|
+
const subRows = cols.reduce((acc, v, idx, cols) => {
|
|
106
|
+
var _a;
|
|
107
|
+
if (idx === 0) {
|
|
108
|
+
return [[[idx, v]]];
|
|
109
|
+
}
|
|
110
|
+
let row = 0;
|
|
111
|
+
while (row < acc.length && acc[row][acc[row].length - 1][1] > v) {
|
|
112
|
+
row++;
|
|
113
|
+
}
|
|
114
|
+
;
|
|
115
|
+
((_a = acc[row]) !== null && _a !== void 0 ? _a : (acc[row] = [])).push([idx, v]);
|
|
116
|
+
return acc;
|
|
117
|
+
}, []);
|
|
118
|
+
return subRows.flatMap((subRow) => {
|
|
119
|
+
const acc = subRow.map((x) => x[1]);
|
|
120
|
+
while (acc[acc.length - 1] < TOTAL_COLUMNS) {
|
|
121
|
+
const idx = acc.reduce(([minIdx, min], size, idx, columns) => {
|
|
122
|
+
const scenario = columns.map((x, cidx) => (cidx === idx ? x + 1 : x));
|
|
123
|
+
const penalty = scenario.reduce((acc, v) => {
|
|
124
|
+
var _a, _b, _c, _d;
|
|
125
|
+
const right = ((_b = (_a = formDataRow[subRow[idx][0]].editor) === null || _a === void 0 ? void 0 : _a.left) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = formDataRow[subRow[idx][0]].editor) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : 0) - leftSide;
|
|
126
|
+
return acc + Math.abs(v * interColumnsDistance - right);
|
|
127
|
+
}, 0);
|
|
128
|
+
return penalty < min ? [idx, penalty] : [minIdx, min];
|
|
129
|
+
}, [undefined, 999999]);
|
|
130
|
+
const selected = idx[0];
|
|
131
|
+
if (selected === undefined) {
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
for (let i = selected; i < acc.length; i++) {
|
|
135
|
+
acc[i]++;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const expandedCols = acc;
|
|
139
|
+
let idx = 0;
|
|
140
|
+
return subRow
|
|
141
|
+
.map(([idx]) => formDataRow[idx])
|
|
142
|
+
.map((formData, index) => {
|
|
143
|
+
var _a, _b, _c, _d, _e, _f;
|
|
144
|
+
const width = expandedCols[index] - idx;
|
|
145
|
+
idx += width;
|
|
146
|
+
return (_d = (_a = {
|
|
147
|
+
StringEditor: makeTextField,
|
|
148
|
+
CheckBoxEditor: makeCheckBox,
|
|
149
|
+
MeasureEditor: makeMeasureField,
|
|
150
|
+
NumberEditor: makeNumberField,
|
|
151
|
+
PopupMenuEditor: makeDropdownField,
|
|
152
|
+
DateTimeEditor: makeDateTimeField,
|
|
153
|
+
StringTableEditor: makeItemsListField,
|
|
154
|
+
TokenFieldEditor: makeTokenField,
|
|
155
|
+
SubFormEditor: makeSubForm,
|
|
156
|
+
ActionButton: makeActionButton,
|
|
157
|
+
})[(_c = (_b = formData.editor) === null || _b === void 0 ? void 0 : _b.key) !== null && _c !== void 0 ? _c : '']) === null || _d === void 0 ? void 0 : _d.call(_a, formData, width, Math.max(1, Math.floor(((_f = (_e = formData.editor) === null || _e === void 0 ? void 0 : _e.height) !== null && _f !== void 0 ? _f : 0) / meanHeight)));
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}));
|
|
161
|
+
}), form.guid);
|
|
162
|
+
return translated;
|
|
163
|
+
}
|
|
164
|
+
exports.convertLegacy = convertLegacy;
|
|
165
|
+
//# sourceMappingURL=icure-convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icure-convert.js","sourceRoot":"","sources":["../../tmp/conversion/icure-convert.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormLayout } from '@icure/api'\nimport {\n\tActionButton,\n\tCheckBox,\n\tDatePicker,\n\tDateTimePicker,\n\tDropdownField,\n\tForm,\n\tItemsListField,\n\tMeasureField,\n\tNumberField,\n\tSection,\n\tSubform,\n\tTextField,\n\tTokenField,\n} from '../components/model'\nimport { FormLayoutData } from '@icure/api/icc-api/model/FormLayoutData'\nimport { cluster } from './ckmeans-grouping'\n\nexport function convertLegacy(form: FormLayout, formsLibrary: FormLayout[]): Form {\n\tconst TOTAL_COLUMNS = 24\n\tconst makeTextField = (formData: FormLayoutData, width: number, height: number) =>\n\t\tnew TextField(formData.name ?? '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })\n\tconst makeItemsListField = (formData: FormLayoutData, width: number, height: number) =>\n\t\tnew ItemsListField(formData.name ?? '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })\n\tconst makeTokenField = (formData: FormLayoutData, width: number, height: number) =>\n\t\tnew TokenField(formData.name ?? '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })\n\tconst makeCheckBox = (formData: FormLayoutData, width: number, height: number) =>\n\t\tnew CheckBox(formData.name ?? '', { shortLabel: formData.label, options: { [formData.label ?? '']: formData.label }, span: width, rowSpan: height > 1 ? height : undefined })\n\tconst makeMeasureField = (formData: FormLayoutData, width: number, height: number) =>\n\t\tnew MeasureField(formData.name ?? '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })\n\tconst makeNumberField = (formData: FormLayoutData, width: number, height: number) =>\n\t\tnew NumberField(formData.name ?? '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })\n\tconst makeDateTimeField = (formData: FormLayoutData, width: number, height: number) =>\n\t\t(formData.editor as any)?.displayTime\n\t\t\t? new DateTimePicker(formData.name ?? '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })\n\t\t\t: new DatePicker(formData.name ?? '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })\n\n\tconst makeDropdownField = (formData: FormLayoutData, width: number, height: number) =>\n\t\tnew DropdownField(formData.name ?? '', {\n\t\t\tshortLabel: formData.label,\n\t\t\tspan: width,\n\t\t\toptions: (formData.editor as any)?.menuOptions\n\t\t\t\t? (formData.editor as any)?.menuOptions.reduce(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tacc: {\n\t\t\t\t\t\t\t\t[key: string]: unknown\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tv: string,\n\t\t\t\t\t\t) => ({ ...acc, [`LEGACY|${v}|1`]: v }),\n\t\t\t\t\t\t{},\n\t\t\t\t )\n\t\t\t\t: undefined,\n\t\t})\n\n\tconst makeSubForm = (formData: FormLayoutData, width: number, height: number) => {\n\t\tconst subForms = ((formData.editor as any)?.optionalFormGuids as string[])?.map((guid: string) => {\n\t\t\tconst subForm = formsLibrary.find((it) => it.guid === guid)\n\t\t\tif (!subForm) {\n\t\t\t\tthrow new Error(`Cannot find subform ${guid}`)\n\t\t\t}\n\t\t\treturn convertLegacy(subForm as FormLayout, formsLibrary)\n\t\t})\n\t\treturn new Subform(\n\t\t\tformData.name ?? '',\n\t\t\tsubForms.reduce((acc, sf) => ({ ...acc, [sf.form]: sf }), {}),\n\t\t\t{\n\t\t\t\tshortLabel: formData.label,\n\t\t\t\tspan: width,\n\t\t\t\trowSpan: height,\n\t\t\t},\n\t\t)\n\t}\n\n\tconst makeActionButton = (formData: FormLayoutData, width: number, height: number) =>\n\t\tnew ActionButton(formData.name ?? '', { shortLabel: formData.label, span: width, rowSpan: height > 1 ? height : undefined })\n\n\t// noinspection UnnecessaryLocalVariableJS\n\tconst translated = new Form(\n\t\t(form.group ? `${form.group}/${form.name}` : form.name) ?? 'Unknown',\n\t\t(form.sections ?? []).map((section) => {\n\t\t\tconst fld = (section.formColumns ?? []).flatMap((column) => column.formDataList ?? [])\n\t\t\tconst sortedList = fld.sort((a, b) => (a.editor?.top ?? 0) - (b.editor?.top ?? 0))\n\n\t\t\tconst rowClusters = cluster(\n\t\t\t\tfld.map((f) => f.editor?.top ?? 0),\n\t\t\t\t5,\n\t\t\t\t16,\n\t\t\t)\n\t\t\tconst rows = rowClusters.clusters\n\n\t\t\tconst intraCentroids = rowClusters.centroids.map((v, idx, centroids) => (idx > 0 ? v - centroids[idx - 1] : 0)).filter((x) => x > 0)\n\t\t\tconst meanHeightWithOutliers = intraCentroids.reduce((sum, v) => v + sum, 0) / intraCentroids.length\n\t\t\tconst intraCentroidsWithoutOutliers = intraCentroids.filter((x) => x < meanHeightWithOutliers * 2)\n\t\t\tconst meanHeight = intraCentroidsWithoutOutliers.reduce((sum, v) => v + sum, 0) / intraCentroidsWithoutOutliers.length\n\n\t\t\tconst formDataClusters = sortedList\n\t\t\t\t.reduce(\n\t\t\t\t\t(cs, fd) => {\n\t\t\t\t\t\tcs[rows.findIndex((c) => c.includes(fd.editor?.top ?? 0))].push(fd)\n\t\t\t\t\t\treturn cs\n\t\t\t\t\t},\n\t\t\t\t\tnew Array(rows.length).fill(null).map(() => [] as FormLayoutData[]),\n\t\t\t\t)\n\t\t\t\t.map((c) => c.sort((a, b) => (a.editor?.left ?? 0) - (b.editor?.left ?? 0)))\n\n\t\t\tconst leftMostField = sortedList.filter((f) => !f.subForm).reduce((a, b) => ((a.editor?.left ?? 0) < (b.editor?.left ?? 0) ? a : b))\n\t\t\tconst rightMostField = sortedList\n\t\t\t\t.filter((f) => !f.subForm)\n\t\t\t\t.reduce((a, b) => ((a.editor?.left ?? 0) + (a.editor?.width ?? 0) < (b.editor?.left ?? 0) + (b.editor?.width ?? 0) ? b : a))\n\n\t\t\tconst leftSide = leftMostField.editor?.left ?? 0\n\t\t\tconst formWidth = (rightMostField?.editor?.left ?? 0) + (rightMostField?.editor?.width ?? 1024) - leftSide\n\t\t\tconst interColumnsDistance = formWidth / TOTAL_COLUMNS\n\t\t\tconst columns = cluster(\n\t\t\t\tfld.map((f) => (f.editor?.left ?? 0) + (f.editor?.width ?? 0) - leftSide),\n\t\t\t\tformWidth / (TOTAL_COLUMNS * 2),\n\t\t\t\tMath.ceil((formWidth ?? 1024) / (TOTAL_COLUMNS * 4)),\n\t\t\t\tMath.max(Math.min(TOTAL_COLUMNS, fld.length / 2), 1),\n\t\t\t)\n\t\t\tconst columnsWidth = columns.centroids.map((v, idx, t) => v - (t[idx - 1] ?? 0))\n\n\t\t\tconst acc = columnsWidth.map(() => 1)\n\t\t\twhile (acc.reduce((s, v) => s + v, 0) < TOTAL_COLUMNS) {\n\t\t\t\tconst idx = acc.reduce(\n\t\t\t\t\t(s: [number | undefined, number], size: number, idx: number): [number | undefined, number] => {\n\t\t\t\t\t\tconst diff = size * interColumnsDistance - columnsWidth[idx]\n\t\t\t\t\t\treturn diff < 0 && -diff > s[1] ? [idx, -diff] : s\n\t\t\t\t\t},\n\t\t\t\t\t[undefined, 0],\n\t\t\t\t)\n\t\t\t\tconst selected = idx[0]\n\t\t\t\tif (selected === undefined) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tacc[selected]++\n\t\t\t}\n\t\t\t// noinspection UnnecessaryLocalVariableJS\n\t\t\tconst columnsRoundedWidth = acc\n\n\t\t\tconst columnsAccumulatedWidth = columnsRoundedWidth.reduce((acc, v) => [...acc, (acc[acc.length - 1] ?? 0) + v], [])\n\t\t\tconst columnsAccumulatedWidthWithInterColumns = columnsAccumulatedWidth.map((v) => v * interColumnsDistance)\n\n\t\t\treturn new Section(\n\t\t\t\t'Main',\n\t\t\t\tformDataClusters.flatMap((formDataRow: FormLayoutData[]) => {\n\t\t\t\t\tconst cols = formDataRow\n\t\t\t\t\t\t.map((formData: FormLayoutData) => {\n\t\t\t\t\t\t\treturn columnsAccumulatedWidth[\n\t\t\t\t\t\t\t\tcolumnsAccumulatedWidthWithInterColumns.reduce(\n\t\t\t\t\t\t\t\t\t([idx, min]: [number, number], x, n) => {\n\t\t\t\t\t\t\t\t\t\tconst right = (formData.editor?.left ?? 0) + (formData.editor?.width ?? 0) - leftSide\n\t\t\t\t\t\t\t\t\t\treturn Math.abs(x - right) < min ? [n, Math.abs(x - right)] : [idx, min]\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t[0, 99999],\n\t\t\t\t\t\t\t\t)[0]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.map((x, idx, cols) => {\n\t\t\t\t\t\t\t//Try to solve inverted positions in columns by adding or removing one column\n\t\t\t\t\t\t\tconst prev = cols[idx - 1] ?? 0\n\t\t\t\t\t\t\tconst next = cols[idx + 1] ?? TOTAL_COLUMNS\n\t\t\t\t\t\t\treturn x > prev + 1 && x >= next - 1 ? x - 1 : x === prev ? x + 1 : x\n\t\t\t\t\t\t})\n\t\t\t\t\tconst subRows = cols.reduce((acc, v, idx, cols) => {\n\t\t\t\t\t\tif (idx === 0) {\n\t\t\t\t\t\t\treturn [[[idx, v]]]\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet row = 0\n\t\t\t\t\t\twhile (row < acc.length && acc[row][acc[row].length - 1][1] > v) {\n\t\t\t\t\t\t\trow++\n\t\t\t\t\t\t}\n\t\t\t\t\t\t;(acc[row] ?? (acc[row] = [])).push([idx, v] as [number, number])\n\t\t\t\t\t\treturn acc\n\t\t\t\t\t}, [] as [number, number][][])\n\n\t\t\t\t\treturn subRows.flatMap((subRow) => {\n\t\t\t\t\t\tconst acc = subRow.map((x) => x[1])\n\t\t\t\t\t\twhile (acc[acc.length - 1] < TOTAL_COLUMNS) {\n\t\t\t\t\t\t\tconst idx = acc.reduce(\n\t\t\t\t\t\t\t\t([minIdx, min]: [number | undefined, number], size: number, idx: number, columns: number[]): [number | undefined, number] => {\n\t\t\t\t\t\t\t\t\tconst scenario = columns.map((x, cidx) => (cidx === idx ? x + 1 : x))\n\t\t\t\t\t\t\t\t\tconst penalty = scenario.reduce((acc, v) => {\n\t\t\t\t\t\t\t\t\t\tconst right = (formDataRow[subRow[idx][0]].editor?.left ?? 0) + (formDataRow[subRow[idx][0]].editor?.width ?? 0) - leftSide\n\t\t\t\t\t\t\t\t\t\treturn acc + Math.abs(v * interColumnsDistance - right)\n\t\t\t\t\t\t\t\t\t}, 0)\n\t\t\t\t\t\t\t\t\treturn penalty < min ? [idx, penalty] : [minIdx, min]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t[undefined, 999999],\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tconst selected = idx[0]\n\t\t\t\t\t\t\tif (selected === undefined) {\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor (let i = selected; i < acc.length; i++) {\n\t\t\t\t\t\t\t\tacc[i]++\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst expandedCols = acc\n\t\t\t\t\t\tlet idx = 0\n\t\t\t\t\t\treturn subRow\n\t\t\t\t\t\t\t.map(([idx]) => formDataRow[idx])\n\t\t\t\t\t\t\t.map((formData: FormLayoutData, index) => {\n\t\t\t\t\t\t\t\tconst width = expandedCols[index] - idx\n\t\t\t\t\t\t\t\tidx += width\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tStringEditor: makeTextField,\n\t\t\t\t\t\t\t\t\tCheckBoxEditor: makeCheckBox,\n\t\t\t\t\t\t\t\t\tMeasureEditor: makeMeasureField,\n\t\t\t\t\t\t\t\t\tNumberEditor: makeNumberField,\n\t\t\t\t\t\t\t\t\tPopupMenuEditor: makeDropdownField,\n\t\t\t\t\t\t\t\t\tDateTimeEditor: makeDateTimeField,\n\t\t\t\t\t\t\t\t\tStringTableEditor: makeItemsListField,\n\t\t\t\t\t\t\t\t\tTokenFieldEditor: makeTokenField,\n\t\t\t\t\t\t\t\t\tSubFormEditor: makeSubForm,\n\t\t\t\t\t\t\t\t\tActionButton: makeActionButton,\n\t\t\t\t\t\t\t\t}[formData.editor?.key ?? '']?.(formData, width, Math.max(1, Math.floor((formData.editor?.height ?? 0) / meanHeight)))\n\t\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t)\n\t\t}),\n\t\tform.guid,\n\t)\n\treturn translated\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './model';
|
package/generic/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./model"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../tmp/generic/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAuB","sourcesContent":["export * from './model'\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface VersionedData<T> {
|
|
2
|
+
[id: string]: Version<T>[];
|
|
3
|
+
}
|
|
4
|
+
export interface Version<T> {
|
|
5
|
+
revision: string | null;
|
|
6
|
+
modified?: number;
|
|
7
|
+
value: T;
|
|
8
|
+
}
|
|
9
|
+
export type ID = string;
|
|
10
|
+
/**
|
|
11
|
+
* FormValuesContainer is a readonly structure that provides and handle the values of a form.
|
|
12
|
+
*/
|
|
13
|
+
export interface FormValuesContainer<Value, Metadata> {
|
|
14
|
+
compute<T, S extends {
|
|
15
|
+
[key: string | symbol]: unknown;
|
|
16
|
+
}>(formula: string, sandbox?: S): T | undefined;
|
|
17
|
+
getLabel(): string;
|
|
18
|
+
getFormId(): string | undefined;
|
|
19
|
+
getValues(revisionsFilter: (id: string, history: Version<Metadata>[]) => (string | null)[]): VersionedData<Value>;
|
|
20
|
+
getMetadata(id: string, revisions: (string | null)[]): VersionedData<Metadata>;
|
|
21
|
+
getChildren(): FormValuesContainer<Value, Metadata>[];
|
|
22
|
+
setValue(label: string, language: string, data?: Value, id?: string, metadata?: Metadata): FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, ID>;
|
|
23
|
+
setMetadata(label: string, metadata: Metadata, id?: string): FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, ID>;
|
|
24
|
+
delete(serviceId: string): FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, void>;
|
|
25
|
+
addChild(anchorId: string, templateId: string, label: string): Promise<FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, FormValuesContainer<Value, Metadata>>>;
|
|
26
|
+
removeChild(container: FormValuesContainer<Value, Metadata>): Promise<FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, void>>;
|
|
27
|
+
registerChangeListener(listener: (newValue: FormValuesContainer<Value, Metadata>) => void): void;
|
|
28
|
+
unregisterChangeListener(listener: (newValue: FormValuesContainer<Value, Metadata>) => void): void;
|
|
29
|
+
}
|
|
30
|
+
export interface FormValuesContainerMutation<Value, Metadata, FVC extends FormValuesContainer<Value, Metadata>, Result> {
|
|
31
|
+
result: Result;
|
|
32
|
+
formValuesContainer: FVC;
|
|
33
|
+
}
|
|
34
|
+
export type Suggestion = {
|
|
35
|
+
id: string;
|
|
36
|
+
code: string;
|
|
37
|
+
text: string;
|
|
38
|
+
terms: string[];
|
|
39
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../tmp/generic/model.ts"],"names":[],"mappings":"","sourcesContent":["export interface VersionedData<T> {\n\t[id: string]: Version<T>[]\n}\n\nexport interface Version<T> {\n\trevision: string | null //null means that the version is not saved yet\n\tmodified?: number\n\tvalue: T\n}\n\nexport type ID = string\n/**\n * FormValuesContainer is a readonly structure that provides and handle the values of a form.\n */\nexport interface FormValuesContainer<Value, Metadata> {\n\t//information retrieval\n\tcompute<T, S extends { [key: string | symbol]: unknown }>(formula: string, sandbox?: S): T | undefined\n\tgetLabel(): string\n\tgetFormId(): string | undefined\n\tgetValues(revisionsFilter: (id: string, history: Version<Metadata>[]) => (string | null)[]): VersionedData<Value>\n\tgetMetadata(id: string, revisions: (string | null)[]): VersionedData<Metadata>\n\tgetChildren(): FormValuesContainer<Value, Metadata>[]\n\t//modification\n\tsetValue(label: string, language: string, data?: Value, id?: string, metadata?: Metadata): FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, ID>\n\tsetMetadata(label: string, metadata: Metadata, id?: string): FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, ID>\n\tdelete(serviceId: string): FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, void>\n\t//hierarchy\n\taddChild(\n\t\tanchorId: string,\n\t\ttemplateId: string,\n\t\tlabel: string,\n\t): Promise<FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, FormValuesContainer<Value, Metadata>>>\n\tremoveChild(container: FormValuesContainer<Value, Metadata>): Promise<FormValuesContainerMutation<Value, Metadata, FormValuesContainer<Value, Metadata>, void>>\n\t//listeners\n\tregisterChangeListener(listener: (newValue: FormValuesContainer<Value, Metadata>) => void): void\n\tunregisterChangeListener(listener: (newValue: FormValuesContainer<Value, Metadata>) => void): void\n}\n\nexport interface FormValuesContainerMutation<Value, Metadata, FVC extends FormValuesContainer<Value, Metadata>, Result> {\n\tresult: Result\n\tformValuesContainer: FVC\n}\n\nexport type Suggestion = { id: string; code: string; text: string; terms: string[] }\n"]}
|