numeric-quantity 1.0.4 → 2.0.0-beta.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/README.md +43 -24
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/numeric-quantity.cjs.development.js +238 -0
- package/dist/cjs/numeric-quantity.cjs.development.js.map +1 -0
- package/dist/cjs/numeric-quantity.cjs.production.js +2 -0
- package/dist/cjs/numeric-quantity.cjs.production.js.map +1 -0
- package/dist/numeric-quantity.d.ts +137 -0
- package/dist/numeric-quantity.legacy-esm.js +203 -0
- package/dist/numeric-quantity.legacy-esm.js.map +1 -0
- package/dist/numeric-quantity.mjs +203 -0
- package/dist/numeric-quantity.mjs.map +1 -0
- package/dist/numeric-quantity.production.mjs +2 -0
- package/dist/numeric-quantity.production.mjs.map +1 -0
- package/dist/numeric-quantity.umd.min.js +2 -0
- package/dist/numeric-quantity.umd.min.js.map +1 -0
- package/package.json +36 -22
- package/CHANGELOG.md +0 -37
- package/dist/index.d.ts +0 -6
- package/dist/numeric-quantity.cjs.js +0 -2
- package/dist/numeric-quantity.cjs.js.map +0 -1
- package/dist/numeric-quantity.es.js +0 -62
- package/dist/numeric-quantity.es.js.map +0 -1
- package/dist/numeric-quantity.umd.js +0 -2
- package/dist/numeric-quantity.umd.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "2.0.0-beta.1",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "numeric-quantity",
|
|
5
5
|
"author": "Jake Boone <jakeboone02@gmail.com>",
|
|
@@ -7,17 +7,22 @@
|
|
|
7
7
|
"files": [
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
10
|
-
"main": "./dist/
|
|
11
|
-
"module": "./dist/numeric-quantity.
|
|
12
|
-
"
|
|
13
|
-
|
|
10
|
+
"main": "./dist/cjs/index.js",
|
|
11
|
+
"module": "./dist/numeric-quantity.legacy-esm.js",
|
|
12
|
+
"exports": {
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/numeric-quantity.d.ts",
|
|
16
|
+
"import": "./dist/numeric-quantity.mjs",
|
|
17
|
+
"require": "./dist/cjs/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"types": "./dist/numeric-quantity.d.ts",
|
|
21
|
+
"unpkg": "./dist/numeric-quantity.umd.min.js",
|
|
14
22
|
"bugs": {
|
|
15
23
|
"url": "https://github.com/jakeboone02/numeric-quantity/issues"
|
|
16
24
|
},
|
|
17
25
|
"homepage": "https://github.com/jakeboone02/numeric-quantity",
|
|
18
|
-
"engines": {
|
|
19
|
-
"node": ">=10"
|
|
20
|
-
},
|
|
21
26
|
"repository": {
|
|
22
27
|
"type": "git",
|
|
23
28
|
"url": "https://github.com/jakeboone02/numeric-quantity.git"
|
|
@@ -30,20 +35,29 @@
|
|
|
30
35
|
],
|
|
31
36
|
"scripts": {
|
|
32
37
|
"start": "vite",
|
|
33
|
-
"build": "
|
|
34
|
-
"test": "jest
|
|
35
|
-
"
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"test": "jest",
|
|
40
|
+
"watch": "jest --watch",
|
|
41
|
+
"publish:npm": "np",
|
|
42
|
+
"pretty-print": "prettier --write *.{mjs,js,ts,json} src/*.*"
|
|
36
43
|
},
|
|
37
44
|
"devDependencies": {
|
|
38
|
-
"@babel/core": "^7.
|
|
39
|
-
"@babel/preset-env": "^7.
|
|
40
|
-
"@babel/preset-typescript": "^7.
|
|
41
|
-
"@types/jest": "^
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
|
|
45
|
+
"@babel/core": "^7.22.5",
|
|
46
|
+
"@babel/preset-env": "^7.22.5",
|
|
47
|
+
"@babel/preset-typescript": "^7.22.5",
|
|
48
|
+
"@types/jest": "^29.5.2",
|
|
49
|
+
"@types/node": "^20.3.0",
|
|
50
|
+
"gh-pages": "^5.0.0",
|
|
51
|
+
"jest": "^29.5.0",
|
|
52
|
+
"np": "^8.0.3",
|
|
53
|
+
"prettier": "^2.8.8",
|
|
54
|
+
"prettier-plugin-organize-imports": "^3.2.2",
|
|
55
|
+
"tsup": "^6.7.0",
|
|
56
|
+
"typescript": "^5.1.3",
|
|
57
|
+
"vite": "^4.3.9"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=16"
|
|
61
|
+
},
|
|
62
|
+
"packageManager": "yarn@3.6.0"
|
|
49
63
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
## 1.0.1 (2021-02-15)
|
|
2
|
-
|
|
3
|
-
- Added description to package.json
|
|
4
|
-
|
|
5
|
-
## 1.0.0 (2021-02-11)
|
|
6
|
-
|
|
7
|
-
- New build system ([tsdx](https://tsdx.io/))
|
|
8
|
-
|
|
9
|
-
## 0.5.1 (2019-08-24)
|
|
10
|
-
|
|
11
|
-
- Fixed README.md note about return values
|
|
12
|
-
|
|
13
|
-
## 0.5.0 (2019-08-24)
|
|
14
|
-
|
|
15
|
-
### Breaking change
|
|
16
|
-
|
|
17
|
-
- Returns `NaN` for invalid inputs instead of `-1`
|
|
18
|
-
|
|
19
|
-
### Bug fixes
|
|
20
|
-
|
|
21
|
-
- Handles negative numbers properly (fixes [#3](https://github.com/jakeboone02/numeric-quantity/issues/3))
|
|
22
|
-
|
|
23
|
-
## 0.4.2 (2019-08-23)
|
|
24
|
-
|
|
25
|
-
- Rewritten with TypeScript
|
|
26
|
-
|
|
27
|
-
## 0.3.2 (2018-09-21)
|
|
28
|
-
|
|
29
|
-
## 0.3.1 (2015-07-16)
|
|
30
|
-
|
|
31
|
-
## 0.3.0 (2015-07-16)
|
|
32
|
-
|
|
33
|
-
## 0.1.2 (2015-03-20)
|
|
34
|
-
|
|
35
|
-
## 0.1.1 (2015-03-19)
|
|
36
|
-
|
|
37
|
-
## 0.1.0 (2015-03-18)
|
package/dist/index.d.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";var m=(e=>(e["\xBC"]="1/4",e["\xBD"]="1/2",e["\xBE"]="3/4",e["\u2150"]="1/7",e["\u2151"]="1/9",e["\u2152"]="1/10",e["\u2153"]="1/3",e["\u2154"]="2/3",e["\u2155"]="1/5",e["\u2156"]="2/5",e["\u2157"]="3/5",e["\u2158"]="4/5",e["\u2159"]="1/6",e["\u215A"]="5/6",e["\u215B"]="1/8",e["\u215C"]="3/8",e["\u215D"]="5/8",e["\u215E"]="7/8",e))(m||{});function R(e){let t=NaN;const o=/(¼|½|¾|⅐|⅑|⅒|⅓|⅔|⅕|⅖|⅗|⅘|⅙|⅚|⅛|⅜|⅝|⅞)/,f=`${e}`.replace(o,(u,n)=>` ${m[n]}`).replace(/⁄/g,"/").trim(),d=/^(-)?\s*(\d*)(\.\d+|(\s+\d*\s*)?\s*\/\s*\d+)?$/.exec(f);if(!d)return NaN;const[,p,r,s]=d;if(!r&&!s)return NaN;if(!r&&s&&s.search(/^\./)!==-1?t=0:t=parseInt(r),isNaN(t))return NaN;if(!s)return t*(p==="-"?-1:1);if(s.search(/^\./)!==-1){const u=parseFloat(s);t+=Math.round(u*1e3)/1e3}else if(s.search(/^\s*\//)!==-1){const u=parseInt(r),n=parseInt(s.replace("/",""));t=Math.round(u*1e3/n)/1e3}else{const u=s.split("/"),[n,b]=u.map(h=>parseInt(h));t+=Math.round(n*1e3/b)/1e3}return t*(p==="-"?-1:1)}module.exports=R;
|
|
2
|
-
//# sourceMappingURL=numeric-quantity.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"numeric-quantity.cjs.js","sources":["../src/index.ts"],"sourcesContent":["enum VulgarFraction {\n '¼' = '1/4',\n '½' = '1/2',\n '¾' = '3/4',\n '⅐' = '1/7',\n '⅑' = '1/9',\n '⅒' = '1/10',\n '⅓' = '1/3',\n '⅔' = '2/3',\n '⅕' = '1/5',\n '⅖' = '2/5',\n '⅗' = '3/5',\n '⅘' = '4/5',\n '⅙' = '1/6',\n '⅚' = '5/6',\n '⅛' = '1/8',\n '⅜' = '3/8',\n '⅝' = '5/8',\n '⅞' = '7/8',\n}\n\n/**\n * Converts a string to a number. The string can include mixed numbers\n * or vulgar fractions.\n */\nfunction numericQuantity(qty: string) {\n const badResult = NaN;\n let finalResult = badResult;\n\n // Resolve any unicode vulgar fractions\n const vulgarFractionsRegex = /(¼|½|¾|⅐|⅑|⅒|⅓|⅔|⅕|⅖|⅗|⅘|⅙|⅚|⅛|⅜|⅝|⅞)/;\n\n const sQty = `${qty}`\n .replace(\n vulgarFractionsRegex,\n (_m, vf: keyof typeof VulgarFraction) => ` ${VulgarFraction[vf]}`\n )\n .replace(/⁄/g, '/')\n .trim();\n\n /**\n * Regex captures\n *\n * +=====+====================+========================+\n * | # | Description | Example |\n * +=====+====================+========================+\n * | 0 | entire string | \"2 2/3\" from \"2 2/3\" |\n * +-----+--------------------+------------------------+\n * | 1 | the dash | \"-\" from \"-2 2/3\" |\n * +-----+--------------------+------------------------+\n * | 2 | the whole number | \"2\" from \"2 2/3\" |\n * | | - OR - | |\n * | | the numerator | \"2\" from \"2/3\" |\n * +-----+--------------------+------------------------+\n * | 3 | entire fraction | \"2/3\" from \"2 2/3\" |\n * | | - OR - | |\n * | | decimal portion | \".66\" from \"2.66\" |\n * | | - OR - | |\n * | | denominator | \"/3\" from \"2/3\" |\n * +=====+====================+========================+\n *\n * re.exec(\"1\") // [ \"1\", \"1\", null, null ]\n * re.exec(\"1.23\") // [ \"1.23\", \"1\", \".23\", null ]\n * re.exec(\"1 2/3\") // [ \"1 2/3\", \"1\", \" 2/3\", \" 2\" ]\n * re.exec(\"2/3\") // [ \"2/3\", \"2\", \"/3\", null ]\n * re.exec(\"2 / 3\") // [ \"2 / 3\", \"2\", \"/ 3\", null ]\n */\n const re = /^(-)?\\s*(\\d*)(\\.\\d+|(\\s+\\d*\\s*)?\\s*\\/\\s*\\d+)?$/;\n\n const ar = re.exec(sQty);\n\n // If the regex fails, give up\n if (!ar) {\n return badResult;\n }\n\n // Store the capture groups so we don't have to access the array\n // elements over and over\n const [, dash, numberGroup1, numberGroup2] = ar;\n\n // The regex can pass and still capture nothing in the relevant groups,\n // which means it failed for our purposes\n if (!numberGroup1 && !numberGroup2) {\n return badResult;\n }\n\n // Numerify capture group 1\n if (!numberGroup1 && numberGroup2 && numberGroup2.search(/^\\./) !== -1) {\n finalResult = 0;\n } else {\n finalResult = parseInt(numberGroup1);\n }\n\n if (isNaN(finalResult)) {\n return badResult;\n }\n\n // If capture group 2 is null, then we're dealing with an integer\n // and there is nothing left to process\n if (!numberGroup2) {\n return finalResult * (dash === '-' ? -1 : 1);\n }\n\n if (numberGroup2.search(/^\\./) !== -1) {\n // If first char is \".\" it's a decimal so just trim to 3 decimal places\n const numerator = parseFloat(numberGroup2);\n finalResult += Math.round(numerator * 1000) / 1000;\n } else if (numberGroup2.search(/^\\s*\\//) !== -1) {\n // If the first non-space char is \"/\" it's a pure fraction (e.g. \"1/2\")\n const numerator = parseInt(numberGroup1);\n const denominator = parseInt(numberGroup2.replace('/', ''));\n finalResult = Math.round((numerator * 1000) / denominator) / 1000;\n } else {\n // Otherwise it's a mixed fraction (e.g. \"1 2/3\")\n const fractionArray = numberGroup2.split('/');\n const [numerator, denominator] = fractionArray.map(v => parseInt(v));\n finalResult += Math.round((numerator * 1000) / denominator) / 1000;\n }\n\n return finalResult * (dash === '-' ? -1 : 1);\n}\n\nexport default numericQuantity;\n"],"names":[],"mappings":"aAAA,GAAK,IAAA,GACG,GAAA,QAAA,MACA,EAAA,QAAA,MACA,EAAA,QAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,OACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MAlBH,IAAA,GAAA,CAAA,CAAA,EAyBL,WAAyB,EAAa,CAEpC,GAAI,GAAc,IAGlB,KAAM,GAAuB,wCAEvB,EAAO,GAAG,IACb,QACC,EACA,CAAC,EAAI,IAAoC,IAAI,EAAe,IAC9D,EACC,QAAQ,KAAM,GAAG,EACjB,OA+BG,EAAK,AAFA,iDAEG,KAAK,CAAI,EAGvB,GAAI,CAAC,EACI,MAAA,KAKT,KAAM,CAAG,CAAA,EAAM,EAAc,GAAgB,EAIzC,GAAA,CAAC,GAAgB,CAAC,EACb,MAAA,KAUL,GANJ,AAAI,CAAC,GAAgB,GAAgB,EAAa,OAAO,KAAK,IAAM,GACpD,EAAA,EAEd,EAAc,SAAS,CAAY,EAGjC,MAAM,CAAW,EACZ,MAAA,KAKT,GAAI,CAAC,EACI,MAAA,GAAwB,KAAA,IAAM,GAAK,GAG5C,GAAI,EAAa,OAAO,KAAK,IAAM,GAAI,CAE/B,KAAA,GAAY,WAAW,CAAY,EACzC,GAAe,KAAK,MAAM,EAAY,GAAI,EAAI,GACrC,SAAA,EAAa,OAAO,QAAQ,IAAM,GAAI,CAEzC,KAAA,GAAY,SAAS,CAAY,EACjC,EAAc,SAAS,EAAa,QAAQ,IAAK,EAAE,CAAC,EAC1D,EAAc,KAAK,MAAO,EAAY,IAAQ,CAAW,EAAI,GAAA,KACxD,CAEC,KAAA,GAAgB,EAAa,MAAM,GAAG,EACtC,CAAC,EAAW,GAAe,EAAc,IAAI,AAAK,GAAA,SAAS,CAAC,CAAC,EACnE,GAAe,KAAK,MAAO,EAAY,IAAQ,CAAW,EAAI,GAChE,CAEO,MAAA,GAAwB,KAAA,IAAM,GAAK,EAC5C"}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
var VulgarFraction = /* @__PURE__ */ ((VulgarFraction2) => {
|
|
2
|
-
VulgarFraction2["\xBC"] = "1/4";
|
|
3
|
-
VulgarFraction2["\xBD"] = "1/2";
|
|
4
|
-
VulgarFraction2["\xBE"] = "3/4";
|
|
5
|
-
VulgarFraction2["\u2150"] = "1/7";
|
|
6
|
-
VulgarFraction2["\u2151"] = "1/9";
|
|
7
|
-
VulgarFraction2["\u2152"] = "1/10";
|
|
8
|
-
VulgarFraction2["\u2153"] = "1/3";
|
|
9
|
-
VulgarFraction2["\u2154"] = "2/3";
|
|
10
|
-
VulgarFraction2["\u2155"] = "1/5";
|
|
11
|
-
VulgarFraction2["\u2156"] = "2/5";
|
|
12
|
-
VulgarFraction2["\u2157"] = "3/5";
|
|
13
|
-
VulgarFraction2["\u2158"] = "4/5";
|
|
14
|
-
VulgarFraction2["\u2159"] = "1/6";
|
|
15
|
-
VulgarFraction2["\u215A"] = "5/6";
|
|
16
|
-
VulgarFraction2["\u215B"] = "1/8";
|
|
17
|
-
VulgarFraction2["\u215C"] = "3/8";
|
|
18
|
-
VulgarFraction2["\u215D"] = "5/8";
|
|
19
|
-
VulgarFraction2["\u215E"] = "7/8";
|
|
20
|
-
return VulgarFraction2;
|
|
21
|
-
})(VulgarFraction || {});
|
|
22
|
-
function numericQuantity(qty) {
|
|
23
|
-
const badResult = NaN;
|
|
24
|
-
let finalResult = badResult;
|
|
25
|
-
const vulgarFractionsRegex = /(¼|½|¾|⅐|⅑|⅒|⅓|⅔|⅕|⅖|⅗|⅘|⅙|⅚|⅛|⅜|⅝|⅞)/;
|
|
26
|
-
const sQty = `${qty}`.replace(vulgarFractionsRegex, (_m, vf) => ` ${VulgarFraction[vf]}`).replace(/⁄/g, "/").trim();
|
|
27
|
-
const re = /^(-)?\s*(\d*)(\.\d+|(\s+\d*\s*)?\s*\/\s*\d+)?$/;
|
|
28
|
-
const ar = re.exec(sQty);
|
|
29
|
-
if (!ar) {
|
|
30
|
-
return badResult;
|
|
31
|
-
}
|
|
32
|
-
const [, dash, numberGroup1, numberGroup2] = ar;
|
|
33
|
-
if (!numberGroup1 && !numberGroup2) {
|
|
34
|
-
return badResult;
|
|
35
|
-
}
|
|
36
|
-
if (!numberGroup1 && numberGroup2 && numberGroup2.search(/^\./) !== -1) {
|
|
37
|
-
finalResult = 0;
|
|
38
|
-
} else {
|
|
39
|
-
finalResult = parseInt(numberGroup1);
|
|
40
|
-
}
|
|
41
|
-
if (isNaN(finalResult)) {
|
|
42
|
-
return badResult;
|
|
43
|
-
}
|
|
44
|
-
if (!numberGroup2) {
|
|
45
|
-
return finalResult * (dash === "-" ? -1 : 1);
|
|
46
|
-
}
|
|
47
|
-
if (numberGroup2.search(/^\./) !== -1) {
|
|
48
|
-
const numerator = parseFloat(numberGroup2);
|
|
49
|
-
finalResult += Math.round(numerator * 1e3) / 1e3;
|
|
50
|
-
} else if (numberGroup2.search(/^\s*\//) !== -1) {
|
|
51
|
-
const numerator = parseInt(numberGroup1);
|
|
52
|
-
const denominator = parseInt(numberGroup2.replace("/", ""));
|
|
53
|
-
finalResult = Math.round(numerator * 1e3 / denominator) / 1e3;
|
|
54
|
-
} else {
|
|
55
|
-
const fractionArray = numberGroup2.split("/");
|
|
56
|
-
const [numerator, denominator] = fractionArray.map((v) => parseInt(v));
|
|
57
|
-
finalResult += Math.round(numerator * 1e3 / denominator) / 1e3;
|
|
58
|
-
}
|
|
59
|
-
return finalResult * (dash === "-" ? -1 : 1);
|
|
60
|
-
}
|
|
61
|
-
export { numericQuantity as default };
|
|
62
|
-
//# sourceMappingURL=numeric-quantity.es.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"numeric-quantity.es.js","sources":["../src/index.ts"],"sourcesContent":["enum VulgarFraction {\n '¼' = '1/4',\n '½' = '1/2',\n '¾' = '3/4',\n '⅐' = '1/7',\n '⅑' = '1/9',\n '⅒' = '1/10',\n '⅓' = '1/3',\n '⅔' = '2/3',\n '⅕' = '1/5',\n '⅖' = '2/5',\n '⅗' = '3/5',\n '⅘' = '4/5',\n '⅙' = '1/6',\n '⅚' = '5/6',\n '⅛' = '1/8',\n '⅜' = '3/8',\n '⅝' = '5/8',\n '⅞' = '7/8',\n}\n\n/**\n * Converts a string to a number. The string can include mixed numbers\n * or vulgar fractions.\n */\nfunction numericQuantity(qty: string) {\n const badResult = NaN;\n let finalResult = badResult;\n\n // Resolve any unicode vulgar fractions\n const vulgarFractionsRegex = /(¼|½|¾|⅐|⅑|⅒|⅓|⅔|⅕|⅖|⅗|⅘|⅙|⅚|⅛|⅜|⅝|⅞)/;\n\n const sQty = `${qty}`\n .replace(\n vulgarFractionsRegex,\n (_m, vf: keyof typeof VulgarFraction) => ` ${VulgarFraction[vf]}`\n )\n .replace(/⁄/g, '/')\n .trim();\n\n /**\n * Regex captures\n *\n * +=====+====================+========================+\n * | # | Description | Example |\n * +=====+====================+========================+\n * | 0 | entire string | \"2 2/3\" from \"2 2/3\" |\n * +-----+--------------------+------------------------+\n * | 1 | the dash | \"-\" from \"-2 2/3\" |\n * +-----+--------------------+------------------------+\n * | 2 | the whole number | \"2\" from \"2 2/3\" |\n * | | - OR - | |\n * | | the numerator | \"2\" from \"2/3\" |\n * +-----+--------------------+------------------------+\n * | 3 | entire fraction | \"2/3\" from \"2 2/3\" |\n * | | - OR - | |\n * | | decimal portion | \".66\" from \"2.66\" |\n * | | - OR - | |\n * | | denominator | \"/3\" from \"2/3\" |\n * +=====+====================+========================+\n *\n * re.exec(\"1\") // [ \"1\", \"1\", null, null ]\n * re.exec(\"1.23\") // [ \"1.23\", \"1\", \".23\", null ]\n * re.exec(\"1 2/3\") // [ \"1 2/3\", \"1\", \" 2/3\", \" 2\" ]\n * re.exec(\"2/3\") // [ \"2/3\", \"2\", \"/3\", null ]\n * re.exec(\"2 / 3\") // [ \"2 / 3\", \"2\", \"/ 3\", null ]\n */\n const re = /^(-)?\\s*(\\d*)(\\.\\d+|(\\s+\\d*\\s*)?\\s*\\/\\s*\\d+)?$/;\n\n const ar = re.exec(sQty);\n\n // If the regex fails, give up\n if (!ar) {\n return badResult;\n }\n\n // Store the capture groups so we don't have to access the array\n // elements over and over\n const [, dash, numberGroup1, numberGroup2] = ar;\n\n // The regex can pass and still capture nothing in the relevant groups,\n // which means it failed for our purposes\n if (!numberGroup1 && !numberGroup2) {\n return badResult;\n }\n\n // Numerify capture group 1\n if (!numberGroup1 && numberGroup2 && numberGroup2.search(/^\\./) !== -1) {\n finalResult = 0;\n } else {\n finalResult = parseInt(numberGroup1);\n }\n\n if (isNaN(finalResult)) {\n return badResult;\n }\n\n // If capture group 2 is null, then we're dealing with an integer\n // and there is nothing left to process\n if (!numberGroup2) {\n return finalResult * (dash === '-' ? -1 : 1);\n }\n\n if (numberGroup2.search(/^\\./) !== -1) {\n // If first char is \".\" it's a decimal so just trim to 3 decimal places\n const numerator = parseFloat(numberGroup2);\n finalResult += Math.round(numerator * 1000) / 1000;\n } else if (numberGroup2.search(/^\\s*\\//) !== -1) {\n // If the first non-space char is \"/\" it's a pure fraction (e.g. \"1/2\")\n const numerator = parseInt(numberGroup1);\n const denominator = parseInt(numberGroup2.replace('/', ''));\n finalResult = Math.round((numerator * 1000) / denominator) / 1000;\n } else {\n // Otherwise it's a mixed fraction (e.g. \"1 2/3\")\n const fractionArray = numberGroup2.split('/');\n const [numerator, denominator] = fractionArray.map(v => parseInt(v));\n finalResult += Math.round((numerator * 1000) / denominator) / 1000;\n }\n\n return finalResult * (dash === '-' ? -1 : 1);\n}\n\nexport default numericQuantity;\n"],"names":[],"mappings":"AAAA,IAAK,mCAAA,oBAAL;AACQ,kBAAA,UAAA;AACA,kBAAA,UAAA;AACA,kBAAA,UAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AACA,kBAAA,YAAA;AAlBH,SAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAyBL,yBAAyB,KAAa;AACpC,QAAM,YAAY;AAClB,MAAI,cAAc;AAGlB,QAAM,uBAAuB;AAE7B,QAAM,OAAO,GAAG,MACb,QACC,sBACA,CAAC,IAAI,OAAoC,IAAI,eAAe,KAC9D,EACC,QAAQ,MAAM,GAAG,EACjB;AA6BH,QAAM,KAAK;AAEL,QAAA,KAAK,GAAG,KAAK,IAAI;AAGvB,MAAI,CAAC,IAAI;AACA,WAAA;AAAA,EACT;AAIA,QAAM,CAAG,EAAA,MAAM,cAAc,gBAAgB;AAIzC,MAAA,CAAC,gBAAgB,CAAC,cAAc;AAC3B,WAAA;AAAA,EACT;AAGA,MAAI,CAAC,gBAAgB,gBAAgB,aAAa,OAAO,KAAK,MAAM,IAAI;AACxD,kBAAA;AAAA,EAAA,OACT;AACL,kBAAc,SAAS,YAAY;AAAA,EACrC;AAEI,MAAA,MAAM,WAAW,GAAG;AACf,WAAA;AAAA,EACT;AAIA,MAAI,CAAC,cAAc;AACV,WAAA,cAAwB,UAAA,MAAM,KAAK;AAAA,EAC5C;AAEA,MAAI,aAAa,OAAO,KAAK,MAAM,IAAI;AAE/B,UAAA,YAAY,WAAW,YAAY;AACzC,mBAAe,KAAK,MAAM,YAAY,GAAI,IAAI;AAAA,EACrC,WAAA,aAAa,OAAO,QAAQ,MAAM,IAAI;AAEzC,UAAA,YAAY,SAAS,YAAY;AACvC,UAAM,cAAc,SAAS,aAAa,QAAQ,KAAK,EAAE,CAAC;AAC1D,kBAAc,KAAK,MAAO,YAAY,MAAQ,WAAW,IAAI;AAAA,EAAA,OACxD;AAEC,UAAA,gBAAgB,aAAa,MAAM,GAAG;AACtC,UAAA,CAAC,WAAW,eAAe,cAAc,IAAI,CAAK,MAAA,SAAS,CAAC,CAAC;AACnE,mBAAe,KAAK,MAAO,YAAY,MAAQ,WAAW,IAAI;AAAA,EAChE;AAEO,SAAA,cAAwB,UAAA,MAAM,KAAK;AAC5C;;"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
(function(n,d){typeof exports=="object"&&typeof module!="undefined"?module.exports=d():typeof define=="function"&&define.amd?define(d):(n=typeof globalThis!="undefined"?globalThis:n||self,n.numericQuantity=d())})(this,function(){"use strict";var n=(e=>(e["\xBC"]="1/4",e["\xBD"]="1/2",e["\xBE"]="3/4",e["\u2150"]="1/7",e["\u2151"]="1/9",e["\u2152"]="1/10",e["\u2153"]="1/3",e["\u2154"]="2/3",e["\u2155"]="1/5",e["\u2156"]="2/5",e["\u2157"]="3/5",e["\u2158"]="4/5",e["\u2159"]="1/6",e["\u215A"]="5/6",e["\u215B"]="1/8",e["\u215C"]="3/8",e["\u215D"]="5/8",e["\u215E"]="7/8",e))(n||{});function d(e){let t=NaN;const i=/(¼|½|¾|⅐|⅑|⅒|⅓|⅔|⅕|⅖|⅗|⅘|⅙|⅚|⅛|⅜|⅝|⅞)/,m=`${e}`.replace(i,(u,f)=>` ${n[f]}`).replace(/⁄/g,"/").trim(),r=/^(-)?\s*(\d*)(\.\d+|(\s+\d*\s*)?\s*\/\s*\d+)?$/.exec(m);if(!r)return NaN;const[,p,o,s]=r;if(!o&&!s)return NaN;if(!o&&s&&s.search(/^\./)!==-1?t=0:t=parseInt(o),isNaN(t))return NaN;if(!s)return t*(p==="-"?-1:1);if(s.search(/^\./)!==-1){const u=parseFloat(s);t+=Math.round(u*1e3)/1e3}else if(s.search(/^\s*\//)!==-1){const u=parseInt(o),f=parseInt(s.replace("/",""));t=Math.round(u*1e3/f)/1e3}else{const u=s.split("/"),[f,h]=u.map(c=>parseInt(c));t+=Math.round(f*1e3/h)/1e3}return t*(p==="-"?-1:1)}return d});
|
|
2
|
-
//# sourceMappingURL=numeric-quantity.umd.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"numeric-quantity.umd.js","sources":["../src/index.ts"],"sourcesContent":["enum VulgarFraction {\n '¼' = '1/4',\n '½' = '1/2',\n '¾' = '3/4',\n '⅐' = '1/7',\n '⅑' = '1/9',\n '⅒' = '1/10',\n '⅓' = '1/3',\n '⅔' = '2/3',\n '⅕' = '1/5',\n '⅖' = '2/5',\n '⅗' = '3/5',\n '⅘' = '4/5',\n '⅙' = '1/6',\n '⅚' = '5/6',\n '⅛' = '1/8',\n '⅜' = '3/8',\n '⅝' = '5/8',\n '⅞' = '7/8',\n}\n\n/**\n * Converts a string to a number. The string can include mixed numbers\n * or vulgar fractions.\n */\nfunction numericQuantity(qty: string) {\n const badResult = NaN;\n let finalResult = badResult;\n\n // Resolve any unicode vulgar fractions\n const vulgarFractionsRegex = /(¼|½|¾|⅐|⅑|⅒|⅓|⅔|⅕|⅖|⅗|⅘|⅙|⅚|⅛|⅜|⅝|⅞)/;\n\n const sQty = `${qty}`\n .replace(\n vulgarFractionsRegex,\n (_m, vf: keyof typeof VulgarFraction) => ` ${VulgarFraction[vf]}`\n )\n .replace(/⁄/g, '/')\n .trim();\n\n /**\n * Regex captures\n *\n * +=====+====================+========================+\n * | # | Description | Example |\n * +=====+====================+========================+\n * | 0 | entire string | \"2 2/3\" from \"2 2/3\" |\n * +-----+--------------------+------------------------+\n * | 1 | the dash | \"-\" from \"-2 2/3\" |\n * +-----+--------------------+------------------------+\n * | 2 | the whole number | \"2\" from \"2 2/3\" |\n * | | - OR - | |\n * | | the numerator | \"2\" from \"2/3\" |\n * +-----+--------------------+------------------------+\n * | 3 | entire fraction | \"2/3\" from \"2 2/3\" |\n * | | - OR - | |\n * | | decimal portion | \".66\" from \"2.66\" |\n * | | - OR - | |\n * | | denominator | \"/3\" from \"2/3\" |\n * +=====+====================+========================+\n *\n * re.exec(\"1\") // [ \"1\", \"1\", null, null ]\n * re.exec(\"1.23\") // [ \"1.23\", \"1\", \".23\", null ]\n * re.exec(\"1 2/3\") // [ \"1 2/3\", \"1\", \" 2/3\", \" 2\" ]\n * re.exec(\"2/3\") // [ \"2/3\", \"2\", \"/3\", null ]\n * re.exec(\"2 / 3\") // [ \"2 / 3\", \"2\", \"/ 3\", null ]\n */\n const re = /^(-)?\\s*(\\d*)(\\.\\d+|(\\s+\\d*\\s*)?\\s*\\/\\s*\\d+)?$/;\n\n const ar = re.exec(sQty);\n\n // If the regex fails, give up\n if (!ar) {\n return badResult;\n }\n\n // Store the capture groups so we don't have to access the array\n // elements over and over\n const [, dash, numberGroup1, numberGroup2] = ar;\n\n // The regex can pass and still capture nothing in the relevant groups,\n // which means it failed for our purposes\n if (!numberGroup1 && !numberGroup2) {\n return badResult;\n }\n\n // Numerify capture group 1\n if (!numberGroup1 && numberGroup2 && numberGroup2.search(/^\\./) !== -1) {\n finalResult = 0;\n } else {\n finalResult = parseInt(numberGroup1);\n }\n\n if (isNaN(finalResult)) {\n return badResult;\n }\n\n // If capture group 2 is null, then we're dealing with an integer\n // and there is nothing left to process\n if (!numberGroup2) {\n return finalResult * (dash === '-' ? -1 : 1);\n }\n\n if (numberGroup2.search(/^\\./) !== -1) {\n // If first char is \".\" it's a decimal so just trim to 3 decimal places\n const numerator = parseFloat(numberGroup2);\n finalResult += Math.round(numerator * 1000) / 1000;\n } else if (numberGroup2.search(/^\\s*\\//) !== -1) {\n // If the first non-space char is \"/\" it's a pure fraction (e.g. \"1/2\")\n const numerator = parseInt(numberGroup1);\n const denominator = parseInt(numberGroup2.replace('/', ''));\n finalResult = Math.round((numerator * 1000) / denominator) / 1000;\n } else {\n // Otherwise it's a mixed fraction (e.g. \"1 2/3\")\n const fractionArray = numberGroup2.split('/');\n const [numerator, denominator] = fractionArray.map(v => parseInt(v));\n finalResult += Math.round((numerator * 1000) / denominator) / 1000;\n }\n\n return finalResult * (dash === '-' ? -1 : 1);\n}\n\nexport default numericQuantity;\n"],"names":[],"mappings":"kPAAA,GAAK,IAAA,GACG,GAAA,QAAA,MACA,EAAA,QAAA,MACA,EAAA,QAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,OACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MACA,EAAA,UAAA,MAlBH,IAAA,GAAA,CAAA,CAAA,EAyBL,WAAyB,EAAa,CAEpC,GAAI,GAAc,IAGlB,KAAM,GAAuB,wCAEvB,EAAO,GAAG,IACb,QACC,EACA,CAAC,EAAI,IAAoC,IAAI,EAAe,IAC9D,EACC,QAAQ,KAAM,GAAG,EACjB,OA+BG,EAAK,AAFA,iDAEG,KAAK,CAAI,EAGvB,GAAI,CAAC,EACI,MAAA,KAKT,KAAM,CAAG,CAAA,EAAM,EAAc,GAAgB,EAIzC,GAAA,CAAC,GAAgB,CAAC,EACb,MAAA,KAUL,GANJ,AAAI,CAAC,GAAgB,GAAgB,EAAa,OAAO,KAAK,IAAM,GACpD,EAAA,EAEd,EAAc,SAAS,CAAY,EAGjC,MAAM,CAAW,EACZ,MAAA,KAKT,GAAI,CAAC,EACI,MAAA,GAAwB,KAAA,IAAM,GAAK,GAG5C,GAAI,EAAa,OAAO,KAAK,IAAM,GAAI,CAE/B,KAAA,GAAY,WAAW,CAAY,EACzC,GAAe,KAAK,MAAM,EAAY,GAAI,EAAI,GACrC,SAAA,EAAa,OAAO,QAAQ,IAAM,GAAI,CAEzC,KAAA,GAAY,SAAS,CAAY,EACjC,EAAc,SAAS,EAAa,QAAQ,IAAK,EAAE,CAAC,EAC1D,EAAc,KAAK,MAAO,EAAY,IAAQ,CAAW,EAAI,GAAA,KACxD,CAEC,KAAA,GAAgB,EAAa,MAAM,GAAG,EACtC,CAAC,EAAW,GAAe,EAAc,IAAI,AAAK,GAAA,SAAS,CAAC,CAAC,EACnE,GAAe,KAAK,MAAO,EAAY,IAAQ,CAAW,EAAI,GAChE,CAEO,MAAA,GAAwB,KAAA,IAAM,GAAK,EAC5C"}
|