@myoc/fractional-indexing 0.19.508

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.
@@ -0,0 +1,212 @@
1
+ // src/index.ts
2
+ var BASE_62_DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
3
+ function midpoint(a, b, digits) {
4
+ const zero = digits[0];
5
+ if (b != null && a >= b) {
6
+ throw new Error(`${a} >= ${b}`);
7
+ }
8
+ if (a.slice(-1) === zero || b && b.slice(-1) === zero) {
9
+ throw new Error("trailing zero");
10
+ }
11
+ if (b) {
12
+ let n = 0;
13
+ while ((a[n] || zero) === b[n]) {
14
+ n++;
15
+ }
16
+ if (n > 0) {
17
+ return b.slice(0, n) + midpoint(a.slice(n), b.slice(n), digits);
18
+ }
19
+ }
20
+ const digitA = a ? digits.indexOf(a[0]) : 0;
21
+ const digitB = b != null ? digits.indexOf(b[0]) : digits.length;
22
+ if (digitB - digitA > 1) {
23
+ const midDigit = Math.round(0.5 * (digitA + digitB));
24
+ return digits[midDigit];
25
+ }
26
+ if (b && b.length > 1) {
27
+ return b.slice(0, 1);
28
+ }
29
+ return digits[digitA] + midpoint(a.slice(1), null, digits);
30
+ }
31
+ function validateInteger(int) {
32
+ if (int.length !== getIntegerLength(int[0])) {
33
+ throw new Error(`invalid integer part of order key: ${int}`);
34
+ }
35
+ }
36
+ function getIntegerLength(head) {
37
+ if (head >= "a" && head <= "z") {
38
+ return head.charCodeAt(0) - "a".charCodeAt(0) + 2;
39
+ } else if (head >= "A" && head <= "Z") {
40
+ return "Z".charCodeAt(0) - head.charCodeAt(0) + 2;
41
+ }
42
+ throw new Error(`invalid order key head: ${head}`);
43
+ }
44
+ function getIntegerPart(key) {
45
+ const integerPartLength = getIntegerLength(key[0]);
46
+ if (integerPartLength > key.length) {
47
+ throw new Error(`invalid order key: ${key}`);
48
+ }
49
+ return key.slice(0, integerPartLength);
50
+ }
51
+ function validateOrderKey(key, digits = BASE_62_DIGITS) {
52
+ const validChars = key.split("").every((char) => digits.includes(char));
53
+ if (key === `A${digits[0].repeat(26)}` || !validChars) {
54
+ throw new Error(`invalid order key: ${key}`);
55
+ }
56
+ const i = getIntegerPart(key);
57
+ const f = key.slice(i.length);
58
+ if (f.slice(-1) === digits[0]) {
59
+ throw new Error(`invalid order key: ${key}`);
60
+ }
61
+ }
62
+ function incrementInteger(x, digits) {
63
+ validateInteger(x);
64
+ const [head, ...digs] = x.split("");
65
+ let carry = true;
66
+ for (let i = digs.length - 1; carry && i >= 0; i--) {
67
+ const d = digits.indexOf(digs[i]) + 1;
68
+ if (d === digits.length) {
69
+ digs[i] = digits[0];
70
+ } else {
71
+ digs[i] = digits[d];
72
+ carry = false;
73
+ }
74
+ }
75
+ if (carry) {
76
+ if (head === "Z") {
77
+ return `a${digits[0]}`;
78
+ }
79
+ if (head === "z") {
80
+ return null;
81
+ }
82
+ const h = String.fromCharCode(head.charCodeAt(0) + 1);
83
+ if (h > "a") {
84
+ digs.push(digits[0]);
85
+ } else {
86
+ digs.pop();
87
+ }
88
+ return h + digs.join("");
89
+ }
90
+ return head + digs.join("");
91
+ }
92
+ function decrementInteger(x, digits) {
93
+ validateInteger(x);
94
+ const [head, ...digs] = x.split("");
95
+ let borrow = true;
96
+ for (let i = digs.length - 1; borrow && i >= 0; i--) {
97
+ const d = digits.indexOf(digs[i]) - 1;
98
+ if (d === -1) {
99
+ digs[i] = digits.slice(-1);
100
+ } else {
101
+ digs[i] = digits[d];
102
+ borrow = false;
103
+ }
104
+ }
105
+ if (borrow) {
106
+ if (head === "a") {
107
+ return `Z${digits.slice(-1)}`;
108
+ }
109
+ if (head === "A") {
110
+ return null;
111
+ }
112
+ const h = String.fromCharCode(head.charCodeAt(0) - 1);
113
+ if (h < "Z") {
114
+ digs.push(digits.slice(-1));
115
+ } else {
116
+ digs.pop();
117
+ }
118
+ return h + digs.join("");
119
+ }
120
+ return head + digs.join("");
121
+ }
122
+ function generateKeyBetween(a, b, digits = BASE_62_DIGITS) {
123
+ if (a != null) {
124
+ validateOrderKey(a, digits);
125
+ }
126
+ if (b != null) {
127
+ validateOrderKey(b, digits);
128
+ }
129
+ if (a != null && b != null && a >= b) {
130
+ throw new Error(`${a} >= ${b}`);
131
+ }
132
+ if (a == null) {
133
+ if (b == null) {
134
+ return `a${digits[0]}`;
135
+ }
136
+ const ib2 = getIntegerPart(b);
137
+ const fb2 = b.slice(ib2.length);
138
+ if (ib2 === `A${digits[0].repeat(26)}`) {
139
+ return ib2 + midpoint("", fb2, digits);
140
+ }
141
+ if (ib2 < b) {
142
+ return ib2;
143
+ }
144
+ const res = decrementInteger(ib2, digits);
145
+ if (res == null) {
146
+ throw new Error("cannot decrement any more");
147
+ }
148
+ return res;
149
+ }
150
+ if (b == null) {
151
+ const ia2 = getIntegerPart(a);
152
+ const fa2 = a.slice(ia2.length);
153
+ const i2 = incrementInteger(ia2, digits);
154
+ return i2 == null ? ia2 + midpoint(fa2, null, digits) : i2;
155
+ }
156
+ const ia = getIntegerPart(a);
157
+ const fa = a.slice(ia.length);
158
+ const ib = getIntegerPart(b);
159
+ const fb = b.slice(ib.length);
160
+ if (ia === ib) {
161
+ return ia + midpoint(fa, fb, digits);
162
+ }
163
+ const i = incrementInteger(ia, digits);
164
+ if (i == null) {
165
+ throw new Error("cannot increment any more");
166
+ }
167
+ if (i < b) {
168
+ return i;
169
+ }
170
+ return ia + midpoint(fa, null, digits);
171
+ }
172
+ function generateNKeysBetween(a, b, n, digits = BASE_62_DIGITS) {
173
+ if (n === 0) {
174
+ return [];
175
+ }
176
+ if (n === 1) {
177
+ return [generateKeyBetween(a, b, digits)];
178
+ }
179
+ if (b == null) {
180
+ let c2 = generateKeyBetween(a, b, digits);
181
+ const result = [c2];
182
+ for (let i = 0; i < n - 1; i++) {
183
+ c2 = generateKeyBetween(c2, b, digits);
184
+ result.push(c2);
185
+ }
186
+ return result;
187
+ }
188
+ if (a == null) {
189
+ let c2 = generateKeyBetween(a, b, digits);
190
+ const result = [c2];
191
+ for (let i = 0; i < n - 1; i++) {
192
+ c2 = generateKeyBetween(a, c2, digits);
193
+ result.push(c2);
194
+ }
195
+ result.reverse();
196
+ return result;
197
+ }
198
+ const mid = Math.floor(n / 2);
199
+ const c = generateKeyBetween(a, b, digits);
200
+ return [
201
+ ...generateNKeysBetween(a, c, mid, digits),
202
+ c,
203
+ ...generateNKeysBetween(c, b, n - mid - 1, digits)
204
+ ];
205
+ }
206
+ export {
207
+ BASE_62_DIGITS,
208
+ generateKeyBetween,
209
+ generateNKeysBetween,
210
+ validateOrderKey
211
+ };
212
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts"],
4
+ "sourcesContent": ["// Vendored from https://www.npmjs.com/package/fractional-indexing\n// License: CC0 (no rights reserved).\n// This is based on https://observablehq.com/@dgreensp/implementing-fractional-indexing\n\nexport const BASE_62_DIGITS =\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\n// `a` may be empty string, `b` is null or non-empty string.\n// `a < b` lexicographically if `b` is non-null.\n// no trailing zeros allowed.\n// digits is a string such as '0123456789' for base 10. Digits must be in\n// ascending character code order!\n/**\n * @param {string} a\n * @param {string | null | undefined} b\n * @param {string} digits\n * @returns {string}\n */\nfunction midpoint(\n a: string,\n b: string | null | undefined,\n digits: string,\n): string {\n const zero = digits[0];\n if (b != null && a >= b) {\n throw new Error(`${a} >= ${b}`);\n }\n if (a.slice(-1) === zero || (b && b.slice(-1) === zero)) {\n throw new Error(\"trailing zero\");\n }\n if (b) {\n // remove longest common prefix. pad `a` with 0s as we\n // go. note that we don't need to pad `b`, because it can't\n // end before `a` while traversing the common prefix.\n let n = 0;\n while ((a[n] || zero) === b[n]) {\n n++;\n }\n if (n > 0) {\n return b.slice(0, n) + midpoint(a.slice(n), b.slice(n), digits);\n }\n }\n // first digits (or lack of digit) are different\n const digitA = a ? digits.indexOf(a[0]) : 0;\n const digitB = b != null ? digits.indexOf(b[0]) : digits.length;\n if (digitB - digitA > 1) {\n const midDigit = Math.round(0.5 * (digitA + digitB));\n return digits[midDigit];\n }\n // first digits are consecutive\n if (b && b.length > 1) {\n return b.slice(0, 1);\n }\n\n // `b` is null or has length 1 (a single digit).\n // the first digit of `a` is the previous digit to `b`,\n // or 9 if `b` is null.\n // given, for example, midpoint('49', '5'), return\n // '4' + midpoint('9', null), which will become\n // '4' + '9' + midpoint('', null), which is '495'\n return digits[digitA] + midpoint(a.slice(1), null, digits);\n}\n\n/**\n * @param {string} int\n * @return {void}\n */\n\nfunction validateInteger(int: string): void {\n if (int.length !== getIntegerLength(int[0])) {\n throw new Error(`invalid integer part of order key: ${int}`);\n }\n}\n\n/**\n * @param {string} head\n * @return {number}\n */\n\nfunction getIntegerLength(head: string): number {\n if (head >= \"a\" && head <= \"z\") {\n return head.charCodeAt(0) - \"a\".charCodeAt(0) + 2;\n } else if (head >= \"A\" && head <= \"Z\") {\n return \"Z\".charCodeAt(0) - head.charCodeAt(0) + 2;\n }\n\n throw new Error(`invalid order key head: ${head}`);\n}\n\n/**\n * @param {string} key\n * @return {string}\n */\n\nfunction getIntegerPart(key: string): string {\n const integerPartLength = getIntegerLength(key[0]);\n\n if (integerPartLength > key.length) {\n throw new Error(`invalid order key: ${key}`);\n }\n return key.slice(0, integerPartLength);\n}\n\n/**\n * @param {string} key\n * @param {string} digits\n * @return {void}\n */\nexport function validateOrderKey(\n key: string,\n digits: string = BASE_62_DIGITS,\n): void {\n const validChars = key.split(\"\").every((char) => digits.includes(char));\n if (key === `A${digits[0].repeat(26)}` || !validChars) {\n throw new Error(`invalid order key: ${key}`);\n }\n // getIntegerPart will throw if the first character is bad,\n // or the key is too short. we'd call it to check these things\n // even if we didn't need the result\n const i = getIntegerPart(key);\n const f = key.slice(i.length);\n if (f.slice(-1) === digits[0]) {\n throw new Error(`invalid order key: ${key}`);\n }\n}\n\n// note that this may return null, as there is a largest integer\n/**\n * @param {string} x\n * @param {string} digits\n * @return {string | null}\n */\nfunction incrementInteger(x: string, digits: string): string | null {\n validateInteger(x);\n const [head, ...digs] = x.split(\"\");\n let carry = true;\n for (let i = digs.length - 1; carry && i >= 0; i--) {\n const d = digits.indexOf(digs[i]) + 1;\n if (d === digits.length) {\n digs[i] = digits[0];\n } else {\n digs[i] = digits[d];\n carry = false;\n }\n }\n if (carry) {\n if (head === \"Z\") {\n return `a${digits[0]}`;\n }\n if (head === \"z\") {\n return null;\n }\n const h = String.fromCharCode(head.charCodeAt(0) + 1);\n if (h > \"a\") {\n digs.push(digits[0]);\n } else {\n digs.pop();\n }\n return h + digs.join(\"\");\n }\n return head + digs.join(\"\");\n}\n\n// note that this may return null, as there is a smallest integer\n/**\n * @param {string} x\n * @param {string} digits\n * @return {string | null}\n */\nfunction decrementInteger(x: string, digits: string): string | null {\n validateInteger(x);\n const [head, ...digs] = x.split(\"\");\n let borrow = true;\n for (let i = digs.length - 1; borrow && i >= 0; i--) {\n const d = digits.indexOf(digs[i]) - 1;\n if (d === -1) {\n digs[i] = digits.slice(-1);\n } else {\n digs[i] = digits[d];\n borrow = false;\n }\n }\n if (borrow) {\n if (head === \"a\") {\n return `Z${digits.slice(-1)}`;\n }\n if (head === \"A\") {\n return null;\n }\n const h = String.fromCharCode(head.charCodeAt(0) - 1);\n if (h < \"Z\") {\n digs.push(digits.slice(-1));\n } else {\n digs.pop();\n }\n return h + digs.join(\"\");\n }\n return head + digs.join(\"\");\n}\n\n// `a` is an order key or null (START).\n// `b` is an order key or null (END).\n// `a < b` lexicographically if both are non-null.\n// digits is a string such as '0123456789' for base 10. Digits must be in\n// ascending character code order!\n/**\n * @param {string | null | undefined} a\n * @param {string | null | undefined} b\n * @param {string=} digits\n * @return {string}\n */\nexport function generateKeyBetween(\n a: string | null | undefined,\n b: string | null | undefined,\n digits = BASE_62_DIGITS,\n): string {\n if (a != null) {\n validateOrderKey(a, digits);\n }\n if (b != null) {\n validateOrderKey(b, digits);\n }\n if (a != null && b != null && a >= b) {\n throw new Error(`${a} >= ${b}`);\n }\n if (a == null) {\n if (b == null) {\n return `a${digits[0]}`;\n }\n\n const ib = getIntegerPart(b);\n const fb = b.slice(ib.length);\n if (ib === `A${digits[0].repeat(26)}`) {\n return ib + midpoint(\"\", fb, digits);\n }\n if (ib < b) {\n return ib;\n }\n const res = decrementInteger(ib, digits);\n if (res == null) {\n throw new Error(\"cannot decrement any more\");\n }\n return res;\n }\n\n if (b == null) {\n const ia = getIntegerPart(a);\n const fa = a.slice(ia.length);\n const i = incrementInteger(ia, digits);\n return i == null ? ia + midpoint(fa, null, digits) : i;\n }\n\n const ia = getIntegerPart(a);\n const fa = a.slice(ia.length);\n const ib = getIntegerPart(b);\n const fb = b.slice(ib.length);\n if (ia === ib) {\n return ia + midpoint(fa, fb, digits);\n }\n const i = incrementInteger(ia, digits);\n if (i == null) {\n throw new Error(\"cannot increment any more\");\n }\n if (i < b) {\n return i;\n }\n return ia + midpoint(fa, null, digits);\n}\n\n/**\n * same preconditions as generateKeysBetween.\n * n >= 0.\n * Returns an array of n distinct keys in sorted order.\n * If a and b are both null, returns [a0, a1, ...]\n * If one or the other is null, returns consecutive \"integer\"\n * keys. Otherwise, returns relatively short keys between\n * a and b.\n * @param {string | null | undefined} a\n * @param {string | null | undefined} b\n * @param {number} n\n * @param {string} digits\n * @return {string[]}\n */\nexport function generateNKeysBetween(\n a: string | null | undefined,\n b: string | null | undefined,\n n: number,\n digits = BASE_62_DIGITS,\n): string[] {\n if (n === 0) {\n return [];\n }\n if (n === 1) {\n return [generateKeyBetween(a, b, digits)];\n }\n if (b == null) {\n let c = generateKeyBetween(a, b, digits);\n const result = [c];\n for (let i = 0; i < n - 1; i++) {\n c = generateKeyBetween(c, b, digits);\n result.push(c);\n }\n return result;\n }\n if (a == null) {\n let c = generateKeyBetween(a, b, digits);\n const result = [c];\n for (let i = 0; i < n - 1; i++) {\n c = generateKeyBetween(a, c, digits);\n result.push(c);\n }\n result.reverse();\n return result;\n }\n const mid = Math.floor(n / 2);\n const c = generateKeyBetween(a, b, digits);\n return [\n ...generateNKeysBetween(a, c, mid, digits),\n c,\n ...generateNKeysBetween(c, b, n - mid - 1, digits),\n ];\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["ib", "fb", "ia", "fa", "i", "c"]
7
+ }
@@ -0,0 +1 @@
1
+ var g="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";function s(n,r,e){let t=e[0];if(r!=null&&n>=r)throw new Error(`${n} >= ${r}`);if(n.slice(-1)===t||r&&r.slice(-1)===t)throw new Error("trailing zero");if(r){let o=0;for(;(n[o]||t)===r[o];)o++;if(o>0)return r.slice(0,o)+s(n.slice(o),r.slice(o),e)}let u=n?e.indexOf(n[0]):0,l=r!=null?e.indexOf(r[0]):e.length;if(l-u>1){let o=Math.round(.5*(u+l));return e[o]}return r&&r.length>1?r.slice(0,1):e[u]+s(n.slice(1),null,e)}function $(n){if(n.length!==v(n[0]))throw new Error(`invalid integer part of order key: ${n}`)}function v(n){if(n>="a"&&n<="z")return n.charCodeAt(0)-97+2;if(n>="A"&&n<="Z")return 90-n.charCodeAt(0)+2;throw new Error(`invalid order key head: ${n}`)}function w(n){let r=v(n[0]);if(r>n.length)throw new Error(`invalid order key: ${n}`);return n.slice(0,r)}function p(n,r=g){let e=n.split("").every(l=>r.includes(l));if(n===`A${r[0].repeat(26)}`||!e)throw new Error(`invalid order key: ${n}`);let t=w(n);if(n.slice(t.length).slice(-1)===r[0])throw new Error(`invalid order key: ${n}`)}function d(n,r){$(n);let[e,...t]=n.split(""),u=!0;for(let l=t.length-1;u&&l>=0;l--){let o=r.indexOf(t[l])+1;o===r.length?t[l]=r[0]:(t[l]=r[o],u=!1)}if(u){if(e==="Z")return`a${r[0]}`;if(e==="z")return null;let l=String.fromCharCode(e.charCodeAt(0)+1);return l>"a"?t.push(r[0]):t.pop(),l+t.join("")}return e+t.join("")}function A(n,r){$(n);let[e,...t]=n.split(""),u=!0;for(let l=t.length-1;u&&l>=0;l--){let o=r.indexOf(t[l])-1;o===-1?t[l]=r.slice(-1):(t[l]=r[o],u=!1)}if(u){if(e==="a")return`Z${r.slice(-1)}`;if(e==="A")return null;let l=String.fromCharCode(e.charCodeAt(0)-1);return l<"Z"?t.push(r.slice(-1)):t.pop(),l+t.join("")}return e+t.join("")}function f(n,r,e=g){if(n!=null&&p(n,e),r!=null&&p(r,e),n!=null&&r!=null&&n>=r)throw new Error(`${n} >= ${r}`);if(n==null){if(r==null)return`a${e[0]}`;let i=w(r),a=r.slice(i.length);if(i===`A${e[0].repeat(26)}`)return i+s("",a,e);if(i<r)return i;let h=A(i,e);if(h==null)throw new Error("cannot decrement any more");return h}if(r==null){let i=w(n),a=n.slice(i.length),h=d(i,e);return h??i+s(a,null,e)}let t=w(n),u=n.slice(t.length),l=w(r),o=r.slice(l.length);if(t===l)return t+s(u,o,e);let c=d(t,e);if(c==null)throw new Error("cannot increment any more");return c<r?c:t+s(u,null,e)}function m(n,r,e,t=g){if(e===0)return[];if(e===1)return[f(n,r,t)];if(r==null){let o=f(n,r,t),c=[o];for(let i=0;i<e-1;i++)o=f(o,r,t),c.push(o);return c}if(n==null){let o=f(n,r,t),c=[o];for(let i=0;i<e-1;i++)o=f(n,o,t),c.push(o);return c.reverse(),c}let u=Math.floor(e/2),l=f(n,r,t);return[...m(n,l,u,t),l,...m(l,r,e-u-1,t)]}export{g as BASE_62_DIGITS,f as generateKeyBetween,m as generateNKeysBetween,p as validateOrderKey};
@@ -0,0 +1,29 @@
1
+ export declare const BASE_62_DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2
+ /**
3
+ * @param {string} key
4
+ * @param {string} digits
5
+ * @return {void}
6
+ */
7
+ export declare function validateOrderKey(key: string, digits?: string): void;
8
+ /**
9
+ * @param {string | null | undefined} a
10
+ * @param {string | null | undefined} b
11
+ * @param {string=} digits
12
+ * @return {string}
13
+ */
14
+ export declare function generateKeyBetween(a: string | null | undefined, b: string | null | undefined, digits?: string): string;
15
+ /**
16
+ * same preconditions as generateKeysBetween.
17
+ * n >= 0.
18
+ * Returns an array of n distinct keys in sorted order.
19
+ * If a and b are both null, returns [a0, a1, ...]
20
+ * If one or the other is null, returns consecutive "integer"
21
+ * keys. Otherwise, returns relatively short keys between
22
+ * a and b.
23
+ * @param {string | null | undefined} a
24
+ * @param {string | null | undefined} b
25
+ * @param {number} n
26
+ * @param {string} digits
27
+ * @return {string[]}
28
+ */
29
+ export declare function generateNKeysBetween(a: string | null | undefined, b: string | null | undefined, n: number, digits?: string): string[];
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "version": "0.19.508",
3
+ "name": "@myoc/fractional-indexing",
4
+ "description": "Provides functions for generating ordering strings",
5
+ "type": "module",
6
+ "types": "./dist/types/fractional-indexing/src/index.d.ts",
7
+ "main": "./dist/prod/index.js",
8
+ "module": "./dist/prod/index.js",
9
+ "engines": {
10
+ "node": "^14.13.1 || >=16.0.0"
11
+ },
12
+ "scripts": {
13
+ "gen:types": "rimraf types && tsc",
14
+ "build:esm": "rimraf dist && node ../../scripts/buildBase.js && yarn gen:types"
15
+ },
16
+ "keywords": [
17
+ "fractional",
18
+ "indexing",
19
+ "ordering",
20
+ "order"
21
+ ],
22
+ "homepage": "https://github.com/rocicorp/fractional-indexing#readme",
23
+ "bugs": "https://github.com/excalidraw/excalidraw/issues",
24
+ "repository": "https://github.com/excalidraw/excalidraw",
25
+ "author": "arv@rocicorp.dev",
26
+ "license": "CC0-1.0",
27
+ "devDependencies": {
28
+ "prettier": "^2.6.0",
29
+ "typescript": "5.9.3"
30
+ },
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/types/fractional-indexing/src/index.d.ts",
34
+ "development": "./dist/dev/index.js",
35
+ "production": "./dist/prod/index.js",
36
+ "default": "./dist/prod/index.js"
37
+ }
38
+ },
39
+ "publishConfig": {
40
+ "access": "public",
41
+ "registry": "https://registry.npmjs.org/"
42
+ },
43
+ "files": [
44
+ "dist/*"
45
+ ]
46
+ }