handsontable 18.1.1 → 18.1.2-rc1
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/CHANGELOG.md +2 -0
- package/base.js +2 -2
- package/base.mjs +2 -2
- package/dataMap/metaManager/metaSchema.js +4 -2
- package/dataMap/metaManager/metaSchema.mjs +4 -2
- package/dist/handsontable.full.js +223 -44
- package/dist/handsontable.full.min.js +129 -129
- package/dist/handsontable.js +223 -44
- package/dist/handsontable.min.js +129 -129
- package/dist/themes/classic.js +2 -2
- package/dist/themes/classic.min.js +2 -2
- package/dist/themes/horizon.js +2 -2
- package/dist/themes/horizon.min.js +2 -2
- package/dist/themes/main.js +2 -2
- package/dist/themes/main.min.js +2 -2
- package/dist/themes/static/variables/colors/ant.js +2 -2
- package/dist/themes/static/variables/colors/ant.min.js +2 -2
- package/dist/themes/static/variables/colors/classic.js +2 -2
- package/dist/themes/static/variables/colors/classic.min.js +2 -2
- package/dist/themes/static/variables/colors/horizon.js +2 -2
- package/dist/themes/static/variables/colors/horizon.min.js +2 -2
- package/dist/themes/static/variables/colors/main.js +2 -2
- package/dist/themes/static/variables/colors/main.min.js +2 -2
- package/dist/themes/static/variables/colors/material.js +2 -2
- package/dist/themes/static/variables/colors/material.min.js +2 -2
- package/dist/themes/static/variables/colors/shadcn.js +2 -2
- package/dist/themes/static/variables/colors/shadcn.min.js +2 -2
- package/dist/themes/static/variables/density.js +2 -2
- package/dist/themes/static/variables/density.min.js +2 -2
- package/dist/themes/static/variables/helpers/iconsMap.js +2 -2
- package/dist/themes/static/variables/helpers/iconsMap.min.js +2 -2
- package/dist/themes/static/variables/icons/horizon.js +2 -2
- package/dist/themes/static/variables/icons/horizon.min.js +2 -2
- package/dist/themes/static/variables/icons/main.js +2 -2
- package/dist/themes/static/variables/icons/main.min.js +2 -2
- package/dist/themes/static/variables/sizing.js +2 -2
- package/dist/themes/static/variables/sizing.min.js +2 -2
- package/dist/themes/static/variables/tokens/classic.js +2 -2
- package/dist/themes/static/variables/tokens/classic.min.js +2 -2
- package/dist/themes/static/variables/tokens/horizon.js +2 -2
- package/dist/themes/static/variables/tokens/horizon.min.js +2 -2
- package/dist/themes/static/variables/tokens/main.js +2 -2
- package/dist/themes/static/variables/tokens/main.min.js +2 -2
- package/helpers/mixed.js +5 -5
- package/helpers/mixed.mjs +5 -5
- package/package.json +1 -1
- package/styles/handsontable.css +2 -2
- package/styles/handsontable.min.css +2 -2
- package/styles/handsontableStyles.js +1 -1
- package/styles/handsontableStyles.mjs +1 -1
- package/styles/ht-icons-horizon.min.css +2 -2
- package/styles/ht-icons-main.min.css +2 -2
- package/styles/ht-theme-classic-no-icons.min.css +2 -2
- package/styles/ht-theme-classic.min.css +2 -2
- package/styles/ht-theme-horizon-no-icons.min.css +2 -2
- package/styles/ht-theme-horizon.min.css +2 -2
- package/styles/ht-theme-main-no-icons.min.css +2 -2
- package/styles/ht-theme-main.min.css +2 -2
- package/utils/entitlementLicenseKey/constants.d.ts +7 -1
- package/utils/entitlementLicenseKey/constants.js +5 -1
- package/utils/entitlementLicenseKey/constants.mjs +6 -1
- package/utils/entitlementLicenseKey/encoding.d.ts +1 -1
- package/utils/entitlementLicenseKey/encoding.js +4 -1
- package/utils/entitlementLicenseKey/encoding.mjs +4 -1
- package/utils/entitlementLicenseKey/extractKeyData.d.ts +47 -8
- package/utils/entitlementLicenseKey/extractKeyData.js +155 -14
- package/utils/entitlementLicenseKey/extractKeyData.mjs +188 -23
- package/utils/entitlementLicenseKey/types.d.ts +5 -0
- package/utils/licenseBranding/index.js +2 -2
- package/utils/licenseBranding/index.mjs +2 -2
- package/utils/licenseNotification.js +2 -2
- package/utils/licenseNotification.mjs +2 -2
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING FROM
|
|
26
26
|
* USE OR INABILITY TO USE THIS SOFTWARE.
|
|
27
27
|
*
|
|
28
|
-
* Version: 18.1.
|
|
29
|
-
* Release date:
|
|
28
|
+
* Version: 18.1.2-rc1
|
|
29
|
+
* Release date: 07/10/2026 (built at 07/10/2026 08:29:56)
|
|
30
30
|
*/
|
|
31
31
|
.ht-theme-main,.ht-theme-main-dark,.ht-theme-main-dark-auto{--ht-sizing-size-0:0px;--ht-sizing-size-0-5:2px;--ht-sizing-size-1:4px;--ht-sizing-size-2:8px;--ht-sizing-size-1-5:6px;--ht-sizing-size-3:12px;--ht-sizing-size-4:16px;--ht-sizing-size-5:20px;--ht-sizing-size-6:24px;--ht-sizing-size-7:28px;--ht-sizing-size-8:32px;--ht-sizing-size-9:36px;--ht-sizing-size-10:40px;--ht-sizing-size-0-25:1px;--ht-density-cell-vertical:var(--ht-sizing-size-1);--ht-density-cell-horizontal:var(--ht-sizing-size-2);--ht-density-bars-horizontal:var(--ht-sizing-size-4);--ht-density-bars-vertical:var(--ht-sizing-size-2);--ht-density-gap:var(--ht-sizing-size-1);--ht-density-button-horizontal:var(--ht-sizing-size-3);--ht-density-button-vertical:var(--ht-sizing-size-1-5);--ht-density-dialog-horizontal:var(--ht-sizing-size-2);--ht-density-dialog-vertical:var(--ht-sizing-size-2);--ht-density-input-horizontal:var(--ht-sizing-size-3);--ht-density-input-vertical:var(--ht-sizing-size-1-5);--ht-density-menu-vertical:var(--ht-sizing-size-2);--ht-density-menu-horizontal:var(--ht-sizing-size-0);--ht-density-menu-item-vertical:var(--ht-sizing-size-1);--ht-density-menu-item-horizontal:var(--ht-sizing-size-3);--ht-colors-white:#fff;--ht-colors-black:#000;--ht-colors-primary-100:#6180ff;--ht-colors-primary-200:#5573f0;--ht-colors-primary-300:#4669f6;--ht-colors-primary-400:#2e56fc;--ht-colors-primary-500:#1a42e8;--ht-colors-primary-600:#1535bc;--ht-colors-palette-50:#f7f7f9;--ht-colors-palette-100:#e7e7e9;--ht-colors-palette-200:#b9b9bb;--ht-colors-palette-300:#a3a3a3;--ht-colors-palette-400:#68696c;--ht-colors-palette-500:#404144;--ht-colors-palette-600:#313132;--ht-colors-palette-700:#282829;--ht-colors-palette-800:#222;--ht-colors-palette-900:#1e1e1f;--ht-colors-palette-950:#050506;--ht-colors-transparent:#fff0;--ht-font-family:Inter;--ht-font-size:14px;--ht-font-size-small:12px;--ht-line-height:20px;--ht-line-height-small:18px;--ht-font-weight:400;--ht-letter-spacing:0px;--ht-border-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-accent-color:var(--lightningcss-light,var(--ht-colors-primary-500))var(--lightningcss-dark,var(--ht-colors-primary-300));--ht-foreground-color:var(--lightningcss-light,var(--ht-colors-palette-800))var(--lightningcss-dark,var(--ht-colors-palette-200));--ht-foreground-secondary-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-background-color:var(--lightningcss-light,var(--ht-colors-white))var(--lightningcss-dark,var(--ht-colors-palette-950));--ht-background-secondary-color:var(--lightningcss-light,var(--ht-colors-palette-50))var(--lightningcss-dark,var(--ht-colors-palette-900));--ht-placeholder-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-read-only-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-disabled-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-gap-size:var(--ht-density-gap);--ht-icon-size:var(--ht-sizing-size-4);--ht-table-transition:.15s;--ht-border-radius:var(--ht-sizing-size-1);--ht-bar-foreground-color:var(--ht-foreground-color);--ht-bar-background-color:var(--ht-background-secondary-color);--ht-bar-horizontal-padding:var(--ht-density-bars-horizontal);--ht-bar-vertical-padding:var(--ht-density-bars-vertical);--ht-shadow-color:var(--lightningcss-light,var(--ht-colors-palette-800))var(--lightningcss-dark,var(--ht-colors-palette-200));--ht-shadow-x:var(--ht-sizing-size-0);--ht-shadow-y:var(--ht-sizing-size-2);--ht-shadow-blur:var(--ht-sizing-size-4);--ht-shadow-opacity:8%;--ht-cell-horizontal-padding:var(--ht-density-cell-horizontal);--ht-cell-vertical-padding:var(--ht-density-cell-vertical);--ht-cell-horizontal-border-color:var(--ht-border-color);--ht-cell-vertical-border-color:var(--ht-border-color);--ht-cell-selection-border-color:var(--ht-accent-color);--ht-cell-selection-background-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-cell-success-background-color:#37bc6c33;--ht-cell-error-background-color:#fa4d3233;--ht-cell-read-only-background-color:var(--ht-background-secondary-color);--ht-cell-autofill-size:var(--ht-sizing-size-1-5);--ht-cell-autofill-hit-area-size:var(--ht-sizing-size-3);--ht-cell-autofill-border-width:var(--ht-sizing-size-0-25);--ht-cell-autofill-border-radius:var(--ht-sizing-size-1);--ht-cell-autofill-border-color:var(--ht-background-color);--ht-cell-autofill-background-color:var(--ht-accent-color);--ht-cell-autofill-fill-border-color:var(--ht-foreground-color);--ht-cell-editor-border-width:2px;--ht-cell-editor-border-color:var(--ht-accent-color);--ht-cell-editor-foreground-color:var(--lightningcss-light,var(--ht-colors-palette-950))var(--lightningcss-dark,var(--ht-colors-white));--ht-cell-editor-background-color:var(--ht-background-color);--ht-cell-editor-shadow-blur-radius:0px;--ht-cell-editor-shadow-color:var(--ht-accent-color);--ht-cell-mobile-handle-size:var(--ht-sizing-size-3);--ht-cell-mobile-handle-border-width:var(--ht-sizing-size-0-25);--ht-cell-mobile-handle-border-radius:var(--ht-sizing-size-3);--ht-cell-mobile-handle-border-color:var(--ht-accent-color);--ht-cell-mobile-handle-background-color:var(--ht-accent-color);--ht-cell-mobile-handle-background-opacity:40%;--ht-cell-selection-handle-size:var(--ht-sizing-size-2);--ht-cell-selection-handle-length:var(--ht-sizing-size-4);--ht-cell-selection-handle-border-width:var(--ht-sizing-size-0-25);--ht-cell-selection-handle-border-radius:var(--ht-sizing-size-3);--ht-cell-selection-handle-border-color:var(--ht-accent-color);--ht-cell-selection-handle-background-color:var(--ht-background-color);--ht-header-font-weight:var(--ht-font-weight);--ht-header-foreground-color:var(--ht-foreground-color);--ht-header-background-color:var(--ht-background-secondary-color);--ht-header-highlighted-shadow-size:0px;--ht-header-highlighted-foreground-color:var(--lightningcss-light,var(--ht-colors-palette-950))var(--lightningcss-dark,var(--ht-colors-white));--ht-header-highlighted-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-header-active-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-header-active-foreground-color:var(--ht-colors-white);--ht-header-active-background-color:var(--ht-accent-color);--ht-header-filter-background-color:var(--ht-cell-success-background-color);--ht-header-row-foreground-color:var(--ht-foreground-color);--ht-header-row-background-color:var(--ht-background-secondary-color);--ht-header-row-highlighted-foreground-color:var(--lightningcss-light,var(--ht-colors-palette-950))var(--lightningcss-dark,var(--ht-colors-white));--ht-header-row-highlighted-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-header-row-active-foreground-color:var(--ht-colors-white);--ht-header-row-active-background-color:var(--ht-accent-color);--ht-row-header-odd-background-color:var(--ht-header-row-background-color);--ht-row-header-even-background-color:var(--ht-header-row-background-color);--ht-row-cell-odd-background-color:var(--ht-background-color);--ht-row-cell-even-background-color:var(--ht-background-color);--ht-button-border-radius:var(--ht-sizing-size-1);--ht-button-horizontal-padding:var(--ht-density-button-horizontal);--ht-button-vertical-padding:var(--ht-density-button-vertical);--ht-primary-button-border-color:var(--ht-colors-transparent);--ht-primary-button-foreground-color:var(--ht-colors-white);--ht-primary-button-background-color:var(--ht-accent-color);--ht-primary-button-disabled-border-color:var(--ht-colors-transparent);--ht-primary-button-disabled-foreground-color:var(--ht-disabled-color);--ht-primary-button-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-primary-button-hover-border-color:var(--ht-colors-transparent);--ht-primary-button-hover-foreground-color:var(--ht-background-color);--ht-primary-button-hover-background-color:var(--lightningcss-light,var(--ht-colors-primary-600))var(--lightningcss-dark,var(--ht-colors-primary-100));--ht-primary-button-focus-border-color:var(--ht-background-color);--ht-primary-button-focus-foreground-color:var(--ht-background-color);--ht-primary-button-focus-background-color:var(--ht-accent-color);--ht-secondary-button-border-color:var(--ht-border-color);--ht-secondary-button-foreground-color:var(--ht-foreground-color);--ht-secondary-button-background-color:var(--ht-background-color);--ht-secondary-button-disabled-border-color:var(--ht-border-color);--ht-secondary-button-disabled-foreground-color:var(--ht-disabled-color);--ht-secondary-button-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-secondary-button-hover-border-color:var(--ht-border-color);--ht-secondary-button-hover-foreground-color:var(--ht-foreground-color);--ht-secondary-button-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-secondary-button-focus-border-color:var(--ht-border-color);--ht-secondary-button-focus-foreground-color:var(--ht-foreground-color);--ht-secondary-button-focus-background-color:var(--ht-background-color);--ht-icon-button-border-radius:var(--ht-sizing-size-0-5);--ht-icon-button-large-border-radius:var(--ht-sizing-size-1);--ht-icon-button-large-padding:var(--ht-sizing-size-1);--ht-icon-button-border-color:var(--lightningcss-light,var(--ht-colors-palette-50))var(--lightningcss-dark,var(--ht-colors-palette-900));--ht-icon-button-background-color:var(--ht-background-secondary-color);--ht-icon-button-icon-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-icon-button-hit-area-size:var(--ht-sizing-size-6);--ht-icon-button-hover-border-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-icon-button-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-icon-button-hover-icon-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-icon-button-active-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-icon-button-active-background-color:var(--ht-accent-color);--ht-icon-button-active-icon-color:var(--ht-colors-white);--ht-icon-button-active-hover-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-icon-button-active-hover-background-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-icon-button-active-hover-icon-color:var(--ht-colors-white);--ht-collapse-button-border-radius:var(--ht-sizing-size-1);--ht-collapse-button-open-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-collapse-button-open-background-color:var(--lightningcss-light,var(--ht-colors-white))var(--lightningcss-dark,var(--ht-colors-palette-950));--ht-collapse-button-open-icon-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-open-icon-active-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-open-hover-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-collapse-button-open-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-50))var(--lightningcss-dark,var(--ht-colors-palette-900));--ht-collapse-button-open-hover-icon-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-open-hover-icon-active-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-close-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-collapse-button-close-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-collapse-button-close-icon-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-close-icon-active-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-close-hover-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-collapse-button-close-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-collapse-button-close-hover-icon-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-close-hover-icon-active-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-link-color:var(--lightningcss-light,var(--ht-colors-primary-600))var(--lightningcss-dark,var(--ht-colors-primary-100));--ht-link-hover-color:var(--ht-accent-color);--ht-input-border-width:1px;--ht-input-border-radius:var(--ht-sizing-size-1);--ht-input-horizontal-padding:var(--ht-density-input-horizontal);--ht-input-vertical-padding:var(--ht-density-input-vertical);--ht-input-border-color:var(--ht-border-color);--ht-input-foreground-color:var(--ht-foreground-color);--ht-input-background-color:var(--ht-background-secondary-color);--ht-input-hover-border-color:var(--ht-border-color);--ht-input-hover-foreground-color:var(--ht-foreground-color);--ht-input-hover-background-color:var(--ht-background-color);--ht-input-disabled-border-color:var(--ht-border-color);--ht-input-disabled-foreground-color:var(--ht-disabled-color);--ht-input-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-input-focus-border-color:var(--ht-accent-color);--ht-input-focus-foreground-color:var(--ht-foreground-color);--ht-input-focus-background-color:var(--ht-background-color);--ht-checkbox-size:var(--ht-icon-size);--ht-checkbox-border-radius:var(--ht-sizing-size-1);--ht-checkbox-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-background-color:var(--ht-background-color);--ht-checkbox-icon-color:var(--ht-colors-transparent);--ht-checkbox-focus-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-focus-background-color:var(--ht-background-color);--ht-checkbox-focus-icon-color:var(--ht-colors-transparent);--ht-checkbox-focus-ring-color:var(--ht-accent-color);--ht-checkbox-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-checkbox-disabled-icon-color:var(--ht-colors-transparent);--ht-checkbox-checked-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-checkbox-checked-background-color:var(--ht-accent-color);--ht-checkbox-checked-icon-color:var(--ht-colors-white);--ht-checkbox-checked-focus-border-color:var(--ht-background-color);--ht-checkbox-checked-focus-background-color:var(--ht-accent-color);--ht-checkbox-checked-focus-icon-color:var(--ht-colors-white);--ht-checkbox-checked-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-checked-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-checkbox-checked-disabled-icon-color:var(--ht-disabled-color);--ht-checkbox-indeterminate-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-checkbox-indeterminate-background-color:var(--ht-accent-color);--ht-checkbox-indeterminate-icon-color:var(--ht-colors-white);--ht-checkbox-indeterminate-focus-border-color:var(--ht-background-color);--ht-checkbox-indeterminate-focus-background-color:var(--ht-accent-color);--ht-checkbox-indeterminate-focus-icon-color:var(--ht-colors-white);--ht-checkbox-indeterminate-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-600));--ht-checkbox-indeterminate-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-indeterminate-disabled-icon-color:var(--ht-disabled-color);--ht-radio-size:var(--ht-icon-size);--ht-radio-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-radio-background-color:var(--ht-background-color);--ht-radio-icon-color:var(--ht-colors-transparent);--ht-radio-focus-border-color:var(--ht-border-color);--ht-radio-focus-background-color:var(--ht-background-color);--ht-radio-focus-icon-color:var(--ht-colors-transparent);--ht-radio-focus-ring-color:var(--ht-accent-color);--ht-radio-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-radio-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-radio-disabled-icon-color:var(--ht-colors-transparent);--ht-radio-checked-border-color:var(--ht-accent-color);--ht-radio-checked-background-color:var(--ht-background-color);--ht-radio-checked-icon-color:var(--ht-accent-color);--ht-radio-checked-focus-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-radio-checked-focus-background-color:var(--ht-background-color);--ht-radio-checked-focus-icon-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-radio-checked-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-radio-checked-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-radio-checked-disabled-icon-color:var(--ht-disabled-color);--ht-move-backlight-color:var(--lightningcss-light,var(--ht-colors-palette-800))var(--lightningcss-dark,var(--ht-colors-palette-200));--ht-move-backlight-opacity:8%;--ht-move-indicator-color:var(--ht-accent-color);--ht-resize-indicator-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-hidden-indicator-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-menu-border-width:1px;--ht-menu-border-radius:var(--ht-sizing-size-1);--ht-menu-horizontal-padding:var(--ht-density-menu-horizontal);--ht-menu-vertical-padding:var(--ht-density-menu-vertical);--ht-menu-item-horizontal-padding:var(--ht-density-menu-item-horizontal);--ht-menu-item-vertical-padding:var(--ht-density-menu-item-vertical);--ht-menu-border-color:var(--ht-border-color);--ht-menu-shadow-x:var(--ht-shadow-x);--ht-menu-shadow-y:var(--ht-shadow-y);--ht-menu-shadow-blur:var(--ht-shadow-blur);--ht-menu-shadow-color:var(--lightningcss-light,var(--ht-colors-palette-950))var(--lightningcss-dark,var(--ht-colors-white));--ht-menu-shadow-opacity:8%;--ht-menu-item-hover-color:var(--lightningcss-light,var(--ht-colors-palette-800))var(--lightningcss-dark,var(--ht-colors-palette-200));--ht-menu-item-hover-color-opacity:4%;--ht-menu-item-active-color:var(--ht-accent-color);--ht-menu-item-active-color-opacity:8%;--ht-comments-textarea-horizontal-padding:var(--ht-density-cell-horizontal);--ht-comments-textarea-vertical-padding:var(--ht-density-cell-vertical);--ht-comments-textarea-border-width:1px;--ht-comments-textarea-border-color:var(--ht-colors-transparent);--ht-comments-textarea-foreground-color:var(--ht-foreground-color);--ht-comments-textarea-background-color:var(--ht-background-secondary-color);--ht-comments-textarea-focus-border-width:1px;--ht-comments-textarea-focus-border-color:var(--ht-accent-color);--ht-comments-textarea-focus-foreground-color:var(--ht-foreground-color);--ht-comments-textarea-focus-background-color:var(--ht-background-color);--ht-comments-indicator-size:var(--ht-sizing-size-1-5);--ht-comments-indicator-color:var(--ht-accent-color);--ht-license-horizontal-padding:var(--ht-bar-horizontal-padding);--ht-license-vertical-padding:var(--ht-bar-vertical-padding);--ht-license-foreground-color:var(--ht-bar-foreground-color);--ht-license-background-color:var(--ht-bar-background-color);--ht-pagination-bar-foreground-color:var(--ht-bar-foreground-color);--ht-pagination-bar-background-color:var(--ht-bar-background-color);--ht-pagination-bar-horizontal-padding:var(--ht-bar-horizontal-padding);--ht-pagination-bar-vertical-padding:var(--ht-bar-vertical-padding);--ht-pagination-button-border-color:var(--ht-pagination-bar-background-color);--ht-pagination-button-foreground-color:var(--ht-foreground-secondary-color);--ht-pagination-button-background-color:var(--ht-pagination-bar-background-color);--ht-pagination-button-hover-border-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-pagination-button-hover-foreground-color:var(--ht-foreground-color);--ht-pagination-button-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-pagination-button-disabled-border-color:var(--ht-pagination-bar-background-color);--ht-pagination-button-disabled-foreground-color:var(--ht-disabled-color);--ht-pagination-button-disabled-background-color:var(--ht-pagination-bar-background-color);--ht-pagination-button-focus-border-color:var(--ht-accent-color);--ht-pagination-button-focus-foreground-color:var(--ht-foreground-color);--ht-pagination-button-focus-background-color:var(--ht-pagination-bar-background-color);--ht-dialog-semi-transparent-background-color:var(--lightningcss-light,var(--ht-colors-white))var(--lightningcss-dark,var(--ht-colors-palette-950));--ht-dialog-semi-transparent-background-opacity:80%;--ht-dialog-solid-background-color:var(--lightningcss-light,var(--ht-colors-white))var(--lightningcss-dark,var(--ht-colors-palette-950));--ht-dialog-content-padding-horizontal:var(--ht-density-dialog-horizontal);--ht-dialog-content-padding-vertical:var(--ht-density-dialog-vertical);--ht-dialog-content-border-radius:var(--ht-sizing-size-2);--ht-dialog-content-background-color:var(--ht-background-secondary-color);--ht-notification-foreground-color:var(--ht-foreground-color);--ht-notification-background-color:var(--ht-background-color);--ht-notification-border-color:var(--ht-background-color);--ht-notification-success-accent:#37bc6c;--ht-notification-warning-accent:#fbe952;--ht-notification-error-accent:#fa4d32;--ht-chip-background:var(--ht-background-secondary-color);--ht-chip-border-radius:var(--ht-sizing-size-0-5);--ht-chip-vertical-padding:var(--ht-sizing-size-0);--ht-chip-horizontal-padding:var(--ht-sizing-size-0-5);--ht-chip-gap:var(--ht-sizing-size-1);--ht-scrollbar-border-radius:var(--ht-sizing-size-2);--ht-scrollbar-track-color:var(--ht-background-secondary-color);--ht-scrollbar-thumb-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400))}.ht-theme-main{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}.ht-theme-main-dark{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}.ht-theme-main-dark-auto{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){.ht-theme-main-dark-auto{--lightningcss-light: ;--lightningcss-dark:initial}}[class*=ht-theme-main] .htDropdownMenu table tbody tr td.htSubmenu .htItemWrapper:after,[class*=ht-theme-main] .htContextMenu table tbody tr td.htSubmenu .htItemWrapper:after,[class*=ht-theme-main] .htFiltersConditionsMenu table tbody tr td.htSubmenu .htItemWrapper:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M6.64648 10.9393L9.93938 7.64644L6.64648 4.35354%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-page-size-section__select-wrapper:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cg opacity=%270.6%27%3E%3Cpath d=%27M11.5859 6L8.29304 9.29289L5.00015 6%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/g%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] .changeType:before,[class*=ht-theme-main] .htUISelectCaption:after,.htAutocompleteArrow:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M11.0002 6.66663C11.4262 6.66663 11.6487 7.15963 11.3917 7.47813L11.3537 7.52013L8.35372 10.5201C8.26762 10.6062 8.15307 10.6579 8.03156 10.6656C7.91005 10.6732 7.78992 10.6363 7.69372 10.5616L7.64672 10.5201L4.64672 7.52013L4.60522 7.47313L4.57822 7.43463L4.55122 7.38663L4.54272 7.36863L4.52922 7.33513L4.51322 7.28113L4.50822 7.25463L4.50322 7.22463L4.50122 7.19613V7.13713L4.50372 7.10813L4.50822 7.07813L4.51322 7.05213L4.52922 6.99813L4.54272 6.96463L4.57772 6.89863L4.61022 6.85363L4.64672 6.81313L4.69372 6.77163L4.73222 6.74463L4.78022 6.71763L4.79822 6.70913L4.83172 6.69563L4.88572 6.67963L4.91222 6.67463L4.94222 6.66963L4.97072 6.66763L11.0002 6.66663Z%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .columnSorting.sortAction.ascending:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M8.00008 12.6667L8.00008 3.33335M8.00008 3.33335L5.33342 6.00002M8.00008 3.33335L10.6667 6.00002%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .columnSorting.sortAction.descending:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M8.00004 3.33331V12.6666M8.00004 12.6666L10.6667 9.99998M8.00004 12.6666L5.33337 9.99998%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-page-navigation-section .ht-page-first:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M11.0713 4.64188L7.72115 7.99203L11.0713 11.3422M4.92936 4.08353L4.92936 11.3422%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] [dir=rtl] .ht-page-navigation-section .ht-page-first:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M4.9292 4.64188L8.27934 7.99203L4.9292 11.3422M11.0711 4.08353V11.3422%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-page-navigation-section .ht-page-prev:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M9.49268 11.2929L6.19978 8.00001L9.49268 4.70712%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] [dir=rtl] .ht-page-navigation-section .ht-page-prev:before,[class*=ht-theme-main] .ht-page-navigation-section .ht-page-next:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M6.64648 10.9393L9.93938 7.64644L6.64648 4.35354%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] [dir=rtl] .ht-page-navigation-section .ht-page-next:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M9.49268 11.2929L6.19978 8.00001L9.49268 4.70712%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-page-navigation-section .ht-page-last:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M4.9292 4.64188L8.27934 7.99203L4.9292 11.3422M11.0711 4.08353V11.3422%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] [dir=rtl] .ht-page-navigation-section .ht-page-last:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M11.0713 4.64188L7.72115 7.99203L11.0713 11.3422M4.92936 4.08353L4.92936 11.3422%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] .htDropdownMenu table tbody tr td .htItemWrapper span.selected:after,[class*=ht-theme-main] .htContextMenu table tbody tr td .htItemWrapper span.selected:after,[class*=ht-theme-main] .htFiltersConditionsMenu table tbody tr td .htItemWrapper span.selected:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M3.33337 8.00002L6.66671 11.3334L13.3334 4.66669%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .htCheckboxRendererInput{-webkit-appearance:none;appearance:none}[class*=ht-theme-main] .htCheckboxRendererInput:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M5 8L7 10L11 6%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] th.beforeHiddenColumn:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width=%2710%27 height=%2710%27 viewBox=%270 0 10 10%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M6.08482 1.35771L6.11503 1.3551H6.17649L6.2067 1.35771L6.23795 1.36239L6.26503 1.3676L6.32128 1.38427L6.35618 1.39833L6.42493 1.43479L6.4718 1.46864L6.51399 1.50667L6.55722 1.55562L6.58534 1.59573L6.61347 1.64573L6.62232 1.66448L6.63639 1.69937L6.65305 1.75562L6.65826 1.78323L6.66347 1.81448L6.66555 1.84417L6.66659 1.87489V8.12489C6.66659 8.56864 6.15305 8.80042 5.82128 8.53271L5.77753 8.49312L2.65253 5.36812C2.56286 5.27844 2.50899 5.15912 2.50103 5.03254C2.49307 4.90596 2.53157 4.78083 2.6093 4.68062L2.65253 4.63167L5.77753 1.50667L5.82649 1.46344L5.86659 1.43531L5.91659 1.40719L5.93534 1.39833L5.97024 1.38427L6.02649 1.3676L6.05409 1.36239L6.08482 1.35771Z%27 fill=%27currentColor%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] th.afterHiddenColumn:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width=%2710%27 height=%2710%27 viewBox=%270 0 10 10%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M3.33337 1.87499C3.33337 1.43124 3.84692 1.19947 4.17869 1.46718L4.22244 1.50676L7.34744 4.63176C7.43711 4.72145 7.49098 4.84077 7.49894 4.96735C7.5069 5.09392 7.4684 5.21905 7.39067 5.31926L7.34744 5.36822L4.22244 8.49322L4.17348 8.53645L4.13337 8.56457L4.08337 8.5927L4.06462 8.60155L4.02973 8.61562L3.97348 8.63228L3.94587 8.63749L3.91462 8.6427L3.88494 8.64478L3.85421 8.64582L3.82348 8.64478L3.79327 8.64218L3.76202 8.63749L3.73494 8.63228L3.67869 8.61562L3.64379 8.60155L3.57504 8.5651L3.52817 8.53124L3.48598 8.49322L3.44275 8.44426L3.41462 8.40416L3.3865 8.35416L3.37764 8.33541L3.36358 8.30051L3.34692 8.24426L3.34171 8.21666L3.3365 8.18541L3.33442 8.15572L3.33337 1.87499Z%27 fill=%27currentColor%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] th.beforeHiddenRow:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%278%27 height=%278%27 viewBox=%270 0 8 8%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M3.76425 2.43099C3.82165 2.3736 3.89801 2.33913 3.97902 2.33403C4.06003 2.32894 4.14012 2.35358 4.20425 2.40333L4.23558 2.43099L6.23558 4.43099L6.26325 4.46233L6.28125 4.48799L6.29925 4.51999L6.30492 4.53199L6.31392 4.55433L6.32458 4.59033L6.32792 4.60799L6.33125 4.62799L6.33258 4.64699L6.33325 4.66666L6.33258 4.68633L6.33092 4.70566L6.32792 4.72566L6.32458 4.74299L6.31392 4.77899L6.30492 4.80133L6.28158 4.84533L6.25992 4.87533L6.23558 4.90233L6.20425 4.92999L6.17858 4.94799L6.14658 4.96599L6.13458 4.97166L6.11225 4.98066L6.07625 4.99133L6.05858 4.99466L6.03858 4.99799L6.01958 4.99933L5.99992 4.99999H1.99992C1.71592 4.99999 1.56758 4.67133 1.73892 4.45899L1.76425 4.43099L3.76425 2.43099Z%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] th.afterHiddenRow:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%278%27 height=%278%27 viewBox=%270 0 8 8%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M5.9999 3C6.2839 3 6.43224 3.32867 6.2609 3.541L6.23557 3.569L4.23557 5.569C4.17817 5.62639 4.10181 5.66087 4.0208 5.66596C3.93979 5.67106 3.8597 5.64642 3.79557 5.59667L3.76424 5.569L1.76424 3.569L1.73657 3.53767L1.71857 3.512L1.70057 3.48L1.6949 3.468L1.6859 3.44567L1.67524 3.40967L1.6719 3.392L1.66857 3.372L1.66724 3.353V3.31367L1.6689 3.29433L1.6719 3.27433L1.67524 3.257L1.6859 3.221L1.6949 3.19867L1.71824 3.15467L1.7399 3.12467L1.76424 3.09767L1.79557 3.07L1.82124 3.052L1.85324 3.034L1.86524 3.02833L1.88757 3.01933L1.92357 3.00867L1.94124 3.00533L1.96124 3.002L1.98024 3.00067L5.9999 3Z%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .collapsibleIndicator:before,[class*=ht-theme-main] .ht_nestingButton:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M4.33325 8H11.6666%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .collapsibleIndicator.collapsed:before,[class*=ht-theme-main] .ht_nestingButton.ht_nestingExpand:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath fill-rule=%27evenodd%27 clip-rule=%27evenodd%27 d=%27M7.49988 11.6667C7.49988 11.9428 7.72374 12.1667 7.99988 12.1667C8.27602 12.1667 8.49988 11.9428 8.49988 11.6667V8.50002H11.6666C11.9427 8.50002 12.1666 8.27616 12.1666 8.00002C12.1666 7.72388 11.9427 7.50002 11.6666 7.50002H8.49988V4.33337C8.49988 4.05723 8.27602 3.83337 7.99988 3.83337C7.72374 3.83337 7.49988 4.05723 7.49988 4.33337V7.50002H4.33325C4.05711 7.50002 3.83325 7.72388 3.83325 8.00002C3.83325 8.27616 4.05711 8.50002 4.33325 8.50002H7.49988V11.6667Z%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .htUIRadio>input[type=radio]:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Ccircle cx=%278%27 cy=%278%27 r=%274%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-multi-select-chip-remove:before,[class*=ht-theme-main] .ht-notification__close:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M12 4L4 12M4 4L12 12%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-multi-select-editor-search-icon{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2732%27 height=%2732%27 viewBox=%270 0 32 32%27 fill=%27none%27%3E%3Cg opacity=%270.5%27%3E%3Cpath d=%27M28 28L20 20M4 13.3333C4 14.559 4.24141 15.7727 4.71046 16.905C5.1795 18.0374 5.86699 19.0663 6.73367 19.933C7.60035 20.7997 8.62925 21.4872 9.76162 21.9562C10.894 22.4253 12.1077 22.6667 13.3333 22.6667C14.559 22.6667 15.7727 22.4253 16.905 21.9562C18.0374 21.4872 19.0663 20.7997 19.933 19.933C20.7997 19.0663 21.4872 18.0374 21.9562 16.905C22.4253 15.7727 22.6667 14.559 22.6667 13.3333C22.6667 12.1077 22.4253 10.894 21.9562 9.76162C21.4872 8.62925 20.7997 7.60035 19.933 6.73367C19.0663 5.86699 18.0374 5.1795 16.905 4.71046C15.7727 4.24141 14.559 4 13.3333 4C12.1077 4 10.894 4.24141 9.76162 4.71046C8.62925 5.1795 7.60035 5.86699 6.73367 6.73367C5.86699 7.60035 5.1795 8.62925 4.71046 9.76162C4.24141 10.894 4 12.1077 4 13.3333Z%27 stroke=%27black%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/g%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-multi-select-editor-item-selected input:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M5 8L7 10L11 6%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The length of the checksum
|
|
2
|
+
* The length of the checksum that closes the machine-readable
|
|
3
3
|
* block of every entitlement license key.
|
|
4
4
|
*
|
|
5
5
|
* @type {number}
|
|
6
6
|
*/
|
|
7
7
|
export declare const CHECKSUM_LENGTH = 128;
|
|
8
|
+
/**
|
|
9
|
+
* The length of the value a current key stores for its text.
|
|
10
|
+
*
|
|
11
|
+
* @type {number}
|
|
12
|
+
*/
|
|
13
|
+
export declare const PROSE_DIGEST_LENGTH = 64;
|
|
8
14
|
/**
|
|
9
15
|
* The two mutually exclusive date fields of a product entry. Exactly one of
|
|
10
16
|
* them is present:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The length of the checksum
|
|
2
|
+
* The length of the checksum that closes the machine-readable
|
|
3
3
|
* block of every entitlement license key.
|
|
4
4
|
*
|
|
5
5
|
* @type {number}
|
|
@@ -35,11 +35,15 @@ _export(exports, {
|
|
|
35
35
|
get NO_UI_WARNS_FLAG () {
|
|
36
36
|
return NO_UI_WARNS_FLAG;
|
|
37
37
|
},
|
|
38
|
+
get PROSE_DIGEST_LENGTH () {
|
|
39
|
+
return PROSE_DIGEST_LENGTH;
|
|
40
|
+
},
|
|
38
41
|
get TRIAL_FLAG () {
|
|
39
42
|
return TRIAL_FLAG;
|
|
40
43
|
}
|
|
41
44
|
});
|
|
42
45
|
const CHECKSUM_LENGTH = 128;
|
|
46
|
+
const PROSE_DIGEST_LENGTH = 64;
|
|
43
47
|
const DATE_FIELDS = [
|
|
44
48
|
'usage_until',
|
|
45
49
|
'release_until'
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The length of the checksum
|
|
2
|
+
* The length of the checksum that closes the machine-readable
|
|
3
3
|
* block of every entitlement license key.
|
|
4
4
|
*
|
|
5
5
|
* @type {number}
|
|
6
6
|
*/ export const CHECKSUM_LENGTH = 128;
|
|
7
|
+
/**
|
|
8
|
+
* The length of the value a current key stores for its text.
|
|
9
|
+
*
|
|
10
|
+
* @type {number}
|
|
11
|
+
*/ export const PROSE_DIGEST_LENGTH = 64;
|
|
7
12
|
/**
|
|
8
13
|
* The two mutually exclusive date fields of a product entry. Exactly one of
|
|
9
14
|
* them is present:
|
|
@@ -55,4 +55,4 @@ export declare function base64ToString(base64: string): string | null;
|
|
|
55
55
|
* @param {string} isoDate The date to parse.
|
|
56
56
|
* @returns {number|null}
|
|
57
57
|
*/
|
|
58
|
-
export declare function parseIsoDateToTimestamp(isoDate:
|
|
58
|
+
export declare function parseIsoDateToTimestamp(isoDate: unknown): number | null;
|
|
@@ -138,7 +138,10 @@ function base64ToString(base64) {
|
|
|
138
138
|
return bytes === null ? null : utf8BytesToString(bytes);
|
|
139
139
|
}
|
|
140
140
|
function parseIsoDateToTimestamp(isoDate) {
|
|
141
|
-
|
|
141
|
+
// Only a string is a date. Checked before the text test on purpose: an array
|
|
142
|
+
// like `['2027-08-12']` stringifies to a valid date and would otherwise pass,
|
|
143
|
+
// and an object whose `toString` is not a function would throw.
|
|
144
|
+
const match = typeof isoDate === 'string' ? /^(\d{4})-(\d{2})-(\d{2})$/.exec(isoDate) : null;
|
|
142
145
|
if (match === null) {
|
|
143
146
|
return null;
|
|
144
147
|
}
|
|
@@ -149,7 +149,10 @@
|
|
|
149
149
|
* @param {string} isoDate The date to parse.
|
|
150
150
|
* @returns {number|null}
|
|
151
151
|
*/ export function parseIsoDateToTimestamp(isoDate) {
|
|
152
|
-
|
|
152
|
+
// Only a string is a date. Checked before the text test on purpose: an array
|
|
153
|
+
// like `['2027-08-12']` stringifies to a valid date and would otherwise pass,
|
|
154
|
+
// and an object whose `toString` is not a function would throw.
|
|
155
|
+
const match = typeof isoDate === 'string' ? /^(\d{4})-(\d{2})-(\d{2})$/.exec(isoDate) : null;
|
|
153
156
|
if (match === null) {
|
|
154
157
|
return null;
|
|
155
158
|
}
|
|
@@ -1,4 +1,36 @@
|
|
|
1
1
|
import type { EntitlementKeyData, ProductEntitlement } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Brings the human-readable text of a key to the form the key protects.
|
|
4
|
+
*
|
|
5
|
+
* Only the whitespace, its escaped forms, and the Unicode composition are
|
|
6
|
+
* ignored. A mail client that rewraps the text (also between two CJK
|
|
7
|
+
* characters or inside a word) or collapses a blank line, a `.env` file that
|
|
8
|
+
* saves a line break as `\n`, or a system that stores "u" + U+0308 instead of
|
|
9
|
+
* U+00FC leaves the key valid. A changed, added, or removed letter, digit, or
|
|
10
|
+
* symbol does not.
|
|
11
|
+
* Exported for the test key builder; the library calls `extractEntitlementKeyData`.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} prose The text in front of the machine-readable block.
|
|
14
|
+
* @returns {string}
|
|
15
|
+
*/
|
|
16
|
+
export declare function canonicalizeProse(prose: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Computes the checksum that closes the block. It must match the canonical
|
|
19
|
+
* reader in every key format, so Handsontable 18.1 keeps reading newer keys.
|
|
20
|
+
* Exported for the test key builder.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} encodedPayload The encoded payload.
|
|
23
|
+
* @returns {string}
|
|
24
|
+
*/
|
|
25
|
+
export declare function computePayloadChecksum(encodedPayload: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Computes the value a current key stores for its text. Exported for the test
|
|
28
|
+
* key builder.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} canonicalProse The text, already passed through `canonicalizeProse`.
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
export declare function computeProseDigest(canonicalProse: string): string;
|
|
2
34
|
/**
|
|
3
35
|
* Adds an own, ordinary property.
|
|
4
36
|
*
|
|
@@ -18,19 +50,26 @@ export declare function defineOwn(target: object, key: string, value: unknown):
|
|
|
18
50
|
/**
|
|
19
51
|
* Extracts the machine-readable data from an entitlement license key.
|
|
20
52
|
*
|
|
21
|
-
* The
|
|
22
|
-
*
|
|
23
|
-
*
|
|
53
|
+
* The key is verified first, so the returned data is guaranteed to belong to
|
|
54
|
+
* an intact key. A malformed or tampered key reads as `null` - reporting an
|
|
55
|
+
* invalid key is the caller's job, not this function's.
|
|
56
|
+
*
|
|
57
|
+
* A current key protects its text as well: edited or removed text (the bare
|
|
58
|
+
* `[...]` block), or anything but whitespace after the block, reads as `null`.
|
|
59
|
+
* A key in the earlier format reads the way Handsontable 18.1 reads it. The
|
|
60
|
+
* verification rules are those of the canonical reader in the private
|
|
61
|
+
* `license-key` repository.
|
|
24
62
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* it makes the key unreadable, exactly as it does for the key generator.
|
|
63
|
+
* The caller passes the whole key. The text is never parsed, and its
|
|
64
|
+
* whitespace and Unicode composition are ignored, so rewrapped or re-pasted
|
|
65
|
+
* text still validates. Whitespace inside the block is ignored too, so a
|
|
66
|
+
* block wrapped by a mail client still validates.
|
|
30
67
|
*
|
|
31
68
|
* Unknown products, capability tokens and flags are all tolerated, so nothing
|
|
32
69
|
* about reading a key depends on the commercial vocabulary.
|
|
33
70
|
*
|
|
71
|
+
* The result is frozen. Copy an array before sorting or changing it.
|
|
72
|
+
*
|
|
34
73
|
* @param {string} licenseKey The license key to extract the data from.
|
|
35
74
|
* @returns {EntitlementKeyData|null}
|
|
36
75
|
*/
|
|
@@ -9,6 +9,15 @@ function _export(target, all) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
|
+
get canonicalizeProse () {
|
|
13
|
+
return canonicalizeProse;
|
|
14
|
+
},
|
|
15
|
+
get computePayloadChecksum () {
|
|
16
|
+
return computePayloadChecksum;
|
|
17
|
+
},
|
|
18
|
+
get computeProseDigest () {
|
|
19
|
+
return computeProseDigest;
|
|
20
|
+
},
|
|
12
21
|
get defineOwn () {
|
|
13
22
|
return defineOwn;
|
|
14
23
|
},
|
|
@@ -23,13 +32,63 @@ const _constants = require("./constants");
|
|
|
23
32
|
const _sha512 = require("./sha512");
|
|
24
33
|
const _encoding = require("./encoding");
|
|
25
34
|
/**
|
|
26
|
-
* The
|
|
27
|
-
*
|
|
28
|
-
* split by a fixed length from the right.
|
|
35
|
+
* The alphabets of the two parts of the machine-readable block. The second
|
|
36
|
+
* part has a fixed length, so the two are split from the right.
|
|
29
37
|
*
|
|
30
38
|
* @type {RegExp}
|
|
31
39
|
*/ const ENCODED_PAYLOAD = /^[A-Za-z0-9\-_]+$/;
|
|
32
40
|
const CHECKSUM = /^[0-9a-f]+$/;
|
|
41
|
+
/**
|
|
42
|
+
* The whitespace the reader ignores, in the text and inside the block: TAB,
|
|
43
|
+
* LF, VT, FF, CR, SPACE, NO-BREAK SPACE,
|
|
44
|
+
* OGHAM SPACE MARK, the U+2000-U+200A spaces, LINE SEPARATOR, PARAGRAPH
|
|
45
|
+
* SEPARATOR, NARROW NO-BREAK SPACE, MEDIUM MATHEMATICAL SPACE, IDEOGRAPHIC
|
|
46
|
+
* SPACE, and the BOM.
|
|
47
|
+
*
|
|
48
|
+
* Listed explicitly instead of `\s`, whose set has changed between JavaScript
|
|
49
|
+
* engines (U+180E) and differs in other languages (U+0085), so it matches the
|
|
50
|
+
* key generator exactly.
|
|
51
|
+
*
|
|
52
|
+
* @type {RegExp}
|
|
53
|
+
*/ const PROSE_WHITESPACE = /[\t\n\v\f\r \u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/g;
|
|
54
|
+
/**
|
|
55
|
+
* A line break or tab that was saved as text - a backslash followed by "n",
|
|
56
|
+
* "r", or "t" - also ignored.
|
|
57
|
+
*
|
|
58
|
+
* Several places a key is stored keep a line break that way rather than as a
|
|
59
|
+
* real one: a single-quoted or unquoted `.env` value, Docker's `--env-file`,
|
|
60
|
+
* and many CI secret fields. The block survives that intact, so without this
|
|
61
|
+
* a genuine key would fail only because of how it was stored. The generator
|
|
62
|
+
* strips backslashes from every free-text field, so a key it issues never
|
|
63
|
+
* carries one of its own.
|
|
64
|
+
*
|
|
65
|
+
* @type {RegExp}
|
|
66
|
+
*/ const ESCAPED_WHITESPACE = /\\[nrt]/g;
|
|
67
|
+
/**
|
|
68
|
+
* Removes every escaped line break or tab (`\n`, `\r`, `\t` saved as text) and
|
|
69
|
+
* then every whitespace character, in that order.
|
|
70
|
+
*
|
|
71
|
+
* The block is one long word, so a mail client or an editor that wraps the key
|
|
72
|
+
* can break it across lines, and a `.env` file can save that line break as the
|
|
73
|
+
* text `\n`. The block's alphabet has neither, so removing them cannot change
|
|
74
|
+
* a genuine block.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} text The text to remove the whitespace from.
|
|
77
|
+
* @returns {string}
|
|
78
|
+
*/ function removeWhitespace(text) {
|
|
79
|
+
return text.replace(ESCAPED_WHITESPACE, '').replace(PROSE_WHITESPACE, '');
|
|
80
|
+
}
|
|
81
|
+
function canonicalizeProse(prose) {
|
|
82
|
+
// NFC runs last: a line break between a letter and its combining mark (an
|
|
83
|
+
// NFD copy rewrapped there) has to be gone before the two can compose.
|
|
84
|
+
return removeWhitespace(prose).normalize('NFC');
|
|
85
|
+
}
|
|
86
|
+
function computePayloadChecksum(encodedPayload) {
|
|
87
|
+
return (0, _sha512.sha512)((0, _encoding.stringToUtf8Bytes)(encodedPayload));
|
|
88
|
+
}
|
|
89
|
+
function computeProseDigest(canonicalProse) {
|
|
90
|
+
return (0, _sha512.sha512)((0, _encoding.stringToUtf8Bytes)(canonicalProse)).slice(0, _constants.PROSE_DIGEST_LENGTH);
|
|
91
|
+
}
|
|
33
92
|
/**
|
|
34
93
|
* Reports own-property presence without trusting a payload's inherited or
|
|
35
94
|
* overridden `hasOwnProperty`.
|
|
@@ -66,6 +125,39 @@ const CHECKSUM = /^[0-9a-f]+$/;
|
|
|
66
125
|
*/ function isStringArray(value) {
|
|
67
126
|
return Array.isArray(value) && value.every((item)=>typeof item === 'string');
|
|
68
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Freezes the value and everything nested in it. The read result is shared
|
|
130
|
+
* between callers (see the memo below), so a caller that sorted or pushed into
|
|
131
|
+
* it would silently rewrite what the next caller reads.
|
|
132
|
+
*
|
|
133
|
+
* It walks with an explicit stack, not by recursion. An unknown extra field is
|
|
134
|
+
* kept as it is, and a key can nest one thousands of levels deep - recursion
|
|
135
|
+
* would then overflow the call stack and throw out of the reader, where a key
|
|
136
|
+
* is only ever allowed to read as data or as `null`.
|
|
137
|
+
*
|
|
138
|
+
* @param {*} value The value to freeze.
|
|
139
|
+
* @returns {*}
|
|
140
|
+
*/ function deepFreeze(value) {
|
|
141
|
+
const pending = [
|
|
142
|
+
value
|
|
143
|
+
];
|
|
144
|
+
while(pending.length > 0){
|
|
145
|
+
const current = pending.pop();
|
|
146
|
+
if (isFreezable(current)) {
|
|
147
|
+
Object.freeze(current);
|
|
148
|
+
Object.keys(current).forEach((key)=>pending.push(current[key]));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return value;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Narrows an unknown value to an object (or array) that is not frozen yet.
|
|
155
|
+
*
|
|
156
|
+
* @param {*} value The value to check.
|
|
157
|
+
* @returns {boolean}
|
|
158
|
+
*/ function isFreezable(value) {
|
|
159
|
+
return value !== null && typeof value === 'object' && !Object.isFrozen(value);
|
|
160
|
+
}
|
|
69
161
|
function defineOwn(target, key, value) {
|
|
70
162
|
Object.defineProperty(target, key, {
|
|
71
163
|
value,
|
|
@@ -104,7 +196,7 @@ function defineOwn(target, key, value) {
|
|
|
104
196
|
if (presentDateFields.length !== 1) {
|
|
105
197
|
return null;
|
|
106
198
|
}
|
|
107
|
-
if ((0, _encoding.parseIsoDateToTimestamp)(
|
|
199
|
+
if ((0, _encoding.parseIsoDateToTimestamp)(entry[presentDateFields[0]]) === null) {
|
|
108
200
|
return null;
|
|
109
201
|
}
|
|
110
202
|
if (!isNonNegativeInteger(entry.notice) || !isNonNegativeInteger(entry.grace)) {
|
|
@@ -129,6 +221,41 @@ function defineOwn(target, key, value) {
|
|
|
129
221
|
defineOwn(normalized, presentDateFields[0], entry[presentDateFields[0]]);
|
|
130
222
|
return normalized;
|
|
131
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Reads the format version of a payload. Returns `null` for a value no
|
|
226
|
+
* generator writes. A version newer than this reader knows is accepted, so a
|
|
227
|
+
* build already in the field keeps reading newer keys.
|
|
228
|
+
*
|
|
229
|
+
* @param {object} payload The decoded payload.
|
|
230
|
+
* @returns {number|null}
|
|
231
|
+
*/ function readFormatVersion(payload) {
|
|
232
|
+
// Own properties only, so a value another script put on `Object.prototype`
|
|
233
|
+
// cannot change how a key is read.
|
|
234
|
+
if (!hasOwn(payload, 'v')) {
|
|
235
|
+
return 1;
|
|
236
|
+
}
|
|
237
|
+
if (!isNonNegativeInteger(payload.v) || payload.v < 2) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
return payload.v;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Checks that the text of a current key is intact and that nothing but
|
|
244
|
+
* whitespace follows its block. A key always states its terms, so the bare
|
|
245
|
+
* block is rejected. A key in the earlier format is read the way Handsontable
|
|
246
|
+
* 18.1 reads it.
|
|
247
|
+
*
|
|
248
|
+
* @param {object} payload The decoded payload.
|
|
249
|
+
* @param {string} prose The text in front of the block.
|
|
250
|
+
* @param {string} textAfterBlock The text after the block.
|
|
251
|
+
* @returns {boolean}
|
|
252
|
+
*/ function coversItsText(payload, prose, textAfterBlock) {
|
|
253
|
+
if (canonicalizeProse(textAfterBlock) !== '') {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
const canonicalProse = canonicalizeProse(prose);
|
|
257
|
+
return canonicalProse !== '' && hasOwn(payload, 'prose') && typeof payload.prose === 'string' && computeProseDigest(canonicalProse) === payload.prose;
|
|
258
|
+
}
|
|
132
259
|
/**
|
|
133
260
|
* Reads and verifies one key. Split out from the memoized public entry point so
|
|
134
261
|
* the memo can wrap every exit path uniformly.
|
|
@@ -146,7 +273,7 @@ function defineOwn(target, key, value) {
|
|
|
146
273
|
if (blockEnd === -1) {
|
|
147
274
|
return null;
|
|
148
275
|
}
|
|
149
|
-
const content = licenseKey.slice(blockStart + 1, blockEnd);
|
|
276
|
+
const content = removeWhitespace(licenseKey.slice(blockStart + 1, blockEnd));
|
|
150
277
|
if (content.length <= _constants.CHECKSUM_LENGTH) {
|
|
151
278
|
return null;
|
|
152
279
|
}
|
|
@@ -155,7 +282,7 @@ function defineOwn(target, key, value) {
|
|
|
155
282
|
if (!ENCODED_PAYLOAD.test(encodedPayload) || !CHECKSUM.test(checksum)) {
|
|
156
283
|
return null;
|
|
157
284
|
}
|
|
158
|
-
if ((
|
|
285
|
+
if (computePayloadChecksum(encodedPayload) !== checksum) {
|
|
159
286
|
return null;
|
|
160
287
|
}
|
|
161
288
|
const payloadJson = (0, _encoding.base64ToString)(encodedPayload);
|
|
@@ -171,6 +298,13 @@ function defineOwn(target, key, value) {
|
|
|
171
298
|
if (!isPlainObject(payload) || !isPlainObject(payload.products)) {
|
|
172
299
|
return null;
|
|
173
300
|
}
|
|
301
|
+
const version = readFormatVersion(payload);
|
|
302
|
+
if (version === null) {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
if (version >= 2 && !coversItsText(payload, licenseKey.slice(0, blockStart), licenseKey.slice(blockEnd + 1))) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
174
308
|
const products = {};
|
|
175
309
|
const entries = payload.products;
|
|
176
310
|
let malformed = false;
|
|
@@ -185,22 +319,29 @@ function defineOwn(target, key, value) {
|
|
|
185
319
|
if (malformed) {
|
|
186
320
|
return null;
|
|
187
321
|
}
|
|
188
|
-
return {
|
|
322
|
+
return deepFreeze({
|
|
323
|
+
version,
|
|
189
324
|
products
|
|
190
|
-
};
|
|
325
|
+
});
|
|
191
326
|
}
|
|
192
327
|
// The license key is read twice per grid init - the bottom bar
|
|
193
328
|
// (`initLicenseNotification`) and the branding UI (`initLicenseBranding`) each resolve the license
|
|
194
|
-
// state - and reading runs the full
|
|
195
|
-
// the second read free. The returned data is
|
|
329
|
+
// state - and reading runs the full verification and decoding. A one-entry memo on the key makes
|
|
330
|
+
// the second read free. The returned data is frozen, as in the canonical reader, so sharing one
|
|
196
331
|
// object is safe.
|
|
197
332
|
let memoizedKey = null;
|
|
198
333
|
let memoizedData = null;
|
|
199
334
|
function extractEntitlementKeyData(licenseKey) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
335
|
+
if (typeof licenseKey !== 'string') {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
if (licenseKey !== memoizedKey) {
|
|
339
|
+
// Read first, remember second. Were the key remembered before the read,
|
|
340
|
+
// a read that throws would leave the new key paired with the previous
|
|
341
|
+
// key's data, and the next read of the new key would return it.
|
|
342
|
+
const data = readEntitlementKeyData(licenseKey);
|
|
343
|
+
memoizedKey = licenseKey;
|
|
344
|
+
memoizedData = data;
|
|
204
345
|
}
|
|
205
346
|
return memoizedData;
|
|
206
347
|
}
|