@simpleapps-com/augur-web 2.3.1 → 2026.11.1
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/EXPORTS.md +18 -189
- package/README.md +18 -364
- package/dist/accordion.cjs.map +1 -1
- package/dist/accordion.d.ts +4 -5
- package/dist/accordion.d.ts.map +1 -0
- package/dist/add-to-cart-button.cjs.map +1 -1
- package/dist/add-to-cart-button.d.ts +5 -8
- package/dist/add-to-cart-button.d.ts.map +1 -0
- package/dist/breadcrumb.cjs.map +1 -1
- package/dist/breadcrumb.d.ts +5 -7
- package/dist/breadcrumb.d.ts.map +1 -0
- package/dist/breadcrumbs.cjs.map +1 -1
- package/dist/breadcrumbs.d.ts +4 -4
- package/dist/breadcrumbs.d.ts.map +1 -0
- package/dist/button.cjs.map +1 -1
- package/dist/button.d.ts +7 -9
- package/dist/button.d.ts.map +1 -0
- package/dist/card.cjs.map +1 -1
- package/dist/card.d.ts +3 -4
- package/dist/card.d.ts.map +1 -0
- package/dist/checkbox.cjs.map +1 -1
- package/dist/checkbox.d.ts +3 -4
- package/dist/checkbox.d.ts.map +1 -0
- package/dist/chunk-32XB3REY.cjs.map +1 -1
- package/dist/chunk-5VMEEKZ5.cjs.map +1 -1
- package/dist/chunk-5ZITWMV4.cjs.map +1 -1
- package/dist/chunk-76RSVRGB.cjs.map +1 -1
- package/dist/chunk-7EXXNELX.cjs.map +1 -1
- package/dist/chunk-BXMTQGKV.cjs.map +1 -1
- package/dist/chunk-EEJYDSXR.cjs +220 -0
- package/dist/chunk-EEJYDSXR.cjs.map +1 -0
- package/dist/chunk-GSR6SMQ2.cjs.map +1 -1
- package/dist/{chunk-3VN3FX2Q.js → chunk-JWTTXZDS.js} +18 -20
- package/dist/chunk-JWTTXZDS.js.map +1 -0
- package/dist/chunk-JXW4XE2P.cjs.map +1 -1
- package/dist/chunk-MAENILZP.cjs.map +1 -1
- package/dist/chunk-NEY26NNF.cjs.map +1 -1
- package/dist/{chunk-NSSX7USQ.cjs → chunk-OQV27VC5.cjs} +18 -20
- package/dist/chunk-OQV27VC5.cjs.map +1 -0
- package/dist/{chunk-DCXYO3RB.js → chunk-PFEPE5UE.js} +7 -3
- package/dist/chunk-PFEPE5UE.js.map +1 -0
- package/dist/chunk-T52J3SHP.cjs.map +1 -1
- package/dist/chunk-UFL6PVLI.cjs.map +1 -1
- package/dist/chunk-VI2IE6RC.js +220 -0
- package/dist/chunk-VI2IE6RC.js.map +1 -0
- package/dist/chunk-VL6L4GDA.cjs.map +1 -1
- package/dist/chunk-WJUDOEVB.cjs.map +1 -1
- package/dist/chunk-XGKBDPGD.cjs.map +1 -1
- package/dist/{chunk-AE4GLYJE.cjs → chunk-YTBB63IE.cjs} +7 -3
- package/dist/chunk-YTBB63IE.cjs.map +1 -0
- package/dist/chunk-Z57QBVUC.cjs.map +1 -1
- package/dist/command.cjs +7 -2
- package/dist/command.cjs.map +1 -1
- package/dist/command.d.ts +17 -16
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +8 -3
- package/dist/command.js.map +1 -1
- package/dist/confirm-dialog.cjs +1 -1
- package/dist/confirm-dialog.cjs.map +1 -1
- package/dist/confirm-dialog.d.ts +4 -6
- package/dist/confirm-dialog.d.ts.map +1 -0
- package/dist/confirm-dialog.js +1 -1
- package/dist/confirm-dialog.js.map +1 -1
- package/dist/data-table.cjs +46 -34
- package/dist/data-table.cjs.map +1 -1
- package/dist/data-table.d.ts +9 -11
- package/dist/data-table.d.ts.map +1 -0
- package/dist/data-table.js +45 -33
- package/dist/data-table.js.map +1 -1
- package/dist/detail-panel.cjs +3 -3
- package/dist/detail-panel.cjs.map +1 -1
- package/dist/detail-panel.d.ts +6 -8
- package/dist/detail-panel.d.ts.map +1 -0
- package/dist/detail-panel.js +3 -3
- package/dist/dialog.cjs.map +1 -1
- package/dist/dialog.d.ts +6 -8
- package/dist/dialog.d.ts.map +1 -0
- package/dist/dropdown-menu.cjs.map +1 -1
- package/dist/dropdown-menu.d.ts +5 -7
- package/dist/dropdown-menu.d.ts.map +1 -0
- package/dist/financing-widget.cjs +1 -3
- package/dist/financing-widget.cjs.map +1 -1
- package/dist/financing-widget.d.ts +5 -6
- package/dist/financing-widget.d.ts.map +1 -0
- package/dist/financing-widget.js +1 -3
- package/dist/financing-widget.js.map +1 -1
- package/dist/form-field.cjs.map +1 -1
- package/dist/form-field.d.ts +4 -5
- package/dist/form-field.d.ts.map +1 -0
- package/dist/form-input.cjs.map +1 -1
- package/dist/form-input.d.ts +4 -5
- package/dist/form-input.d.ts.map +1 -0
- package/dist/form-select.cjs.map +1 -1
- package/dist/form-select.d.ts +4 -5
- package/dist/form-select.d.ts.map +1 -0
- package/dist/form-textarea.cjs.map +1 -1
- package/dist/form-textarea.d.ts +4 -5
- package/dist/form-textarea.d.ts.map +1 -0
- package/dist/gtm.cjs +3 -2
- package/dist/gtm.cjs.map +1 -1
- package/dist/gtm.d.ts +12 -15
- package/dist/gtm.d.ts.map +1 -0
- package/dist/gtm.js +2 -1
- package/dist/input.cjs.map +1 -1
- package/dist/input.d.ts +4 -5
- package/dist/input.d.ts.map +1 -0
- package/dist/label.cjs.map +1 -1
- package/dist/label.d.ts +5 -7
- package/dist/label.d.ts.map +1 -0
- package/dist/list-view.cjs.map +1 -1
- package/dist/list-view.d.ts +5 -7
- package/dist/list-view.d.ts.map +1 -0
- package/dist/mdx-components.cjs +5 -2
- package/dist/mdx-components.cjs.map +1 -1
- package/dist/mdx-components.d.ts +11 -6
- package/dist/mdx-components.d.ts.map +1 -0
- package/dist/mdx-components.js +5 -2
- package/dist/mdx-components.js.map +1 -1
- package/dist/navigation-menu.cjs.map +1 -1
- package/dist/navigation-menu.d.ts +5 -7
- package/dist/navigation-menu.d.ts.map +1 -0
- package/dist/pagination.cjs +3 -2
- package/dist/pagination.cjs.map +1 -1
- package/dist/pagination.d.ts +10 -14
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +2 -1
- package/dist/payment-modal.cjs +20 -19
- package/dist/payment-modal.cjs.map +1 -1
- package/dist/payment-modal.d.ts +5 -7
- package/dist/payment-modal.d.ts.map +1 -0
- package/dist/payment-modal.js +19 -18
- package/dist/payment-modal.js.map +1 -1
- package/dist/popover.cjs.map +1 -1
- package/dist/popover.d.ts +4 -5
- package/dist/popover.d.ts.map +1 -0
- package/dist/price-format.cjs +27 -5
- package/dist/price-format.cjs.map +1 -1
- package/dist/price-format.d.ts +4 -5
- package/dist/price-format.d.ts.map +1 -0
- package/dist/price-format.js +26 -4
- package/dist/price-format.js.map +1 -1
- package/dist/price.cjs +34 -5
- package/dist/price.cjs.map +1 -1
- package/dist/price.d.ts +8 -10
- package/dist/price.d.ts.map +1 -0
- package/dist/price.js +32 -3
- package/dist/price.js.map +1 -1
- package/dist/provider.cjs +4 -2
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.ts +7 -10
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +3 -1
- package/dist/provider.js.map +1 -1
- package/dist/quantity-input.cjs +27 -40
- package/dist/quantity-input.cjs.map +1 -1
- package/dist/quantity-input.d.ts +4 -5
- package/dist/quantity-input.d.ts.map +1 -0
- package/dist/quantity-input.js +27 -40
- package/dist/quantity-input.js.map +1 -1
- package/dist/radio-group.cjs.map +1 -1
- package/dist/radio-group.d.ts +3 -4
- package/dist/radio-group.d.ts.map +1 -0
- package/dist/resource-tabs.cjs +1 -0
- package/dist/resource-tabs.cjs.map +1 -1
- package/dist/resource-tabs.d.ts +6 -8
- package/dist/resource-tabs.d.ts.map +1 -0
- package/dist/resource-tabs.js +1 -0
- package/dist/resource-tabs.js.map +1 -1
- package/dist/rules.d.ts +210 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/select.cjs.map +1 -1
- package/dist/select.d.ts +4 -5
- package/dist/select.d.ts.map +1 -0
- package/dist/separator.cjs.map +1 -1
- package/dist/separator.d.ts +3 -4
- package/dist/separator.d.ts.map +1 -0
- package/dist/session-replay.cjs +4 -2
- package/dist/session-replay.cjs.map +1 -1
- package/dist/session-replay.d.ts +4 -5
- package/dist/session-replay.d.ts.map +1 -0
- package/dist/session-replay.js +4 -2
- package/dist/session-replay.js.map +1 -1
- package/dist/skeleton.cjs.map +1 -1
- package/dist/skeleton.d.ts +2 -4
- package/dist/skeleton.d.ts.map +1 -0
- package/dist/spinner.cjs.map +1 -1
- package/dist/spinner.d.ts +2 -4
- package/dist/spinner.d.ts.map +1 -0
- package/dist/stock-label.cjs +14 -12
- package/dist/stock-label.cjs.map +1 -1
- package/dist/stock-label.d.ts +7 -7
- package/dist/stock-label.d.ts.map +1 -0
- package/dist/stock-label.js +14 -12
- package/dist/stock-label.js.map +1 -1
- package/dist/table.cjs.map +1 -1
- package/dist/table.d.ts +3 -4
- package/dist/table.d.ts.map +1 -0
- package/dist/tabs.cjs.map +1 -1
- package/dist/tabs.d.ts +4 -5
- package/dist/tabs.d.ts.map +1 -0
- package/dist/textarea.cjs.map +1 -1
- package/dist/textarea.d.ts +4 -5
- package/dist/textarea.d.ts.map +1 -0
- package/llms.txt +23 -38
- package/package.json +26 -17
- package/dist/accordion.d.cts +0 -9
- package/dist/add-to-cart-button.d.cts +0 -14
- package/dist/breadcrumb.d.cts +0 -22
- package/dist/breadcrumbs.d.cts +0 -31
- package/dist/button.d.cts +0 -27
- package/dist/card.d.cts +0 -10
- package/dist/checkbox.d.cts +0 -6
- package/dist/chunk-3VN3FX2Q.js.map +0 -1
- package/dist/chunk-AE4GLYJE.cjs.map +0 -1
- package/dist/chunk-DCXYO3RB.js.map +0 -1
- package/dist/chunk-DZDC4HHK.js +0 -33
- package/dist/chunk-DZDC4HHK.js.map +0 -1
- package/dist/chunk-NSSX7USQ.cjs.map +0 -1
- package/dist/chunk-VLZDTWPR.cjs +0 -33
- package/dist/chunk-VLZDTWPR.cjs.map +0 -1
- package/dist/command.d.cts +0 -84
- package/dist/confirm-dialog.d.cts +0 -35
- package/dist/data-table.d.cts +0 -55
- package/dist/detail-panel.d.cts +0 -59
- package/dist/dialog.d.cts +0 -22
- package/dist/dropdown-menu.d.cts +0 -30
- package/dist/financing-widget.d.cts +0 -45
- package/dist/form-field.d.cts +0 -14
- package/dist/form-input.d.cts +0 -19
- package/dist/form-select.d.cts +0 -34
- package/dist/form-textarea.d.cts +0 -12
- package/dist/gtm.d.cts +0 -69
- package/dist/input.d.cts +0 -6
- package/dist/label.d.cts +0 -8
- package/dist/list-view.d.cts +0 -18
- package/dist/mdx-components.d.cts +0 -20
- package/dist/navigation-menu.d.cts +0 -15
- package/dist/pagination.d.cts +0 -50
- package/dist/payment-modal.d.cts +0 -30
- package/dist/popover.d.cts +0 -9
- package/dist/price-format.d.cts +0 -21
- package/dist/price.d.cts +0 -78
- package/dist/provider.d.cts +0 -47
- package/dist/quantity-input.d.cts +0 -33
- package/dist/radio-group.d.cts +0 -7
- package/dist/resource-tabs.d.cts +0 -33
- package/dist/select.d.cts +0 -15
- package/dist/separator.d.cts +0 -6
- package/dist/session-replay.d.cts +0 -44
- package/dist/skeleton.d.cts +0 -5
- package/dist/spinner.d.cts +0 -10
- package/dist/stock-label.d.cts +0 -47
- package/dist/table.d.cts +0 -12
- package/dist/tabs.d.cts +0 -9
- package/dist/textarea.d.cts +0 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../src/card.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,QAAA,MAAM,IAAI,6GAQT,CAAC;AAGF,QAAA,MAAM,UAAU,6GAIf,CAAC;AAGF,QAAA,MAAM,SAAS,uHAQd,CAAC;AAGF,QAAA,MAAM,eAAe,yHAKnB,CAAC;AAGH,QAAA,MAAM,WAAW,6GAIhB,CAAC;AAGF,QAAA,MAAM,UAAU,6GAIf,CAAC;AAGF,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC"}
|
package/dist/checkbox.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/checkbox.cjs"],"names":[],"mappings":"AAAA,qFAAY;AACZ,YAAY;AACZ;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,8CAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/checkbox.cjs"}
|
package/dist/checkbox.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import * as CheckboxPrimitive from
|
|
3
|
-
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
4
3
|
declare const Checkbox: React.ForwardRefExoticComponent<Omit<CheckboxPrimitive.CheckboxProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
-
|
|
6
4
|
export { Checkbox };
|
|
5
|
+
//# sourceMappingURL=checkbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../src/checkbox.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAI9D,QAAA,MAAM,QAAQ,iKAgBZ,CAAC;AAGH,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-32XB3REY.cjs","../src/form-input.tsx"],"names":[],"mappings":"AAAA,2cAAY;AACZ;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACNA,2EAAuB;AACvB,sDAAmB;AA+BX,+CAAA;AAZR,IAAM,UAAA,EAAkB,KAAA,CAAA,UAAA;AAAA,EACtB,CAAC,EAAE,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,SAAA,EAAW,EAAA,EAAI,IAAA,EAAM,GAAG,MAAM,CAAA,EAAG,GAAA,EAAA,GAAQ;AAC5E,IAAA,MAAM,QAAA,oCAAU,EAAA,UAAM,MAAA,UAAQ,IAAA;AAE9B,IAAA,uBACE,6BAAA;AAAA,MAAC,2BAAA;AAAA,MAAA;AAAA,QACC,KAAA;AAAA,QACA,OAAA;AAAA,QACA,QAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA,EAAW,qBAAA,QAAG,EAAU,SAAS,CAAA;AAAA,QAEjC,QAAA,kBAAA,6BAAA,uBAAC,EAAA,EAAM,GAAA,EAAU,EAAA,EAAI,OAAA,EAAS,IAAA,EAAa,GAAG,MAAA,CAAO;AAAA,MAAA;AAAA,IACvD,CAAA;AAAA,EAEJ;AACF,CAAA;AACA,SAAA,CAAU,YAAA,EAAc,WAAA;ADVxB;AACA;AACE;AACF,8BAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-32XB3REY.cjs","sourcesContent":[null,"\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { FormField } from \"./form-field\";\nimport { Input } from \"./input\";\n\nexport interface FormInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label: string;\n error?: string;\n required?: boolean;\n gridSpan?: string;\n}\n\n/**\n * Labeled text input with error display. Composes FormField + Input.\n *\n * @example\n * ```tsx\n * <FormInput label=\"Email\" name=\"email\" type=\"email\" required error={errors.email} />\n * ```\n */\nconst FormInput = React.forwardRef<HTMLInputElement, FormInputProps>(\n ({ label, error, required, gridSpan, className, id, name, ...props }, ref) => {\n const htmlFor = id ?? name ?? \"\";\n\n return (\n <FormField\n label={label}\n htmlFor={htmlFor}\n required={required}\n error={error}\n className={cn(gridSpan, className)}\n >\n <Input ref={ref} id={htmlFor} name={name} {...props} />\n </FormField>\n );\n },\n);\nFormInput.displayName = \"FormInput\";\n\nexport { FormInput };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-5VMEEKZ5.cjs","../src/spinner.tsx"],"names":[],"mappings":"AAAA,qFAAY;AACZ;AACA;ACFA,sDAAmB;AAgBf,+CAAA;AATJ,IAAM,YAAA,EAAc;AAAA,EAClB,EAAA,EAAI,SAAA;AAAA,EACJ,EAAA,EAAI,SAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAGA,IAAM,QAAA,EAAU,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,KAAK,CAAA,EAAA,GAAoB;AAC5D,EAAA,uBACE,8BAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,qBAAA,cAAG,EAAgB,WAAA,CAAY,IAAI,CAAA,EAAG,SAAS,CAAA;AAAA,MAC1D,KAAA,EAAM,4BAAA;AAAA,MACN,IAAA,EAAK,MAAA;AAAA,MACL,OAAA,EAAQ,WAAA;AAAA,MAER,QAAA,EAAA;AAAA,wBAAA,6BAAA,QAAC,EAAA,EAAO,SAAA,EAAU,YAAA,EAAa,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,CAAA,EAAE,IAAA,EAAK,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,IAAA,CAAI,CAAA;AAAA,wBAC5F,6BAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,YAAA;AAAA,YACV,IAAA,EAAK,cAAA;AAAA,YACL,CAAA,EAAE;AAAA,UAAA;AAAA,QACJ;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,CAAA;AAEJ,CAAA;ADEA;AACA;AACE;AACF,0BAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-5VMEEKZ5.cjs","sourcesContent":[null,"import { cn } from \"@simpleapps-com/augur-utils/web\";\n\ninterface SpinnerProps {\n className?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n}\n\nconst sizeClasses = {\n sm: \"h-3 w-3\",\n md: \"h-4 w-4\",\n lg: \"h-6 w-6\",\n};\n\n/** Animated SVG loading spinner. Sizes: `sm` (12px), `md` (16px), `lg` (24px). */\nconst Spinner = ({ className, size = \"md\" }: SpinnerProps) => {\n return (\n <svg\n className={cn(\"animate-spin\", sizeClasses[size], className)}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"m4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n );\n};\n\nexport { Spinner };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-5ZITWMV4.cjs","../src/textarea.tsx"],"names":[],"mappings":"AAAA,uWAAY;AACZ;AACA;ACCA,2EAAuB;AACvB,sDAAmB;AAOb,+CAAA;AAHN,IAAM,SAAA,EAAiB,KAAA,CAAA,UAAA;AAAA,EACrB,CAAC,EAAE,SAAA,EAAW,GAAG,MAAM,CAAA,EAAG,GAAA,EAAA,GAAQ;AAChC,IAAA,uBACE,6BAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,qBAAA;AAAA,UACT,8PAAA;AAAA,UACA;AAAA,QACF,CAAA;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA,MAAA;AAAA,IACN,CAAA;AAAA,EAEJ;AACF,CAAA;AACA,QAAA,CAAS,YAAA,EAAc,UAAA;ADAvB;AACA;AACE;AACF,4BAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-5ZITWMV4.cjs","sourcesContent":[null,"/** Styled textarea with focus ring and disabled state. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\n\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"border-input placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[60px] w-full rounded-md border bg-transparent px-3 py-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-76RSVRGB.cjs","../src/select.tsx"],"names":[],"mappings":"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","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-76RSVRGB.cjs","sourcesContent":[null,"/** Styled wrapper around @radix-ui/react-select. See https://www.radix-ui.com/primitives/docs/components/select */\n\"use client\";\n\nimport * as React from \"react\";\nimport { LuChevronsUpDown, LuCheck, LuChevronDown, LuChevronUp } from \"react-icons/lu\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\n\nconst Select = SelectPrimitive.Root;\nconst SelectGroup = SelectPrimitive.Group;\nconst SelectValue = SelectPrimitive.Value;\n\nconst SelectTrigger = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n \"border-input ring-offset-background placeholder:text-muted-foreground focus:ring-ring flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-transparent px-3 py-2 text-sm shadow-sm focus:outline-none focus:ring-1 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <LuChevronsUpDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst SelectScrollUpButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton\n ref={ref}\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <LuChevronUp />\n </SelectPrimitive.ScrollUpButton>\n));\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst SelectScrollDownButton = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton\n ref={ref}\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <LuChevronDown />\n </SelectPrimitive.ScrollDownButton>\n));\nSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;\n\nconst SelectContent = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = \"popper\", ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border shadow-md\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst SelectLabel = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"px-2 py-1.5 text-sm font-semibold\", className)}\n {...props}\n />\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst SelectItem = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <LuCheck className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst SelectSeparator = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"bg-muted -mx-1 my-1 h-px\", className)}\n {...props}\n />\n));\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-7EXXNELX.cjs","../src/input.tsx"],"names":[],"mappings":"AAAA,uWAAY;AACZ;AACA;ACCA,2EAAuB;AACvB,sDAAmB;AAOb,+CAAA;AAHN,IAAM,MAAA,EAAc,KAAA,CAAA,UAAA;AAAA,EAClB,CAAC,EAAE,SAAA,EAAW,IAAA,EAAM,GAAG,MAAM,CAAA,EAAG,GAAA,EAAA,GAAQ;AACtC,IAAA,uBACE,6BAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,SAAA,EAAW,qBAAA;AAAA,UACT,uUAAA;AAAA,UACA;AAAA,QACF,CAAA;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA,MAAA;AAAA,IACN,CAAA;AAAA,EAEJ;AACF,CAAA;AACA,KAAA,CAAM,YAAA,EAAc,OAAA;ADApB;AACA;AACE;AACF,sBAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-7EXXNELX.cjs","sourcesContent":[null,"/** Styled text input with focus ring and disabled state. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\n\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-BXMTQGKV.cjs","../src/form-field.tsx"],"names":[],"mappings":"AAAA,uWAAY;AACZ;AACE;AACF,wDAA6B;AAC7B;AACA;ACHA,2EAAuB;AACvB,sDAAmB;AAiBX,+CAAA;AAJR,IAAM,UAAA,EAAkB,KAAA,CAAA,UAAA;AAAA,EACtB,CAAC,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,SAAA,EAAW,SAAS,CAAA,EAAG,GAAA,EAAA,GAAQ;AACjE,IAAA,uBACE,8BAAA,KAAC,EAAA,EAAI,GAAA,EAAU,SAAA,EAAW,qBAAA,WAAG,EAAa,SAAS,CAAA,EACjD,QAAA,EAAA;AAAA,sBAAA,8BAAA,uBAAC,EAAA,EAAM,OAAA,EACJ,QAAA,EAAA;AAAA,QAAA,KAAA;AAAA,QACA,SAAA,mBAAY,6BAAA,MAAC,EAAA,EAAK,SAAA,EAAU,kBAAA,EAAmB,QAAA,EAAA,IAAA,CAAC;AAAA,MAAA,EAAA,CACnD,CAAA;AAAA,MACC,QAAA;AAAA,MACA,MAAA,mBAAS,6BAAA,GAAC,EAAA,EAAE,SAAA,EAAU,0BAAA,EAA4B,QAAA,EAAA,MAAA,CAAM;AAAA,IAAA,EAAA,CAC3D,CAAA;AAAA,EAEJ;AACF,CAAA;AACA,SAAA,CAAU,YAAA,EAAc,WAAA;ADRxB;AACA;AACE;AACF,8BAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-BXMTQGKV.cjs","sourcesContent":[null,"\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Label } from \"./label\";\n\nexport interface FormFieldProps {\n label: string;\n htmlFor: string;\n required?: boolean;\n error?: string;\n className?: string;\n children: React.ReactNode;\n}\n\n/** Base form layout: label + children + optional error message. */\nconst FormField = React.forwardRef<HTMLDivElement, FormFieldProps>(\n ({ label, htmlFor, required, error, className, children }, ref) => {\n return (\n <div ref={ref} className={cn(\"space-y-2\", className)}>\n <Label htmlFor={htmlFor}>\n {label}\n {required && <span className=\"text-destructive\">*</span>}\n </Label>\n {children}\n {error && <p className=\"text-destructive text-sm\">{error}</p>}\n </div>\n );\n },\n);\nFormField.displayName = \"FormField\";\n\nexport { FormField };\n"]}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
+
|
|
3
|
+
// ../utils/src/strings.ts
|
|
4
|
+
function codeAt(s, i) {
|
|
5
|
+
return i >= 0 && i < s.length ? s.charCodeAt(i) : -1;
|
|
6
|
+
}
|
|
7
|
+
function indexOfCode(s, code, from) {
|
|
8
|
+
const c = codeAt(s, from);
|
|
9
|
+
if (c === code) return from;
|
|
10
|
+
if (c === -1) return -1;
|
|
11
|
+
return indexOfCode(s, code, from + 1);
|
|
12
|
+
}
|
|
13
|
+
function startsWithAt(s, x, pos) {
|
|
14
|
+
const at = Math.min(pos, s.length);
|
|
15
|
+
return s.slice(at, Math.min(at + x.length, s.length)) === x;
|
|
16
|
+
}
|
|
17
|
+
function untilCode(s, code) {
|
|
18
|
+
const k = indexOfCode(s, code, 0);
|
|
19
|
+
return k >= 0 ? s.slice(0, k) : s;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ../utils/src/replace.ts
|
|
23
|
+
function codeIndex(codes, c, i) {
|
|
24
|
+
if (i === codes.length) return -1;
|
|
25
|
+
return codes[i] === c ? i : codeIndex(codes, c, i + 1);
|
|
26
|
+
}
|
|
27
|
+
function substitute(s, codes, texts) {
|
|
28
|
+
let out = "";
|
|
29
|
+
for (let i = 0; i !== s.length; i++) {
|
|
30
|
+
const k = codeIndex(codes, s.charCodeAt(i), 0);
|
|
31
|
+
out = k >= 0 && k < texts.length ? out + texts[k] : out + s.slice(i, i + 1);
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function replaceCode(s, from, to) {
|
|
36
|
+
return substitute(s, [from], [to]);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/rules.ts
|
|
40
|
+
function pageRangeFrom(total, i) {
|
|
41
|
+
if (i >= total) return [];
|
|
42
|
+
return [{ kind: "page", n: i + 1 }, ...pageRangeFrom(total, i + 1)];
|
|
43
|
+
}
|
|
44
|
+
function pageNumbersOf(current, total) {
|
|
45
|
+
if (total <= 0) return [];
|
|
46
|
+
if (total === 1) return [{ kind: "page", n: 1 }];
|
|
47
|
+
const page = clampPage(current, total);
|
|
48
|
+
if (total <= 5) return pageRangeFrom(total, 0);
|
|
49
|
+
const first = { kind: "page", n: 1 };
|
|
50
|
+
const last = { kind: "page", n: total };
|
|
51
|
+
const gap = { kind: "ellipsis" };
|
|
52
|
+
if (page <= 3) {
|
|
53
|
+
return [
|
|
54
|
+
first,
|
|
55
|
+
{ kind: "page", n: 2 },
|
|
56
|
+
{ kind: "page", n: 3 },
|
|
57
|
+
{ kind: "page", n: 4 },
|
|
58
|
+
gap,
|
|
59
|
+
last
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
if (page >= total - 2) {
|
|
63
|
+
return [
|
|
64
|
+
first,
|
|
65
|
+
gap,
|
|
66
|
+
{ kind: "page", n: total - 3 },
|
|
67
|
+
{ kind: "page", n: total - 2 },
|
|
68
|
+
{ kind: "page", n: total - 1 },
|
|
69
|
+
last
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
return [
|
|
73
|
+
first,
|
|
74
|
+
gap,
|
|
75
|
+
{ kind: "page", n: page - 1 },
|
|
76
|
+
{ kind: "page", n: page },
|
|
77
|
+
{ kind: "page", n: page + 1 },
|
|
78
|
+
gap,
|
|
79
|
+
last
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
function clampPage(current, total) {
|
|
83
|
+
const capped = current > total ? total : current;
|
|
84
|
+
return capped < 1 ? 1 : capped;
|
|
85
|
+
}
|
|
86
|
+
function isFirstPage(page) {
|
|
87
|
+
return page <= 1;
|
|
88
|
+
}
|
|
89
|
+
function isLastPage(page, totalPages) {
|
|
90
|
+
return page >= totalPages;
|
|
91
|
+
}
|
|
92
|
+
function prevTarget(page) {
|
|
93
|
+
return isFirstPage(page) ? 1 : page - 1;
|
|
94
|
+
}
|
|
95
|
+
function nextTarget(page, totalPages) {
|
|
96
|
+
return isLastPage(page, totalPages) ? totalPages : page + 1;
|
|
97
|
+
}
|
|
98
|
+
function clampQuantity(value, min, max) {
|
|
99
|
+
const atLeast = value < min ? min : value;
|
|
100
|
+
if (max === void 0) return atLeast;
|
|
101
|
+
return atLeast > max ? max : atLeast;
|
|
102
|
+
}
|
|
103
|
+
function stepDown(value, step, min) {
|
|
104
|
+
return value - step > min ? value - step : min;
|
|
105
|
+
}
|
|
106
|
+
function stepUp(value, step, max) {
|
|
107
|
+
if (max === void 0) return value + step;
|
|
108
|
+
return value + step > max ? max : value + step;
|
|
109
|
+
}
|
|
110
|
+
function decreaseDisabled(disabled, value, min) {
|
|
111
|
+
return disabled || value <= min;
|
|
112
|
+
}
|
|
113
|
+
function increaseDisabled(disabled, value, max) {
|
|
114
|
+
if (max === void 0) return disabled;
|
|
115
|
+
return disabled || value >= max;
|
|
116
|
+
}
|
|
117
|
+
function digitKey(key) {
|
|
118
|
+
const c = codeAt(key, 0);
|
|
119
|
+
return c >= 48 && c <= 56 || key === "9";
|
|
120
|
+
}
|
|
121
|
+
function editingKey(key) {
|
|
122
|
+
return key === "Backspace" || key === "Delete" || key === "ArrowLeft" || key === "ArrowRight" || key === "Tab" || key === "Enter";
|
|
123
|
+
}
|
|
124
|
+
function keyAllowed(key, decimals, hasDot) {
|
|
125
|
+
return editingKey(key) || decimals > 0 && key === "." && !hasDot || digitKey(key);
|
|
126
|
+
}
|
|
127
|
+
function cleanQtyFrom(raw, allowDot, seenDot, i) {
|
|
128
|
+
if (i >= raw.length) return "";
|
|
129
|
+
const c = codeAt(raw, i);
|
|
130
|
+
if (c >= 48 && c <= 57) return raw.slice(i, i + 1) + cleanQtyFrom(raw, allowDot, seenDot, i + 1);
|
|
131
|
+
if (allowDot && c === 46 && !seenDot) return "." + cleanQtyFrom(raw, allowDot, true, i + 1);
|
|
132
|
+
return cleanQtyFrom(raw, allowDot, seenDot, i + 1);
|
|
133
|
+
}
|
|
134
|
+
function stockViewOf(loading, isInStock, isLowStock) {
|
|
135
|
+
if (loading) return "loading";
|
|
136
|
+
if (!isInStock) return "out-of-stock";
|
|
137
|
+
return isLowStock ? "low-stock" : "in-stock";
|
|
138
|
+
}
|
|
139
|
+
function showStockQuantity(view, hasQuantity) {
|
|
140
|
+
return hasQuantity && view !== "out-of-stock" && view !== "loading";
|
|
141
|
+
}
|
|
142
|
+
function priceViewOf(loading, valueIsZero, hasOriginal) {
|
|
143
|
+
if (loading) return "skeleton";
|
|
144
|
+
if (valueIsZero && !hasOriginal) return "zero-label";
|
|
145
|
+
return "amount";
|
|
146
|
+
}
|
|
147
|
+
function needsQuotes(s) {
|
|
148
|
+
return indexOfCode(s, 44, 0) >= 0 || indexOfCode(s, 34, 0) >= 0 || indexOfCode(s, 10, 0) >= 0;
|
|
149
|
+
}
|
|
150
|
+
function csvField(s) {
|
|
151
|
+
if (!needsQuotes(s)) return s;
|
|
152
|
+
return '"' + replaceCode(s, 34, '""') + '"';
|
|
153
|
+
}
|
|
154
|
+
function ariaSortOf(sortable, dir) {
|
|
155
|
+
if (!sortable) return void 0;
|
|
156
|
+
if (dir === "asc") return "ascending";
|
|
157
|
+
if (dir === "desc") return "descending";
|
|
158
|
+
return "none";
|
|
159
|
+
}
|
|
160
|
+
function alignClass(align) {
|
|
161
|
+
if (align === "left") return "text-left";
|
|
162
|
+
if (align === "center") return "text-center";
|
|
163
|
+
return align === "right" ? "text-right" : "";
|
|
164
|
+
}
|
|
165
|
+
function bodyViewOf(loading, rowCount) {
|
|
166
|
+
if (loading) return "loading";
|
|
167
|
+
return rowCount === 0 ? "empty" : "rows";
|
|
168
|
+
}
|
|
169
|
+
function gtmTiming(strategy, hasIdleCallback) {
|
|
170
|
+
if (strategy === "lazyOnload" && hasIdleCallback) return "idle";
|
|
171
|
+
return strategy === "afterInteractive" ? "next-tick" : "now";
|
|
172
|
+
}
|
|
173
|
+
function replaySampled(disabled, injected, rate, draw) {
|
|
174
|
+
return !disabled && !injected && !(rate < 1 && draw > rate);
|
|
175
|
+
}
|
|
176
|
+
function binMarkAt(s, k) {
|
|
177
|
+
const c = codeAt(s, k);
|
|
178
|
+
const v = codeAt(s, k + 5);
|
|
179
|
+
return (c === 63 || c === 38) && startsWithAt(s, "Bin=", k + 1) && v >= 0 && v !== 38;
|
|
180
|
+
}
|
|
181
|
+
function binAt(s, i) {
|
|
182
|
+
if (i + 6 > s.length) return -1;
|
|
183
|
+
if (binMarkAt(s, i)) return i;
|
|
184
|
+
return binAt(s, i + 1);
|
|
185
|
+
}
|
|
186
|
+
function binFromString(s) {
|
|
187
|
+
const k = binAt(s, 0);
|
|
188
|
+
if (k < 0) return void 0;
|
|
189
|
+
return untilCode(afterBinMark(s, k), 38);
|
|
190
|
+
}
|
|
191
|
+
function afterBinMark(s, k) {
|
|
192
|
+
if (k < 0 || k + 5 > s.length) return "";
|
|
193
|
+
return s.slice(k + 5);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
exports.pageNumbersOf = pageNumbersOf; exports.isFirstPage = isFirstPage; exports.isLastPage = isLastPage; exports.prevTarget = prevTarget; exports.nextTarget = nextTarget; exports.clampQuantity = clampQuantity; exports.stepDown = stepDown; exports.stepUp = stepUp; exports.decreaseDisabled = decreaseDisabled; exports.increaseDisabled = increaseDisabled; exports.keyAllowed = keyAllowed; exports.cleanQtyFrom = cleanQtyFrom; exports.stockViewOf = stockViewOf; exports.showStockQuantity = showStockQuantity; exports.priceViewOf = priceViewOf; exports.csvField = csvField; exports.ariaSortOf = ariaSortOf; exports.alignClass = alignClass; exports.bodyViewOf = bodyViewOf; exports.gtmTiming = gtmTiming; exports.replaySampled = replaySampled; exports.binFromString = binFromString;
|
|
220
|
+
//# sourceMappingURL=chunk-EEJYDSXR.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-EEJYDSXR.cjs","../../utils/src/strings.ts","../../utils/src/replace.ts","../src/rules.ts"],"names":[],"mappings":"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","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-EEJYDSXR.cjs","sourcesContent":[null,"//@ backend dafny\nimport {\n isAlnumChar,\n isBase64UrlChar,\n isDigit,\n isHexChar,\n isJsSpace,\n isLineTerminator,\n isLowerHexChar,\n isSnakeChar,\n isWordChar,\n lowerCode,\n} from \"./chars\";\n\n/* String scans and slices, verified with LemmaScript → Dafny (hand lemmas in strings.dfy;\n model: models/Utils.dfy; link: models/links/utils-strings.dfy). Recursive and\n expression-bodied so specs can use them, and each contract pins the result exactly, so\n an importer (which sees only the contract) knows what it returns. Two of them stand in\n for constructs lsc mistranslates: `prefix` for an unclamped `slice`, and the code-unit\n scans for \"\\r\" / \"\\n\" literals. */\n\n/**\n * The code unit at `i`, or -1 when `i` is outside `s`. JS `charCodeAt` gives NaN there,\n * which no code equals, so a scan's own bounds test would change no result and no test\n * could tell it from none (an equivalent mutant); with the bound here once, the boundary is\n * observable (tests pin -1) and the scans that use it carry no bound of their own. A code\n * unit is never negative, so -1 matches no `code` a caller passes (`requires code >= 0`).\n *\n * @ensures 0 ≤ i < |s| ⟹ result = s[i]; otherwise result = -1\n */\nexport function codeAt(s: string, i: number): number {\n //@ verify\n //@ ensures (i >= 0 && i < s.length) ==> \\result === s.charCodeAt(i)\n //@ ensures !(i >= 0 && i < s.length) ==> \\result === -1\n return i >= 0 && i < s.length ? s.charCodeAt(i) : -1;\n}\n\n/**\n * Every character of `s` from index `i` on is base64url.\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). isBase64UrlChar(s[k])\n */\nexport function base64UrlFrom(s: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> isBase64UrlChar(s.charCodeAt(k)))\n return i >= s.length || (isBase64UrlChar(s.charCodeAt(i)) && base64UrlFrom(s, i + 1));\n}\n\n/**\n * The base64url digit for `v` (RFC 4648 §5): A-Z a-z 0-9 - _.\n *\n * @ensures exactly the model's Base64UrlDigit\n */\nexport function base64UrlDigit(v: number): string {\n //@ verify\n //@ type v nat\n //@ requires v >= 0 && v < 64\n //@ ensures \\result === \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\".slice(v, v + 1)\n return \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\".slice(v, v + 1);\n}\n\n/**\n * Bytes from `i` on as unpadded base64url: each three as four digits, a last one or two as two or\n * three (JS `btoa` with `+/` as `-_` and the `=` dropped). One frame per three bytes: a JWT part\n * is a few hundred.\n *\n * @ensures exactly the model's Base64UrlFrom (links/utils-strings.dfy)\n */\nexport function encodeBase64UrlFrom(b: number[], i: number): string {\n //@ verify\n //@ type i nat\n //@ requires i >= 0 && forall(k: nat, k < b.length ==> (b[k] >= 0 && b[k] < 256))\n //@ decreases b.length - i\n //@ ensures i >= b.length ==> \\result === \"\"\n if (i >= b.length) return \"\";\n const x = b[i] as number;\n const first = base64UrlDigit(Math.floor(x / 4));\n if (i + 1 === b.length) return first + base64UrlDigit((x % 4) * 16);\n const y = b[i + 1] as number;\n const second = base64UrlDigit((x % 4) * 16 + Math.floor(y / 16));\n if (i + 2 === b.length) return first + second + base64UrlDigit((y % 16) * 4);\n const z = b[i + 2] as number;\n return (\n first +\n second +\n base64UrlDigit((y % 16) * 4 + Math.floor(z / 64)) +\n base64UrlDigit(z % 64) +\n encodeBase64UrlFrom(b, i + 3)\n );\n}\n\n/**\n * Every character of `s` from index `i` on is lowercase hex.\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). isLowerHexChar(s[k])\n */\nexport function lowerHexFrom(s: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> isLowerHexChar(s.charCodeAt(k)))\n return i >= s.length || (isLowerHexChar(s.charCodeAt(i)) && lowerHexFrom(s, i + 1));\n}\n\n/**\n * Every character of `s` from index `i` on is hex, either case.\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). isHexChar(s[k])\n */\nexport function hexFrom(s: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> isHexChar(s.charCodeAt(k)))\n return i >= s.length || (isHexChar(s.charCodeAt(i)) && hexFrom(s, i + 1));\n}\n\n/**\n * Every character of `s` from index `i` on is an ASCII digit (`\\d` without the `u` flag).\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). isDigit(s[k])\n */\nexport function digitsFrom(s: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> isDigit(s.charCodeAt(k)))\n return i >= s.length || (isDigit(s.charCodeAt(i)) && digitsFrom(s, i + 1));\n}\n\n/**\n * Every character of `s` from index `i` on is a word character (`\\w`: `[A-Za-z0-9_]`).\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). isWordChar(s[k])\n */\nexport function wordCharsFrom(s: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> isWordChar(s.charCodeAt(k)))\n return i >= s.length || (isWordChar(s.charCodeAt(i)) && wordCharsFrom(s, i + 1));\n}\n\n/**\n * Every character of `s` from index `i` on is a snake_case character (`[a-z0-9_]`).\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). isSnakeChar(s[k])\n */\nexport function snakeCharsFrom(s: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> isSnakeChar(s.charCodeAt(k)))\n return i >= s.length || (isSnakeChar(s.charCodeAt(i)) && snakeCharsFrom(s, i + 1));\n}\n\n/**\n * Every character of `s` from index `i` on is an ASCII letter or digit (`[A-Za-z0-9]`).\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). isAlnumChar(s[k])\n */\nexport function alnumFrom(s: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> isAlnumChar(s.charCodeAt(k)))\n return i >= s.length || (isAlnumChar(s.charCodeAt(i)) && alnumFrom(s, i + 1));\n}\n\n/**\n * Every character of `s` from index `i` on is an ASCII letter, digit or `-` (`[A-Za-z0-9-]`):\n * a domain label's tail, a service name's tail.\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). isAlnumChar(s[k]) ∨ s[k] = \"-\" — the model's AlnumDashFrom\n */\nexport function alnumDashFrom(s: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> (isAlnumChar(s.charCodeAt(k)) || s.charCodeAt(k) === 45))\n if (i >= s.length) return true;\n const c = s.charCodeAt(i);\n return (isAlnumChar(c) || c === 45) && alnumDashFrom(s, i + 1);\n}\n\n/**\n * The last index before `end` holding `code`, or -1 (JS `s.lastIndexOf(c)` at end = |s|).\n *\n * @ensures result = -1 ∨ (0 ≤ result < end ∧ s[result] = code ∧ no `code` in (result, end))\n */\nexport function lastIndexOfCode(s: string, code: number, end: number): number {\n //@ verify\n //@ type end nat\n //@ requires end <= s.length\n //@ decreases end\n //@ ensures \\result === -1 || (0 <= \\result && \\result < end)\n //@ ensures \\result >= 0 ==> s.charCodeAt(\\result) === code\n //@ ensures \\result >= 0 ==> forall(k: nat, (\\result < k && k < end) ==> s.charCodeAt(k) !== code)\n //@ ensures \\result === -1 ==> forall(k: nat, k < end ==> s.charCodeAt(k) !== code)\n if (end === 0) return -1;\n if (s.charCodeAt(end - 1) === code) return end - 1;\n return lastIndexOfCode(s, code, end - 1);\n}\n\n/**\n * No character of `s` from index `i` on is `code`.\n *\n * @ensures result ⟺ ∀ k ∈ [i, |s|). s[k] ≠ code\n */\nexport function lacksCode(s: string, code: number, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ requires i <= s.length\n //@ decreases s.length - i\n //@ ensures \\result <==> forall(k: nat, (i <= k && k < s.length) ==> s.charCodeAt(k) !== code)\n // `===`, not `>=`: past the end a read is NaN !== code, so `>=` vs `>` would be equivalent\n return i === s.length || (s.charCodeAt(i) !== code && lacksCode(s, code, i + 1));\n}\n\n/**\n * The end of the run of `code` starting at `i`: the first index ≥ i that isn't `code`\n * (skip spaces: `codeRunEnd(header, 32, i)`).\n *\n * @requires i ≤ |s|\n * @ensures i ≤ result ≤ |s| ∧ ∀ k ∈ [i, result). s[k] = code ∧ (result < |s| ⟹ s[result] ≠ code)\n * — exactly the run's end\n */\nexport function codeRunEnd(s: string, code: number, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires 0 <= i && i <= s.length\n //@ requires code >= 0\n //@ decreases s.length - i\n //@ ensures i <= \\result && \\result <= s.length\n //@ ensures forall(k: nat, (i <= k && k < \\result) ==> s.charCodeAt(k) === code)\n //@ ensures \\result < s.length ==> s.charCodeAt(\\result) !== code\n return codeAt(s, i) === code ? codeRunEnd(s, code, i + 1) : i;\n}\n\n/**\n * The first index ≥ `from` holding `code`, or -1 (`indexOf` for one code unit, so \"\\n\" is\n * passed as 10, never as a literal).\n *\n * @ensures result = -1 ∨ (from ≤ result < |s| ∧ s[result] = code), with no `code` in\n * [from, result) — the first one; result = -1 ⟹ none from `from` on\n */\nexport function indexOfCode(s: string, code: number, from: number): number {\n //@ verify\n //@ type from nat\n //@ requires code >= 0\n //@ decreases s.length - from\n //@ ensures \\result === -1 || (from <= \\result && \\result < s.length)\n //@ ensures \\result >= 0 ==> s.charCodeAt(\\result) === code\n //@ ensures \\result >= 0 ==> forall(k: nat, (from <= k && k < \\result) ==> s.charCodeAt(k) !== code)\n //@ ensures \\result === -1 ==> forall(k: nat, (from <= k && k < s.length) ==> s.charCodeAt(k) !== code)\n const c = codeAt(s, from);\n if (c === code) return from;\n if (c === -1) return -1;\n return indexOfCode(s, code, from + 1);\n}\n\n/**\n * The first index ≥ `i` holding `a` or `b`, or |s| (a run either code ends: a path segment's\n * run to \"/\" or \"?\"). One scan: the lesser of two `indexOfCode` ends is the same index, but\n * its two sides are equal only when both are |s|, a boundary no test can observe.\n *\n * @requires i ≤ |s|\n * @ensures i ≤ result ≤ |s| ∧ ∀ k ∈ [i, result). s[k] ∉ {a, b} ∧ (result < |s| ⟹ s[result] ∈ {a, b})\n * — exactly the first such index\n */\nexport function eitherCodeEnd(s: string, a: number, b: number, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires 0 <= i && i <= s.length\n //@ requires a >= 0 && b >= 0\n //@ decreases s.length - i\n //@ ensures i <= \\result && \\result <= s.length\n //@ ensures forall(k: nat, (i <= k && k < \\result) ==> (s.charCodeAt(k) !== a && s.charCodeAt(k) !== b))\n //@ ensures \\result < s.length ==> (s.charCodeAt(\\result) === a || s.charCodeAt(\\result) === b)\n const c = codeAt(s, i);\n if (c === -1 || c === a || c === b) return i;\n return eitherCodeEnd(s, a, b, i + 1);\n}\n\n/**\n * `s` without one trailing `code` (\"\\r\" before a \"\\n\", say); unchanged otherwise.\n *\n * @ensures s ends with code ⟹ result = s[0, |s| − 1)\n * @ensures otherwise result = s\n */\nexport function dropLast(s: string, code: number): string {\n //@ verify\n //@ requires code >= 0\n //@ ensures (s.length > 0 && s.charCodeAt(s.length - 1) === code) ==> \\result === s.slice(0, s.length - 1)\n //@ ensures !(s.length > 0 && s.charCodeAt(s.length - 1) === code) ==> \\result === s\n return codeAt(s, s.length - 1) === code ? s.slice(0, s.length - 1) : s;\n}\n\n/**\n * `s` without its leading `code` units (every one of them).\n *\n * @ensures exactly the model's LStripCode\n */\nexport function lStripCode(s: string, code: number): string {\n //@ verify\n //@ requires code >= 0\n //@ decreases s.length\n //@ ensures \\result.length <= s.length\n if (codeAt(s, 0) === code) return lStripCode(s.slice(1), code);\n return s;\n}\n\n/**\n * `s` without its trailing `code` units (every one of them).\n *\n * @ensures exactly the model's RStripCode\n */\nexport function rStripCode(s: string, code: number): string {\n //@ verify\n //@ requires code >= 0\n //@ decreases s.length\n //@ ensures \\result.length <= s.length\n if (codeAt(s, s.length - 1) === code) {\n return rStripCode(s.slice(0, s.length - 1), code);\n }\n return s;\n}\n\n/**\n * `s` without its leading and trailing `code` units, the middle kept (`/a/b/` with `/` →\n * `a/b`).\n *\n * @ensures exactly the model's StripCode — neither end is `code` (StripCodeTrims)\n */\nexport function stripCode(s: string, code: number): string {\n //@ verify\n //@ requires code >= 0\n //@ ensures \\result === rStripCode(lStripCode(s, code), code)\n return rStripCode(lStripCode(s, code), code);\n}\n\n/**\n * JS `s.startsWith(x, pos)`, which lsc mistranslates (it drops `pos`). Like JS, a `pos`\n * past the end counts as the end, so the empty string matches anywhere.\n *\n * @ensures pos ≤ |s| ⟹ (result ⟺ pos + |x| ≤ |s| ∧ s[pos, pos + |x|) = x) — so a true\n * result also gives the bounds for slicing after the match\n * @ensures pos > |s| ⟹ (result ⟺ x = \"\")\n */\nexport function startsWithAt(s: string, x: string, pos: number): boolean {\n //@ verify\n //@ type pos nat\n //@ requires pos >= 0\n //@ ensures pos <= s.length ==> (\\result <==> (pos + x.length <= s.length && s.slice(pos, pos + x.length) === x))\n //@ ensures pos > s.length ==> (\\result <==> x.length === 0)\n // Math.min, not a ternary: at pos = |s| both branches agree, so `<` vs `<=` is equivalent\n const at = Math.min(pos, s.length);\n // The slice is clamped to the end, so a too-long x differs by length: no separate fit test\n // (JS slice clamps too, which made one unobservable)\n return s.slice(at, Math.min(at + x.length, s.length)) === x;\n}\n\n/**\n * `s` with A-Z lowercased and every other character kept: what lsc's proofs take\n * `toLowerCase()` to be. JS's `toLowerCase()` also maps non-ASCII letters, some onto ASCII\n * (the Kelvin sign K, U+212A, becomes \"k\") or onto two characters (İ, U+0130), so a proved\n * function that lowercases MUST use this, or the runtime does what the proof says it\n * doesn't.\n *\n * @ensures result = s with A-Z lowercased — same length, every other character unchanged\n */\nexport function lowerAscii(s: string): string {\n //@ verify\n //@ decreases s.length\n //@ ensures \\result === s.toLowerCase()\n if (s.length === 0) return \"\";\n const c = s.charCodeAt(0);\n const head =\n c >= 65 && c <= 90 ? \"abcdefghijklmnopqrstuvwxyz\".slice(c - 65, c - 64) : s.slice(0, 1);\n return head + lowerAscii(s.slice(1));\n}\n\n/**\n * `lowerAscii` as a loop: a constant stack depth (and linear time) on long text, where the\n * recursive spec takes a frame and a slice per character.\n *\n * @ensures result = lowerAscii(s)\n */\nexport function lowerAsciiText(s: string): string {\n //@ verify\n //@ ensures \\result === lowerAscii(s)\n let out = \"\";\n let i = 0;\n while (i !== s.length) {\n //@ invariant 0 <= i && i <= s.length\n //@ invariant out + lowerAscii(s.slice(i)) === lowerAscii(s)\n //@ decreases s.length - i\n const c = s.charCodeAt(i);\n out =\n out +\n (c >= 65 && c <= 90 ? \"abcdefghijklmnopqrstuvwxyz\".slice(c - 65, c - 64) : s.slice(i, i + 1));\n i = i + 1;\n }\n return out;\n}\n\n/**\n * Whether `x` from index `k` matches `s` from `pos + k`, code by code, ASCII-lowered. A code\n * past the end of `s` is -1 (`codeAt`), which no code of `x` is, so there is no bound to\n * check (a `pos + |x| ≤ |s|` guard before a slice never changed the answer at runtime, where\n * `slice` clamps: an equivalent mutant, 2026-11-02).\n *\n * @ensures exactly the model's CaselessFrom\n */\nexport function caselessFrom(s: string, x: string, pos: number, k: number): boolean {\n //@ verify\n //@ type pos nat\n //@ type k nat\n //@ requires pos >= 0 && k >= 0 && k <= x.length\n //@ decreases x.length - k\n //@ ensures k === x.length ==> \\result\n if (k === x.length) return true;\n return lowerCode(codeAt(s, pos + k)) === x.charCodeAt(k) && caselessFrom(s, x, pos, k + 1);\n}\n\n/**\n * Whether the text of `s` at `pos`, ASCII-lowered, is `x` (`x` given lowercase): a case-free\n * `startsWith`; callers carry no length guard of their own. Only `pos ≤ |s|` is checked: it\n * decides an empty `x` past the end, the one case the code-by-code test can't see.\n *\n * @ensures result ⟺ pos + |x| ≤ |s| ∧ lowerAscii(s[pos, pos + |x|)) = x — Utils.StartsWithCaseless\n */\nexport function startsWithCaseless(s: string, x: string, pos: number): boolean {\n //@ verify\n //@ type pos nat\n //@ requires pos >= 0\n //@ ensures \\result <==> (pos + x.length <= s.length && s.slice(pos, pos + x.length).toLowerCase() === x)\n return pos <= s.length && caselessFrom(s, x, pos, 0);\n}\n\n/**\n * Whether `s` ends with `suffix` (JS one-argument `endsWith`, which lsc reads as its\n * two-argument form; moved from the augur-api generator 2026-11-01).\n *\n * @ensures result ⟺ |s| ≥ |suffix| ∧ s[|s| − |suffix|, |s|) = suffix — exactly the model's EndsWith\n */\nexport function endsWith(s: string, suffix: string): boolean {\n //@ verify\n //@ ensures \\result <==> (s.length >= suffix.length && s.slice(s.length - suffix.length) === suffix)\n // No length test: from max(|s| − |suffix|, 0), a too-long suffix compares unequal by length\n return s.slice(Math.max(s.length - suffix.length, 0)) === suffix;\n}\n\n/**\n * The order of `a` and `b` by UTF-16 code unit from index `i`, as a recursive spec: -1, 0\n * or 1 (JS `<` on strings; a proper prefix comes first). Locale-free, unlike `localeCompare`.\n *\n * @ensures result ∈ {-1, 0, 1} — exactly the model's CompareFrom\n */\nexport function compareFrom(a: string, b: string, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires i >= 0\n //@ decreases a.length - i\n //@ ensures \\result === -1 || \\result === 0 || \\result === 1\n if (i >= a.length) return i >= b.length ? 0 : -1;\n if (i >= b.length) return 1;\n const x = a.charCodeAt(i);\n const y = b.charCodeAt(i);\n if (x < y) return -1;\n if (x > y) return 1;\n return compareFrom(a, b, i + 1);\n}\n\n/**\n * The order of two strings by UTF-16 code unit, for `sort` (what the default `sort` uses on\n * strings), so sorted output never depends on locale.\n *\n * @ensures result = compareFrom(a, b, 0)\n */\nexport function compareCodeUnits(a: string, b: string): number {\n //@ verify\n //@ ensures \\result === compareFrom(a, b, 0)\n return compareFrom(a, b, 0);\n}\n\n/**\n * JS `s.slice(0, n)`: at most `n` characters, clamped to the length. lsc reads a bare\n * `slice(0, n)` without JS's clamp, so use this instead.\n *\n * @ensures result = s[0, min(n, |s|))\n */\nexport function prefix(s: string, n: number): string {\n //@ verify\n //@ type n nat\n //@ requires n >= 0\n //@ ensures n < s.length ==> \\result === s.slice(0, n)\n //@ ensures n >= s.length ==> \\result === s\n // Math.min, not a ternary: JS slice already clamps, so a ternary's branch is unobservable\n return s.slice(0, Math.min(n, s.length));\n}\n\n/**\n * The end of the JS-whitespace (`\\s`) run starting at `i`: the first index ≥ i that is not\n * whitespace, or |s|.\n *\n * @ensures i ≤ result ≤ |s| ∧ s[i, result) all whitespace ∧ (result = |s| ∨ ¬space(s[result]))\n */\nexport function spaceRunEnd(s: string, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires 0 <= i && i <= s.length\n //@ decreases s.length - i\n //@ ensures i <= \\result && \\result <= s.length\n //@ ensures forall(k: nat, (i <= k && k < \\result) ==> isJsSpace(s.charCodeAt(k)))\n //@ ensures \\result < s.length ==> !isJsSpace(s.charCodeAt(\\result))\n // codeAt is -1 at the end, which is no space: the bound needs no test of its own here\n if (!isJsSpace(codeAt(s, i))) return i;\n return spaceRunEnd(s, i + 1);\n}\n\n/**\n * A natural number written canonically (`^(0|[1-9][0-9]*)$`): the keys JS objects move\n * first, ahead of their source order.\n *\n * @ensures exactly the model's CanonicalNat, stated over the codes themselves so an importer\n * can use it (a contract naming `digitsFrom` can't be resolved there, models/LSC-GAPS.md)\n */\nexport function isCanonicalNat(s: string): boolean {\n //@ verify\n //@ ensures \\result <==> (s === \"0\" || (s.length > 0 && s.charCodeAt(0) >= 49 && s.charCodeAt(0) <= 57 && forall(k: nat, (1 <= k && k < s.length) ==> (s.charCodeAt(k) >= 48 && s.charCodeAt(k) <= 57))))\n if (s === \"0\") return true;\n const first = codeAt(s, 0);\n return first >= 49 && first <= 57 && digitsFrom(s, 1);\n}\n\n/**\n * The value of a run of decimal digits, most significant first (\"\" is 0).\n *\n * @requires ∀ k ∈ [0, |s|). isDigit(s[k])\n * @ensures exactly the model's DigitsValue (proved in links/utils-strings.dfy)\n */\nexport function digitsValue(s: string): number {\n //@ verify\n //@ requires forall(k: nat, k < s.length ==> (s.charCodeAt(k) >= 48 && s.charCodeAt(k) <= 57))\n //@ decreases s.length\n //@ ensures \\result >= 0\n if (s.length === 0) return 0;\n return digitsValue(s.slice(0, s.length - 1)) * 10 + (s.charCodeAt(s.length - 1) - 48);\n}\n\n/**\n * What a number from the environment means (owner 2026-11-04: a bad one fails at start):\n * \"default\" when unset (\"\": the wrapper reads a missing variable as \"\"), \"value\" when it is\n * a canonical natural number at least `min` (its value is `digitsValue(raw)`), and \"bad\"\n * otherwise: a sign, a space, a fraction, an exponent, hex, text, or below `min`.\n *\n * @ensures exactly the model's EnvNumberOf (proved in links/utils-strings.dfy)\n */\nexport function envNumberKind(raw: string, min: number): string {\n //@ verify\n //@ type min nat\n //@ ensures raw === \"\" ==> \\result === \"default\"\n //@ ensures (raw !== \"\" && !isCanonicalNat(raw)) ==> \\result === \"bad\"\n if (raw === \"\") return \"default\";\n if (!isCanonicalNat(raw)) return \"bad\";\n return digitsValue(raw) < min ? \"bad\" : \"value\";\n}\n\n/**\n * The first index ≥ `i` holding a line terminator, or |s|: where a regex `.+` started at `i`\n * stops.\n *\n * @ensures i ≤ result ≤ |s| ∧ no terminator in s[i, result) ∧ (result = |s| ∨ terminator at result)\n */\nexport function lineEnd(s: string, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires 0 <= i && i <= s.length\n //@ decreases s.length - i\n //@ ensures i <= \\result && \\result <= s.length\n //@ ensures forall(k: nat, (i <= k && k < \\result) ==> !isLineTerminator(s.charCodeAt(k)))\n //@ ensures \\result < s.length ==> isLineTerminator(s.charCodeAt(\\result))\n if (i === s.length || isLineTerminator(s.charCodeAt(i))) return i;\n return lineEnd(s, i + 1);\n}\n\n/**\n * The largest p with lo ≤ p < hi whose character is not a line terminator, or -1: where a\n * backtracking regex `.` can start.\n *\n * @ensures result = -1 ∨ (lo ≤ result < hi ∧ ¬terminator(s[result]) ∧ only terminators in (result, hi))\n */\nexport function lastLineCharBelow(s: string, hi: number, lo: number): number {\n //@ verify\n //@ type hi nat\n //@ type lo nat\n //@ requires 0 <= lo && 0 <= hi && hi <= s.length\n //@ decreases hi\n //@ ensures \\result === -1 || (lo <= \\result && \\result < hi)\n //@ ensures \\result >= 0 ==> !isLineTerminator(s.charCodeAt(\\result))\n //@ ensures \\result >= 0 ==> forall(k: nat, (\\result < k && k < hi) ==> isLineTerminator(s.charCodeAt(k)))\n //@ ensures \\result === -1 ==> forall(k: nat, (lo <= k && k < hi) ==> isLineTerminator(s.charCodeAt(k)))\n if (hi <= lo) return -1;\n if (!isLineTerminator(s.charCodeAt(hi - 1))) return hi - 1;\n return lastLineCharBelow(s, hi - 1, lo);\n}\n\n/**\n * Nothing but JS whitespace (`s.trim() === \"\"`).\n *\n * @ensures exactly the model's Blank\n */\nexport function isBlank(s: string): boolean {\n //@ verify\n //@ ensures \\result <==> s.trim() === \"\"\n return s.trim() === \"\";\n}\n\n/**\n * The first index ≥ `i` where `x` occurs in `s`, or -1 (JS `s.indexOf(x, i)` for i ≤ |s|).\n *\n * @ensures result = -1 ∨ (i ≤ result ∧ s[result, result + |x|) = x) — and the first such\n * index: links/utils-strings.dfy proves it is exactly the model's IndexOfFrom (lsc can't\n * give the \"no earlier match\" quantifier a trigger)\n */\nexport function indexOfFrom(s: string, x: string, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires i >= 0 && i <= s.length\n //@ decreases s.length - i\n //@ ensures \\result === -1 || (i <= \\result && \\result + x.length <= s.length)\n //@ ensures \\result >= 0 ==> s.slice(\\result, \\result + x.length) === x\n // A match here, else the end, else the next index: stopping at `i === |s|` (not \"x no\n // longer fits\") leaves no bound whose slip a later, harmless step would hide\n if (startsWithAt(s, x, i)) return i;\n if (i === s.length) return -1;\n return indexOfFrom(s, x, i + 1);\n}\n\n/**\n * `indexOfFrom` as a loop: the same answer at a constant stack depth, for text long enough that\n * one frame per character would overflow the stack (a rendered page, 50–60 KB with its inlined\n * stylesheet). Specs and links use `indexOfFrom`; runtime scans over long text use this.\n *\n * @ensures result = indexOfFrom(s, x, i)\n */\nexport function findFrom(s: string, x: string, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires i >= 0 && i <= s.length\n //@ ensures \\result === indexOfFrom(s, x, i)\n let k = i;\n while (k !== s.length) {\n //@ invariant i <= k && k <= s.length\n //@ invariant indexOfFrom(s, x, k) === indexOfFrom(s, x, i)\n //@ decreases s.length - k\n if (startsWithAt(s, x, k)) return k;\n k = k + 1;\n }\n return startsWithAt(s, x, k) ? k : -1;\n}\n\n/**\n * `indexOfCode` as a loop: the same answer at a constant stack depth (see `findFrom`).\n *\n * @ensures result = indexOfCode(s, code, from)\n */\nexport function findCodeFrom(s: string, code: number, from: number): number {\n //@ verify\n //@ type from nat\n //@ requires code >= 0 && from >= 0\n //@ ensures \\result === indexOfCode(s, code, from)\n let k = from;\n while (k < s.length) {\n //@ invariant from <= k\n //@ invariant indexOfCode(s, code, k) === indexOfCode(s, code, from)\n //@ decreases s.length - k\n if (s.charCodeAt(k) === code) return k;\n k = k + 1;\n }\n return -1;\n}\n\n/**\n * How many times `x` occurs in `s` from `i` on, left to right without overlaps (repeated JS\n * `s.indexOf(x, at + x.length)`).\n *\n * @requires |x| > 0\n * @ensures result ≥ 0 — exactly the model's CountFrom (links/utils-strings.dfy)\n */\nexport function countFrom(s: string, x: string, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires x.length > 0 && i >= 0 && i <= s.length\n //@ decreases s.length - i\n //@ ensures \\result >= 0\n const at = indexOfFrom(s, x, i);\n if (at === -1) return 0;\n return 1 + countFrom(s, x, at + x.length);\n}\n\n/**\n * `countFrom(s, x, 0)` as a loop: a constant stack depth on long text (see `findFrom`).\n *\n * @requires |x| > 0\n * @ensures result = countFrom(s, x, 0)\n */\nexport function countOf(s: string, x: string): number {\n //@ verify\n //@ requires x.length > 0\n //@ ensures \\result === countFrom(s, x, 0)\n let n = 0;\n let i = 0;\n let at = findFrom(s, x, 0);\n while (at !== -1) {\n //@ invariant 0 <= i && i <= s.length\n //@ invariant at === indexOfFrom(s, x, i)\n //@ invariant n + countFrom(s, x, i) === countFrom(s, x, 0)\n //@ decreases s.length - i\n n = n + 1;\n i = at + x.length;\n at = findFrom(s, x, i);\n }\n return n;\n}\n\n/**\n * The text before the first `code`, or all of it when there is none (JS `s.split(c)[0]`).\n *\n * @ensures result = s[0, first code) when s holds one, else s — the model's UntilCode\n */\nexport function untilCode(s: string, code: number): string {\n //@ verify\n //@ requires code >= 0\n //@ ensures \\result === (indexOfCode(s, code, 0) >= 0 && indexOfCode(s, code, 0) <= s.length ? s.slice(0, indexOfCode(s, code, 0)) : s)\n const k = indexOfCode(s, code, 0);\n return k >= 0 ? s.slice(0, k) : s;\n}\n\n/**\n * `s` from `i` on split at every `code` (JS `s.split(c)` at i = 0, for a one-character\n * separator): always at least one part.\n *\n * @ensures |result| ≥ 1 — exactly the model's SplitCodeFrom (links/utils-strings.dfy)\n */\nexport function splitCodeFrom(s: string, code: number, i: number): string[] {\n //@ verify\n //@ type i nat\n //@ requires code >= 0 && i >= 0 && i <= s.length\n //@ decreases s.length - i\n //@ ensures \\result.length > 0\n const k = indexOfCode(s, code, i);\n if (k === -1) return [s.slice(i)];\n return [s.slice(i, k), ...splitCodeFrom(s, code, k + 1)];\n}\n\n/**\n * Every run of JS whitespace in `s` from `i` on as one space (JS `s.replace(/\\s+/g, \" \")` at\n * i = 0).\n *\n * @ensures |result| ≤ |s| − i — exactly the model's CollapseSpacesFrom (links/utils-strings.dfy)\n */\nexport function collapseSpacesFrom(s: string, i: number): string {\n //@ verify\n //@ type i nat\n //@ requires 0 <= i && i <= s.length\n //@ decreases s.length - i\n //@ ensures \\result.length <= s.length - i\n if (i === s.length) return \"\";\n if (isJsSpace(s.charCodeAt(i))) return \" \" + collapseSpacesFrom(s, spaceRunEnd(s, i));\n return s.slice(i, i + 1) + collapseSpacesFrom(s, i + 1);\n}\n\n/**\n * `collapseSpacesFrom(s, 0)` at a constant stack depth (a page's text is tens of KB).\n *\n * @ensures result = collapseSpacesFrom(s, 0)\n */\nexport function collapseSpaces(s: string): string {\n //@ verify\n //@ ensures \\result === collapseSpacesFrom(s, 0)\n let out = \"\";\n let i = 0;\n while (i < s.length) {\n //@ invariant 0 <= i && i <= s.length\n //@ invariant out + collapseSpacesFrom(s, i) === collapseSpacesFrom(s, 0)\n //@ decreases s.length - i\n if (isJsSpace(s.charCodeAt(i))) {\n out = out + \" \";\n i = spaceRunEnd(s, i);\n } else {\n out = out + s.slice(i, i + 1);\n i = i + 1;\n }\n }\n return out;\n}\n\n/**\n * `n` spaces.\n *\n * @ensures result = \" \" repeated n times — the model's Spaces\n */\nexport function spaces(n: number): string {\n //@ verify\n //@ type n nat\n //@ requires n >= 0\n //@ decreases n\n //@ ensures \\result.length === n\n //@ ensures forall(k: nat, k < n ==> \\result.charCodeAt(k) === 32)\n if (n === 0) return \"\";\n return \" \" + spaces(n - 1);\n}\n\n/**\n * A line feed, `\"\\n\"`, for proved text that spans lines: lsc emits a `\"\\n\"` escape raw, which\n * Dafny cannot parse (models/LSC-GAPS.md), so the contract pins it by code unit and the body is\n * a template literal holding the line break itself.\n *\n * @ensures result = \"\\n\" — one code unit, 10\n */\nexport function lineFeed(): string {\n //@ verify\n //@ ensures \\result.length === 1 && \\result.charCodeAt(0) === 10\n return `\n`;\n}\n\n/**\n * `s` padded on the left with spaces to `width` (JS `s.padStart(width)`).\n *\n * @ensures result = Spaces(width − |s|) + s when width > |s|, else s\n */\nexport function padLeft(s: string, width: number): string {\n //@ verify\n //@ ensures width <= s.length ==> \\result === s\n // width > |s| ⟹ spaces(width − |s|) + s: a hand ensures in strings.dfy, so importers'\n // axioms name no helper (models/LSC-GAPS.md). Math.max, not a ternary: at width = |s|\n // both branches agree (spaces(0) is \"\"), so `>` vs `>=` would be equivalent.\n return spaces(Math.max(width - s.length, 0)) + s;\n}\n\n/**\n * `s` padded on the right with spaces to `width` (JS `s.padEnd(width)`).\n *\n * @ensures result = s + Spaces(width − |s|) when width > |s|, else s\n */\nexport function padRight(s: string, width: number): string {\n //@ verify\n //@ ensures width <= s.length ==> \\result === s\n // width > |s| ⟹ s + spaces(width − |s|): a hand ensures in strings.dfy, as padLeft's.\n return s + spaces(Math.max(width - s.length, 0));\n}\n\n/**\n * An optional part of a key: `tag` then `text`, or nothing when `text` is empty, so an absent\n * part never leaves a bare tag.\n *\n * @ensures result = \"\" when text = \"\", else tag + text — exactly the model's KeyPart\n */\nexport function keyPart(tag: string, text: string): string {\n //@ verify\n //@ ensures \\result === (text === \"\" ? \"\" : tag + text)\n return text === \"\" ? \"\" : tag + text;\n}\n\n/**\n * Two texts joined by one space: the one rule behind a loader key's `<column> <direction>`, a\n * sync line's `METHOD /path` and a field's description then note.\n *\n * @ensures result = a + \" \" + b — exactly the model's SpaceJoined\n */\nexport function spaceJoined(a: string, b: string): string {\n //@ verify\n //@ ensures \\result === a + \" \" + b\n return a + \" \" + b;\n}\n\n/**\n * Whether `x` occurs in `s` at some index ≥ `i` (JS `s.includes(x, i)` for i ≤ |s|).\n *\n * @ensures result ⟺ ∃ k. i ≤ k ≤ |s| ∧ startsWithAt(s, x, k) — exactly the model's\n * IncludesFrom: a hand lemma in strings.dfy (`includesFrom_exists`), so importers' axioms\n * name no helper (models/LSC-GAPS.md)\n */\nexport function includesFrom(s: string, x: string, i: number): boolean {\n //@ verify\n //@ type i nat\n //@ requires i >= 0\n //@ decreases s.length + 1 - i\n if (i > s.length) return false;\n if (startsWithAt(s, x, i)) return true;\n return includesFrom(s, x, i + 1);\n}\n\n/**\n * `s` with a-z uppercased and every other character kept, the mirror of `lowerAscii`: JS's\n * `toUpperCase()` also maps non-ASCII letters (ß becomes \"SS\").\n *\n * @ensures result = s with a-z uppercased — same length, every other character unchanged\n */\nexport function upperAscii(s: string): string {\n //@ verify\n //@ decreases s.length\n //@ ensures \\result === s.toUpperCase()\n if (s.length === 0) return \"\";\n const c = s.charCodeAt(0);\n const head =\n c >= 97 && c <= 122 ? \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\".slice(c - 97, c - 96) : s.slice(0, 1);\n return head + upperAscii(s.slice(1));\n}\n","//@ backend dafny\nimport { codeAt } from \"./strings\";\n\n/* Whole-string rewrites, verified with LemmaScript → Dafny (model: models/Utils.dfy \"text\n replacement\"; link: models/links/utils-replace.dfy). Each has a recursive spec (for\n proofs and tests) and a loop proved to build exactly it (for callers: its depth doesn't\n grow with the input). The `\\result === spec(s)` clause of each loop is a hand `ensures`\n in replace.dfy, as utils `escapeHtml`'s is: lsc would put it in every importer's axiom,\n where this file's own spec isn't emitted. */\n\n// --- One substitution rule (model `Utils.Substituted`, 2026-11-03): each code unit found in a\n// table is replaced by its text, every other kept. replaceCode, pointerToken, escapeHtml and\n// the generator's look-alike fold are this rule, each with its own table.\n\n/**\n * The first index ≥ `i` holding `c` in `codes`, or -1.\n *\n * @ensures result = -1 ∨ (i ≤ result < |codes| ∧ codes[result] = c) — the model's CodeIndex\n */\nexport function codeIndex(codes: number[], c: number, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires i <= codes.length\n //@ decreases codes.length - i\n //@ ensures \\result === -1 || (i <= \\result && \\result < codes.length && codes[\\result] === c)\n // `===`, not `>=`: past the end codes[i] is undefined, never c, so `>=` vs `>` is equivalent\n if (i === codes.length) return -1;\n return (codes[i] as number) === c ? i : codeIndex(codes, c, i + 1);\n}\n\n/** `s` with each code unit in `codes` replaced by its text, recursively: the spec `substitute` builds. */\nexport function substitutedText(s: string, codes: number[], texts: string[]): string {\n //@ verify\n //@ decreases s.length\n //@ ensures s.length === 0 ==> \\result === \"\"\n //@ ensures codes.length === 0 ==> \\result === s\n if (s.length === 0) return \"\";\n const k = codeIndex(codes, s.charCodeAt(0), 0);\n const head = k >= 0 && k < texts.length ? (texts[k] as string) : s.slice(0, 1);\n return head + substitutedText(s.slice(1), codes, texts);\n}\n\n/**\n * `s` with each code unit in `codes` replaced by the text at its first index there, every\n * other kept. A loop, so its depth doesn't grow with the input.\n *\n * @ensures result = substitutedText(s, codes, texts) — the model's Substituted (a hand\n * ensures in replace.dfy: importers can't resolve substitutedText)\n * @ensures |s| = 0 ⟹ result = \"\" ∧ |codes| = 0 ⟹ result = s — no table, no change\n */\nexport function substitute(s: string, codes: number[], texts: string[]): string {\n //@ verify\n //@ ensures s.length === 0 ==> \\result === \"\"\n //@ ensures codes.length === 0 ==> \\result === s\n let out = \"\";\n // `!==`, not `<`: one step past the end reads NaN and adds \"\", so `<=` would be equivalent\n for (let i = 0; i !== s.length; i++) {\n //@ invariant 0 <= i && i <= s.length\n //@ invariant out + substitutedText(s.slice(i), codes, texts) === substitutedText(s, codes, texts)\n //@ decreases s.length - i\n const k = codeIndex(codes, s.charCodeAt(i), 0);\n out = k >= 0 && k < texts.length ? out + (texts[k] as string) : out + s.slice(i, i + 1);\n }\n return out;\n}\n\n/** `s` with every `from` code unit replaced by `to`, recursively: the one-entry table. */\nexport function replacedCode(s: string, from: number, to: string): string {\n //@ verify\n return substitutedText(s, [from], [to]);\n}\n\n/**\n * `s` with every `from` code unit replaced by `to` (`replaceAll` of one character).\n *\n * @ensures result = replacedCode(s, from, to) — the model's ReplaceCode; no `from` survives\n * when `to` holds none (ReplaceCodeRemoves)\n */\nexport function replaceCode(s: string, from: number, to: string): string {\n //@ verify\n return substitute(s, [from], [to]);\n}\n\n/**\n * `s` with every `find` replaced by `put`, left to right without overlaps: JS\n * `s.split(find).join(put)` for a non-empty `find` (tests pin the two). Recursive, with no\n * loop twin: its callers fill short templates (the SDK's registry paths), so the depth stays\n * small; a long-input caller would need one.\n *\n * @requires |find| > 0 — split(\"\") splits into characters, a different rule\n * @ensures exactly the model's ReplaceText — proved in the link\n */\nexport function replaceText(s: string, find: string, put: string): string {\n //@ verify\n //@ requires find.length > 0\n //@ decreases s.length\n if (s.length < find.length) return s;\n if (s.slice(0, find.length) === find) {\n return put + replaceText(s.slice(find.length), find, put);\n }\n return s.slice(0, 1) + replaceText(s.slice(1), find, put);\n}\n\n/** A JSON Pointer token of `s`, recursively: `~` → `~0`, `/` → `~1`. */\nexport function pointerTokenOf(s: string): string {\n //@ verify\n return substitutedText(s, [126, 47], [\"~0\", \"~1\"]);\n}\n\n/**\n * `s` as a JSON Pointer reference token (RFC 6901 §3): `~` as `~0`, `/` as `~1`.\n *\n * @ensures result = pointerTokenOf(s) — the model's PointerToken; never holds \"/\"\n * (PointerTokenHasNoSlash)\n */\nexport function pointerToken(s: string): string {\n //@ verify\n return substitute(s, [126, 47], [\"~0\", \"~1\"]);\n}\n\n/** The escape of `s`, recursively: each `&` `<` `>` `\"` `'` as its entity. */\nexport function escapedText(s: string): string {\n //@ verify\n return substitutedText(s, [38, 60, 62, 34, 39], [\"&\", \"<\", \">\", \""\", \"'\"]);\n}\n\n/**\n * Escape text for an HTML body or a double-quoted attribute.\n *\n * @ensures result = escapedText(value) — exactly the model's EscapeHtml (a hand ensures in\n * replace.dfy, since importers can't see escapedText)\n * @ensures ∀ k < |result|. result[k] ∉ {\"<\", \">\", \"\\\"\", \"'\"} — nothing in the output can\n * open a tag or close the attribute; \"&\" appears only as the start of an entity\n */\nexport function escapeHtml(value: string): string {\n //@ verify\n //@ ensures forall(k: nat, k < \\result.length ==> (\\result.charCodeAt(k) !== 60 && \\result.charCodeAt(k) !== 62 && \\result.charCodeAt(k) !== 34 && \\result.charCodeAt(k) !== 39))\n return substitute(value, [38, 60, 62, 34, 39], [\"&\", \"<\", \">\", \""\", \"'\"]);\n}\n\n/** `s` with every `*` `/` pair written `* /`, recursively: the spec `commentSafe` builds. */\nexport function commentSafeOf(s: string): string {\n //@ verify\n //@ decreases s.length\n if (s.length === 0) return \"\";\n if (codeAt(s, 0) === 42 && codeAt(s, 1) === 47) {\n return \"* /\" + commentSafeOf(s.slice(2));\n }\n return s.slice(0, 1) + commentSafeOf(s.slice(1));\n}\n\n/**\n * Text safe inside a `/* … *\\/` comment: every `*` `/` pair written `* /`.\n *\n * @ensures result = commentSafeOf(s) — the model's CommentSafe\n */\nexport function commentSafe(s: string): string {\n //@ verify\n let out = \"\";\n let i = 0;\n while (i !== s.length) {\n //@ invariant 0 <= i && i <= s.length\n //@ invariant out + commentSafeOf(s.slice(i)) === commentSafeOf(s)\n //@ decreases s.length - i\n if (codeAt(s, i) === 42 && codeAt(s, i + 1) === 47) {\n out = out + \"* /\";\n i = i + 2;\n } else {\n out = out + s.slice(i, i + 1);\n i = i + 1;\n }\n }\n return out;\n}\n","//@ backend dafny\nimport { codeAt, indexOfCode, startsWithAt, untilCode } from \"@atlas/utils/strings\";\nimport { replaceCode } from \"@atlas/utils/replace\";\n\n/* The components' decisions, as pure functions verified with LemmaScript → Dafny (model:\n models/AugurWeb.dfy; link: models/links/augur-web-rules.dfy). JSX, the DOM, timers,\n `parseFloat`/`toFixed` and `Math.random` stay in the components. */\n\n/** One entry of a pagination bar: a page number or an ellipsis. */\nexport type PageEntry = { kind: \"page\"; n: number } | { kind: \"ellipsis\" };\n\n/**\n * Pages i + 1 … total, in order.\n *\n * @ensures exactly the model's Range1\n */\nexport function pageRangeFrom(total: number, i: number): PageEntry[] {\n //@ verify\n //@ type i nat\n //@ requires i >= 0\n //@ decreases total - i\n //@ ensures i >= total ==> \\result.length === 0\n //@ ensures i < total ==> \\result.length === total - i\n if (i >= total) return [];\n return [{ kind: \"page\", n: i + 1 }, ...pageRangeFrom(total, i + 1)];\n}\n\n/**\n * getPageNumbers: none for no pages; all of them up to 5; else the first, the last, and a window\n * around the (clamped) current page with ellipses.\n *\n * @ensures exactly the model's PageNumbers\n */\nexport function pageNumbersOf(current: number, total: number): PageEntry[] {\n //@ verify\n //@ ensures total <= 0 ==> \\result.length === 0\n //@ ensures total === 1 ==> \\result.length === 1\n if (total <= 0) return [];\n if (total === 1) return [{ kind: \"page\", n: 1 }];\n const page = clampPage(current, total);\n if (total <= 5) return pageRangeFrom(total, 0);\n const first: PageEntry = { kind: \"page\", n: 1 };\n const last: PageEntry = { kind: \"page\", n: total };\n const gap: PageEntry = { kind: \"ellipsis\" };\n if (page <= 3) {\n return [\n first,\n { kind: \"page\", n: 2 },\n { kind: \"page\", n: 3 },\n { kind: \"page\", n: 4 },\n gap,\n last,\n ];\n }\n if (page >= total - 2) {\n return [\n first,\n gap,\n { kind: \"page\", n: total - 3 },\n { kind: \"page\", n: total - 2 },\n { kind: \"page\", n: total - 1 },\n last,\n ];\n }\n return [\n first,\n gap,\n { kind: \"page\", n: page - 1 },\n { kind: \"page\", n: page },\n { kind: \"page\", n: page + 1 },\n gap,\n last,\n ];\n}\n\n/**\n * The current page clamped to [1, total] (`Math.max(1, Math.min(current, total))`).\n *\n * @ensures result = 1 below 1, total above it, else current\n */\nexport function clampPage(current: number, total: number): number {\n //@ verify\n //@ ensures current > total && total >= 1 ==> \\result === total\n //@ ensures current > total && total < 1 ==> \\result === 1\n //@ ensures current <= total && current < 1 ==> \\result === 1\n //@ ensures current <= total && current >= 1 ==> \\result === current\n const capped = current > total ? total : current;\n return capped < 1 ? 1 : capped;\n}\n\n/**\n * ListPagination's first page: at or before page 1 (on the unclamped page).\n *\n * @ensures exactly the model's IsFirstPage\n */\nexport function isFirstPage(page: number): boolean {\n //@ verify\n //@ ensures \\result === (page <= 1)\n return page <= 1;\n}\n\n/**\n * ListPagination's last page: at or past the total (on the unclamped page).\n *\n * @ensures exactly the model's IsLastPage\n */\nexport function isLastPage(page: number, totalPages: number): boolean {\n //@ verify\n //@ ensures \\result === (page >= totalPages)\n return page >= totalPages;\n}\n\n/**\n * The Prev link's target: page 1 on the first page, else the one before.\n *\n * @ensures exactly the model's PrevTarget\n */\nexport function prevTarget(page: number): number {\n //@ verify\n //@ ensures isFirstPage(page) ==> \\result === 1\n //@ ensures !isFirstPage(page) ==> \\result === page - 1\n return isFirstPage(page) ? 1 : page - 1;\n}\n\n/**\n * The Next link's target: the last page on it, else the one after.\n *\n * @ensures exactly the model's NextTarget\n */\nexport function nextTarget(page: number, totalPages: number): number {\n //@ verify\n //@ ensures isLastPage(page, totalPages) ==> \\result === totalPages\n //@ ensures !isLastPage(page, totalPages) ==> \\result === page + 1\n return isLastPage(page, totalPages) ? totalPages : page + 1;\n}\n\n/**\n * commit's clamp: at least min, then at most max when there is one (max wins if max < min).\n *\n * @ensures exactly the model's Clamp\n */\nexport function clampQuantity(value: number, min: number, max: number | undefined): number {\n //@ verify\n //@ ensures max === undefined ==> \\result === (value < min ? min : value)\n //@ ensures max !== undefined && (value < min ? min : value) > max ==> \\result === max\n //@ ensures max !== undefined && (value < min ? min : value) <= max ==> \\result === (value < min ? min : value)\n const atLeast = value < min ? min : value;\n if (max === undefined) return atLeast;\n return atLeast > max ? max : atLeast;\n}\n\n/**\n * The decrease stepper: one step down, not below min (`Math.max(value - step, min)`).\n *\n * @ensures exactly the model's StepDown\n */\nexport function stepDown(value: number, step: number, min: number): number {\n //@ verify\n //@ ensures value - step > min ==> \\result === value - step\n //@ ensures value - step <= min ==> \\result === min\n return value - step > min ? value - step : min;\n}\n\n/**\n * The increase stepper: one step up, not above max when there is one.\n *\n * @ensures exactly the model's StepUp\n */\nexport function stepUp(value: number, step: number, max: number | undefined): number {\n //@ verify\n //@ ensures max === undefined ==> \\result === value + step\n //@ ensures max !== undefined && value + step > max ==> \\result === max\n //@ ensures max !== undefined && value + step <= max ==> \\result === value + step\n if (max === undefined) return value + step;\n return value + step > max ? max : value + step;\n}\n\n/**\n * The decrease button is off when the input is, or the value is already at the minimum.\n *\n * @ensures exactly the model's MinDisabled\n */\nexport function decreaseDisabled(disabled: boolean, value: number, min: number): boolean {\n //@ verify\n //@ ensures \\result === (disabled || value <= min)\n return disabled || value <= min;\n}\n\n/**\n * The increase button is off when the input is, or the value is already at the maximum.\n *\n * @ensures exactly the model's MaxDisabled\n */\nexport function increaseDisabled(\n disabled: boolean,\n value: number,\n max: number | undefined,\n): boolean {\n //@ verify\n //@ ensures max === undefined ==> \\result === disabled\n //@ ensures max !== undefined ==> \\result === (disabled || value >= max)\n if (max === undefined) return disabled;\n return disabled || value >= max;\n}\n\n/**\n * The quantity input's digit test, JS's `key >= \"0\" && key <= \"9\"` (string order): a first code\n * unit 0–8 with anything after it, or exactly \"9\".\n *\n * @ensures exactly the model's KeyAllowed digit clause\n */\nexport function digitKey(key: string): boolean {\n //@ verify\n //@ ensures \\result === ((codeAt(key, 0) >= 48 && codeAt(key, 0) <= 56) || key === \"9\")\n const c = codeAt(key, 0);\n return (c >= 48 && c <= 56) || key === \"9\";\n}\n\n/**\n * The editing and navigation keys the input always lets through.\n *\n * @ensures result ⟺ key ∈ {Backspace, Delete, ArrowLeft, ArrowRight, Tab, Enter}\n */\nexport function editingKey(key: string): boolean {\n //@ verify\n //@ ensures \\result === (key === \"Backspace\" || key === \"Delete\" || key === \"ArrowLeft\" || key === \"ArrowRight\" || key === \"Tab\" || key === \"Enter\")\n return (\n key === \"Backspace\" ||\n key === \"Delete\" ||\n key === \"ArrowLeft\" ||\n key === \"ArrowRight\" ||\n key === \"Tab\" ||\n key === \"Enter\"\n );\n}\n\n/**\n * A keypress is allowed: an editing key, one \".\" when decimals are allowed, or a digit.\n *\n * @ensures exactly the model's KeyAllowed\n */\nexport function keyAllowed(key: string, decimals: number, hasDot: boolean): boolean {\n //@ verify\n //@ ensures \\result === (editingKey(key) || (decimals > 0 && key === \".\" && !hasDot) || digitKey(key))\n return editingKey(key) || (decimals > 0 && key === \".\" && !hasDot) || digitKey(key);\n}\n\n/**\n * handleChange from index `i`: digits only, plus the first \".\" when decimals are allowed.\n *\n * @ensures exactly the model's CleanQtyFrom\n */\nexport function cleanQtyFrom(raw: string, allowDot: boolean, seenDot: boolean, i: number): string {\n //@ verify\n //@ type i nat\n //@ requires i >= 0\n //@ decreases raw.length - i\n //@ ensures i >= raw.length ==> \\result === \"\"\n if (i >= raw.length) return \"\";\n const c = codeAt(raw, i);\n if (c >= 48 && c <= 57) return raw.slice(i, i + 1) + cleanQtyFrom(raw, allowDot, seenDot, i + 1);\n if (allowDot && c === 46 && !seenDot) return \".\" + cleanQtyFrom(raw, allowDot, true, i + 1);\n return cleanQtyFrom(raw, allowDot, seenDot, i + 1);\n}\n\n/** What a stock label shows. */\nexport type StockView = \"loading\" | \"out-of-stock\" | \"low-stock\" | \"in-stock\";\n\n/**\n * Loading first; out of stock overrides low stock.\n *\n * @ensures exactly the model's StockViewOf\n */\nexport function stockViewOf(loading: boolean, isInStock: boolean, isLowStock: boolean): StockView {\n //@ verify\n //@ ensures loading ==> \\result === \"loading\"\n //@ ensures !loading && !isInStock ==> \\result === \"out-of-stock\"\n //@ ensures !loading && isInStock && isLowStock ==> \\result === \"low-stock\"\n //@ ensures !loading && isInStock && !isLowStock ==> \\result === \"in-stock\"\n if (loading) return \"loading\";\n if (!isInStock) return \"out-of-stock\";\n return isLowStock ? \"low-stock\" : \"in-stock\";\n}\n\n/**\n * The quantity shows only when given and the item is in stock (low or not).\n *\n * @ensures exactly the model's ShowStockQuantity\n */\nexport function showStockQuantity(view: StockView, hasQuantity: boolean): boolean {\n //@ verify\n //@ ensures \\result === (hasQuantity && view !== \"out-of-stock\" && view !== \"loading\")\n return hasQuantity && view !== \"out-of-stock\" && view !== \"loading\";\n}\n\n/** What a price shows. */\nexport type PriceView = \"skeleton\" | \"zero-label\" | \"amount\";\n\n/**\n * Loading first; a 0 value with no original price shows the zero label (\"Call for Price\").\n *\n * @ensures exactly the model's PriceViewOf\n */\nexport function priceViewOf(\n loading: boolean,\n valueIsZero: boolean,\n hasOriginal: boolean,\n): PriceView {\n //@ verify\n //@ ensures loading ==> \\result === \"skeleton\"\n //@ ensures !loading && valueIsZero && !hasOriginal ==> \\result === \"zero-label\"\n //@ ensures !loading && !(valueIsZero && !hasOriginal) ==> \\result === \"amount\"\n if (loading) return \"skeleton\";\n if (valueIsZero && !hasOriginal) return \"zero-label\";\n return \"amount\";\n}\n\n/**\n * A CSV field needs quotes iff it holds a comma, a quote or a line feed (a carriage return alone\n * does not).\n *\n * @ensures exactly the model's NeedsQuotes\n */\nexport function needsQuotes(s: string): boolean {\n //@ verify\n //@ ensures \\result === (indexOfCode(s, 44, 0) >= 0 || indexOfCode(s, 34, 0) >= 0 || indexOfCode(s, 10, 0) >= 0)\n return indexOfCode(s, 44, 0) >= 0 || indexOfCode(s, 34, 0) >= 0 || indexOfCode(s, 10, 0) >= 0;\n}\n\n/**\n * A CSV field: quoted, with quotes doubled, when it needs quotes; else as is.\n *\n * @ensures exactly the model's CsvField\n */\nexport function csvField(s: string): string {\n //@ verify\n //@ ensures needsQuotes(s) ==> \\result === \"\\\"\" + replaceCode(s, 34, \"\\\"\\\"\") + \"\\\"\"\n //@ ensures !needsQuotes(s) ==> \\result === s\n if (!needsQuotes(s)) return s;\n return '\"' + replaceCode(s, 34, '\"\"') + '\"';\n}\n\n/** A column's sort direction. */\nexport type SortDir = \"asc\" | \"desc\" | \"unsorted\";\n\n/**\n * aria-sort: only on a sortable column, naming its direction. A string, not a literal union:\n * lsc names a `\"none\"` literal `None`, which clashes with Option's (models/LSC-GAPS.md).\n *\n * @ensures exactly the model's AriaSort\n */\nexport function ariaSortOf(sortable: boolean, dir: SortDir): string | undefined {\n //@ verify\n //@ ensures !sortable ==> \\result === undefined\n //@ ensures sortable && dir === \"asc\" ==> \\result === \"ascending\"\n //@ ensures sortable && dir === \"desc\" ==> \\result === \"descending\"\n //@ ensures sortable && dir === \"unsorted\" ==> \\result === \"none\"\n if (!sortable) return undefined;\n if (dir === \"asc\") return \"ascending\";\n if (dir === \"desc\") return \"descending\";\n return \"none\";\n}\n\n/**\n * A column's cell alignment class from its meta's `align` (\"left\" when it has none); any other\n * value has none.\n *\n * @ensures exactly the model's AlignClass\n */\nexport function alignClass(align: string): string {\n //@ verify\n //@ ensures align === \"left\" ==> \\result === \"text-left\"\n //@ ensures align === \"center\" ==> \\result === \"text-center\"\n //@ ensures align === \"right\" ==> \\result === \"text-right\"\n //@ ensures align !== \"left\" && align !== \"center\" && align !== \"right\" ==> \\result === \"\"\n if (align === \"left\") return \"text-left\";\n if (align === \"center\") return \"text-center\";\n return align === \"right\" ? \"text-right\" : \"\";\n}\n\n/** What the table body shows. */\nexport type BodyView = \"loading\" | \"empty\" | \"rows\";\n\n/**\n * Loading first, then the empty message for no rows.\n *\n * @ensures exactly the model's BodyViewOf\n */\nexport function bodyViewOf(loading: boolean, rowCount: number): BodyView {\n //@ verify\n //@ ensures loading ==> \\result === \"loading\"\n //@ ensures !loading && rowCount === 0 ==> \\result === \"empty\"\n //@ ensures !loading && rowCount !== 0 ==> \\result === \"rows\"\n if (loading) return \"loading\";\n return rowCount === 0 ? \"empty\" : \"rows\";\n}\n\n/** When GTM loads. */\nexport type LoadTiming = \"idle\" | \"next-tick\" | \"now\";\n\n/**\n * GTM loads at idle for lazyOnload when the browser has requestIdleCallback, on the next tick for\n * afterInteractive, else at once.\n *\n * @ensures exactly the model's GtmTiming\n */\nexport function gtmTiming(strategy: string, hasIdleCallback: boolean): LoadTiming {\n //@ verify\n //@ ensures strategy === \"lazyOnload\" && hasIdleCallback ==> \\result === \"idle\"\n //@ ensures !(strategy === \"lazyOnload\" && hasIdleCallback) && strategy === \"afterInteractive\" ==> \\result === \"next-tick\"\n //@ ensures !(strategy === \"lazyOnload\" && hasIdleCallback) && strategy !== \"afterInteractive\" ==> \\result === \"now\"\n if (strategy === \"lazyOnload\" && hasIdleCallback) return \"idle\";\n return strategy === \"afterInteractive\" ? \"next-tick\" : \"now\";\n}\n\n/**\n * Session replay is injected unless disabled or already there, and, under a rate below 1, only\n * when the draw is at or under it.\n *\n * @ensures exactly the model's ReplaySampled\n */\nexport function replaySampled(\n disabled: boolean,\n injected: boolean,\n rate: number,\n draw: number,\n): boolean {\n //@ verify\n //@ type rate real\n //@ type draw real\n //@ ensures \\result === (!disabled && !injected && !(rate < 1 && draw > rate))\n return !disabled && !injected && !(rate < 1 && draw > rate);\n}\n\n/**\n * A \"?\" or \"&\" at `k`, \"Bin=\" right after it, and a value character (not \"&\") after that: what\n * `[?&]Bin=[^&]` matches there.\n *\n * @ensures result ⟺ s[k] ∈ {?, &} ∧ s[k+1 ..] starts with \"Bin=\" ∧ s[k+5] is a char ≠ \"&\"\n */\nexport function binMarkAt(s: string, k: number): boolean {\n //@ verify\n //@ type k nat\n //@ requires k >= 0\n //@ ensures \\result === ((codeAt(s, k) === 63 || codeAt(s, k) === 38) && startsWithAt(s, \"Bin=\", k + 1) && codeAt(s, k + 5) >= 0 && codeAt(s, k + 5) !== 38)\n const c = codeAt(s, k);\n const v = codeAt(s, k + 5);\n return (c === 63 || c === 38) && startsWithAt(s, \"Bin=\", k + 1) && v >= 0 && v !== 38;\n}\n\n/**\n * The first \"?Bin=\" or \"&Bin=\" from index `i` with a value after it, or −1 (the regex skips a\n * mark with an empty value and keeps searching).\n *\n * @ensures result is the first k ≥ i with k + 6 ≤ |s| where `binMarkAt(s, k)`, else −1 —\n * exactly the model's BinAt\n */\nexport function binAt(s: string, i: number): number {\n //@ verify\n //@ type i nat\n //@ requires i >= 0\n //@ decreases s.length - i\n //@ ensures \\result === -1 || (i <= \\result && \\result + 6 <= s.length)\n //@ ensures \\result >= 0 ==> binMarkAt(s, \\result)\n //@ ensures \\result >= 0 ==> forall(k: nat, (i <= k && k < \\result) ==> !binMarkAt(s, k))\n //@ ensures \\result === -1 ==> forall(k: nat, (i <= k && k + 6 <= s.length) ==> !binMarkAt(s, k))\n if (i + 6 > s.length) return -1;\n if (binMarkAt(s, i)) return i;\n return binAt(s, i + 1);\n}\n\n/**\n * extractBin from a message string (`/[?&]Bin=([^&]+)/`): the first mark's value up to the next\n * \"&\" (never empty), or undefined.\n *\n * @ensures exactly the model's BinFromString\n */\nexport function binFromString(s: string): string | undefined {\n //@ verify\n //@ ensures binAt(s, 0) < 0 ==> \\result === undefined\n //@ ensures binAt(s, 0) >= 0 ==> \\result === untilCode(afterBinMark(s, binAt(s, 0)), 38)\n const k = binAt(s, 0);\n if (k < 0) return undefined;\n return untilCode(afterBinMark(s, k), 38);\n}\n\n/**\n * The text after a \"?Bin=\" mark at `k`, or \"\" when no mark fits there (`binAt` never gives\n * such a k; the guard keeps the slice in range for the proof).\n *\n * @ensures result = s[k + 5 ..] when 0 ≤ k ∧ k + 5 ≤ |s|, else \"\"\n */\nexport function afterBinMark(s: string, k: number): string {\n //@ verify\n //@ ensures (k < 0 || k + 5 > s.length) ==> \\result === \"\"\n //@ ensures !(k < 0 || k + 5 > s.length) ==> \\result === s.slice(k + 5)\n if (k < 0 || k + 5 > s.length) return \"\";\n return s.slice(k + 5);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-GSR6SMQ2.cjs","../src/breadcrumb.tsx"],"names":[],"mappings":"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","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/chunk-GSR6SMQ2.cjs","sourcesContent":[null,"\"use client\";\n\nimport * as React from \"react\";\nimport { LuChevronRight, LuEllipsis } from \"react-icons/lu\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\n\nconst Breadcrumb = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<\"nav\"> & {\n separator?: React.ReactNode;\n }\n>(({ ...props }, ref) => <nav ref={ref} aria-label=\"breadcrumb\" {...props} />);\nBreadcrumb.displayName = \"Breadcrumb\";\n\nconst BreadcrumbList = React.forwardRef<HTMLOListElement, React.ComponentPropsWithoutRef<\"ol\">>(\n ({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n \"text-muted-foreground flex flex-wrap items-center gap-1.5 break-words text-sm sm:gap-2.5\",\n className,\n )}\n {...props}\n />\n ),\n);\nBreadcrumbList.displayName = \"BreadcrumbList\";\n\nconst BreadcrumbItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<\"li\">>(\n ({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"inline-flex items-center gap-1.5\", className)} {...props} />\n ),\n);\nBreadcrumbItem.displayName = \"BreadcrumbItem\";\n\nconst BreadcrumbLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentPropsWithoutRef<\"a\"> & {\n asChild?: boolean;\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : \"a\";\n return (\n <Comp\n ref={ref}\n className={cn(\"hover:text-foreground transition-colors\", className)}\n {...props}\n />\n );\n});\nBreadcrumbLink.displayName = \"BreadcrumbLink\";\n\nconst BreadcrumbPage = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<\"span\">>(\n ({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(\"text-foreground font-normal\", className)}\n {...props}\n />\n ),\n);\nBreadcrumbPage.displayName = \"BreadcrumbPage\";\n\nconst BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<\"li\">) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"[&>svg]:size-3.5\", className)}\n {...props}\n >\n {children ?? <LuChevronRight />}\n </li>\n);\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\";\n\nconst BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<\"span\">) => (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"flex h-9 w-9 items-center justify-center\", className)}\n {...props}\n >\n <LuEllipsis className=\"h-4 w-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n);\nBreadcrumbEllipsis.displayName = \"BreadcrumbEllipsis\";\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n"]}
|