@lhncbc/ucum-lhc 7.1.6 → 7.1.8
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/browser-dist/ucum-lhc.min.js +1 -1
- package/browser-dist/ucum-lhc.min.js.map +1 -1
- package/package.json +6 -8
- package/source/unitString.js +165 -99
- package/source-cjs/config.js +1 -2
- package/source-cjs/config.js.map +1 -1
- package/source-cjs/dimension.js.map +1 -1
- package/source-cjs/prefixTables.js +2 -3
- package/source-cjs/prefixTables.js.map +1 -1
- package/source-cjs/ucumFunctions.js +1 -2
- package/source-cjs/ucumFunctions.js.map +1 -1
- package/source-cjs/ucumInternalUtils.js +2 -2
- package/source-cjs/ucumJsonDefs.js +1 -2
- package/source-cjs/ucumJsonDefs.js.map +1 -1
- package/source-cjs/ucumLhcUtils.js.map +1 -1
- package/source-cjs/ucumPkg.js +3 -6
- package/source-cjs/ucumPkg.js.map +1 -1
- package/source-cjs/ucumXmlDocument.js.map +1 -1
- package/source-cjs/unit.js.map +1 -1
- package/source-cjs/unitString.js +150 -92
- package/source-cjs/unitString.js.map +1 -1
- package/source-cjs/unitTables.js +1 -2
- package/source-cjs/unitTables.js.map +1 -1
package/source-cjs/unitString.js
CHANGED
|
@@ -990,34 +990,6 @@ class UnitString {
|
|
|
990
990
|
retUnit.ciCode_ = retUnit.ciCode_.replace('*', '^');
|
|
991
991
|
}
|
|
992
992
|
}
|
|
993
|
-
// If that didn't work, check to see if it should have brackets
|
|
994
|
-
// around it (uCode = degF when it should be [degF]
|
|
995
|
-
if (!retUnit) {
|
|
996
|
-
let addBrackets = '[' + uCode + ']';
|
|
997
|
-
retUnit = this.utabs_.getUnitByCode(addBrackets);
|
|
998
|
-
if (retUnit) {
|
|
999
|
-
retUnit = retUnit.clone();
|
|
1000
|
-
origString = origString.replace(uCode, addBrackets);
|
|
1001
|
-
this.retMsg_.push(`${uCode} is not a valid unit expression, but ` + `${addBrackets} is.\n` + this.vcMsgStart_ + `${addBrackets} (${retUnit.name_})${this.vcMsgEnd_}`);
|
|
1002
|
-
} // end if we found the unit after adding brackets
|
|
1003
|
-
} // end trying to add brackets
|
|
1004
|
-
|
|
1005
|
-
// If we didn't find it, try it as a name
|
|
1006
|
-
if (!retUnit) {
|
|
1007
|
-
let retUnitAry = this.utabs_.getUnitByName(uCode);
|
|
1008
|
-
if (retUnitAry && retUnitAry.length > 0) {
|
|
1009
|
-
retUnit = retUnitAry[0].clone();
|
|
1010
|
-
let mString = 'The UCUM code for ' + uCode + ' is ' + retUnit.csCode_ + '.\n' + this.vcMsgStart_ + retUnit.csCode_ + this.vcMsgEnd_;
|
|
1011
|
-
let dupMsg = false;
|
|
1012
|
-
for (let r = 0; r < this.retMsg_.length && !dupMsg; r++) dupMsg = this.retMsg_[r] === mString;
|
|
1013
|
-
if (!dupMsg) this.retMsg_.push(mString);
|
|
1014
|
-
let rStr = new RegExp('(^|[.\/({])(' + uCode + ')($|[.\/)}])');
|
|
1015
|
-
let res = origString.match(rStr);
|
|
1016
|
-
origString = origString.replace(rStr, res[1] + retUnit.csCode_ + res[3]);
|
|
1017
|
-
uCode = retUnit.csCode_;
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
993
|
// If we still don't have a unit, try assuming a modifier (prefix and/or
|
|
1022
994
|
// exponent) and look for a unit without the modifier
|
|
1023
995
|
if (!retUnit) {
|
|
@@ -1091,12 +1063,21 @@ class UnitString {
|
|
|
1091
1063
|
// without the exponent, the unit string without a prefix,
|
|
1092
1064
|
// common errors, etc. That's all we can try).
|
|
1093
1065
|
if (!origUnit) {
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1066
|
+
let bracketRet = this._getUnitAfterAddingBrackets(origCode, origString);
|
|
1067
|
+
retUnit = bracketRet[0];
|
|
1068
|
+
origString = bracketRet[1];
|
|
1069
|
+
if (!retUnit) {
|
|
1070
|
+
let nameRet = this._getUnitByName(origCode, origString);
|
|
1071
|
+
retUnit = nameRet[0];
|
|
1072
|
+
origString = nameRet[1];
|
|
1073
|
+
if (!retUnit) {
|
|
1074
|
+
// BUT if the user asked for suggestions, at least look for them
|
|
1075
|
+
if (this.suggestions_) {
|
|
1076
|
+
let suggestStat = this._getSuggestions(origCode);
|
|
1077
|
+
} else {
|
|
1078
|
+
this.retMsg_.push(`${origCode} is not a valid UCUM code.`);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1100
1081
|
}
|
|
1101
1082
|
} else {
|
|
1102
1083
|
// Otherwise we found a unit object. Clone it and then apply the
|
|
@@ -1114,75 +1095,83 @@ class UnitString {
|
|
|
1114
1095
|
// If there is an exponent for the unit, apply it to the dimension
|
|
1115
1096
|
// and magnitude now
|
|
1116
1097
|
if (exp) {
|
|
1117
|
-
|
|
1118
|
-
if (
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1098
|
+
// Special units cannot be raised to a power
|
|
1099
|
+
if (retUnit.isSpecial_) {
|
|
1100
|
+
this.retMsg_.push(`Special units like ${retUnit.name_} cannot be raised to a power.`);
|
|
1101
|
+
retUnit = null;
|
|
1102
|
+
} else {
|
|
1103
|
+
exp = parseInt(exp);
|
|
1104
|
+
if (theDim) theDim = theDim.mul(exp);
|
|
1105
|
+
retUnit.equivalentExp_ *= exp;
|
|
1106
|
+
retUnit.moleExp_ *= exp;
|
|
1107
|
+
theMag = Math.pow(theMag, exp);
|
|
1108
|
+
retUnit.assignVals({
|
|
1109
|
+
'magnitude_': theMag
|
|
1110
|
+
});
|
|
1125
1111
|
|
|
1126
|
-
|
|
1112
|
+
// If there is also a prefix, apply the exponent to the prefix.
|
|
1113
|
+
if (pfxObj) {
|
|
1114
|
+
// We don't need to consider pfxObj.getExp(), because when
|
|
1115
|
+
// present that is reflected in the pfxVal. However, in some
|
|
1116
|
+
// cases one can avoid floating-point math inaccuracies by using
|
|
1117
|
+
// that exponent instead of relying on pfxVal. For example:
|
|
1118
|
+
// 1e-66 = Math.pow(10, -3*22) = Math.pow(0.001, 22) = 1.0000000000000005e-66
|
|
1119
|
+
// (This is the from the test case of the unit mg% raised to the 22nd power (mg%22).)
|
|
1120
|
+
// This does not help in all cases, but it does help the above
|
|
1121
|
+
// test case (which is in our web API service test code).
|
|
1122
|
+
let pfxExp = pfxObj.getExp();
|
|
1123
|
+
if (pfxExp) {
|
|
1124
|
+
// This is relying on the fact that pfxExp is null when
|
|
1125
|
+
// the prefix base is not 10.
|
|
1126
|
+
pfxVal = Math.pow(10, exp * pfxExp);
|
|
1127
|
+
} else {
|
|
1128
|
+
pfxVal = Math.pow(pfxVal, exp);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
} // end else - prefix and exponent handling for non-special units
|
|
1132
|
+
} // end if there's an exponent
|
|
1133
|
+
|
|
1134
|
+
if (retUnit) {
|
|
1135
|
+
// Now apply the prefix, if there is one, to the conversion
|
|
1136
|
+
// prefix or the magnitude
|
|
1127
1137
|
if (pfxObj) {
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
// 1e-66 = Math.pow(10, -3*22) = Math.pow(0.001, 22) = 1.0000000000000005e-66
|
|
1133
|
-
// (This is the from the test case of the unit mg% raised to the 22nd power (mg%22).)
|
|
1134
|
-
// This does not help in all cases, but it does help the above
|
|
1135
|
-
// test case (which is in our web API service test code).
|
|
1136
|
-
let pfxExp = pfxObj.getExp();
|
|
1137
|
-
if (pfxExp) {
|
|
1138
|
-
// This is relying on the fact that pfxExp is null when
|
|
1139
|
-
// the prefix base is not 10.
|
|
1140
|
-
pfxVal = Math.pow(10, exp * pfxExp);
|
|
1138
|
+
if (retUnit.cnv_) {
|
|
1139
|
+
retUnit.assignVals({
|
|
1140
|
+
'cnvPfx_': pfxVal
|
|
1141
|
+
});
|
|
1141
1142
|
} else {
|
|
1142
|
-
|
|
1143
|
+
theMag *= pfxVal;
|
|
1144
|
+
retUnit.assignVals({
|
|
1145
|
+
'magnitude_': theMag
|
|
1146
|
+
});
|
|
1143
1147
|
}
|
|
1144
1148
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1149
|
+
// if we have a prefix and/or an exponent, add them to the unit
|
|
1150
|
+
// attributes - name, csCode, ciCode and print symbol
|
|
1151
|
+
let theCode = retUnit.csCode_;
|
|
1152
|
+
if (pfxObj) {
|
|
1153
|
+
theName = pfxObj.getName() + theName;
|
|
1154
|
+
theCode = pfxCode + theCode;
|
|
1155
|
+
theCiCode = pfxObj.getCiCode() + theCiCode;
|
|
1156
|
+
thePrintSymbol = pfxObj.getPrintSymbol() + thePrintSymbol;
|
|
1151
1157
|
retUnit.assignVals({
|
|
1152
|
-
'
|
|
1158
|
+
'name_': theName,
|
|
1159
|
+
'csCode_': theCode,
|
|
1160
|
+
'ciCode_': theCiCode,
|
|
1161
|
+
'printSymbol_': thePrintSymbol
|
|
1153
1162
|
});
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1163
|
+
}
|
|
1164
|
+
if (exp) {
|
|
1165
|
+
let expStr = exp.toString();
|
|
1166
|
+
const intergerUnitExpSign = isIntegerUnitWithExp && exp > 0 ? '+' : '';
|
|
1156
1167
|
retUnit.assignVals({
|
|
1157
|
-
'
|
|
1168
|
+
'name_': theName + '<sup>' + expStr + '</sup>',
|
|
1169
|
+
'csCode_': theCode + intergerUnitExpSign + expStr,
|
|
1170
|
+
'ciCode_': theCiCode + intergerUnitExpSign + expStr,
|
|
1171
|
+
'printSymbol_': thePrintSymbol + '<sup>' + expStr + '</sup>'
|
|
1158
1172
|
});
|
|
1159
1173
|
}
|
|
1160
1174
|
}
|
|
1161
|
-
// if we have a prefix and/or an exponent, add them to the unit
|
|
1162
|
-
// attributes - name, csCode, ciCode and print symbol
|
|
1163
|
-
let theCode = retUnit.csCode_;
|
|
1164
|
-
if (pfxObj) {
|
|
1165
|
-
theName = pfxObj.getName() + theName;
|
|
1166
|
-
theCode = pfxCode + theCode;
|
|
1167
|
-
theCiCode = pfxObj.getCiCode() + theCiCode;
|
|
1168
|
-
thePrintSymbol = pfxObj.getPrintSymbol() + thePrintSymbol;
|
|
1169
|
-
retUnit.assignVals({
|
|
1170
|
-
'name_': theName,
|
|
1171
|
-
'csCode_': theCode,
|
|
1172
|
-
'ciCode_': theCiCode,
|
|
1173
|
-
'printSymbol_': thePrintSymbol
|
|
1174
|
-
});
|
|
1175
|
-
}
|
|
1176
|
-
if (exp) {
|
|
1177
|
-
let expStr = exp.toString();
|
|
1178
|
-
const intergerUnitExpSign = isIntegerUnitWithExp && exp > 0 ? '+' : '';
|
|
1179
|
-
retUnit.assignVals({
|
|
1180
|
-
'name_': theName + '<sup>' + expStr + '</sup>',
|
|
1181
|
-
'csCode_': theCode + intergerUnitExpSign + expStr,
|
|
1182
|
-
'ciCode_': theCiCode + intergerUnitExpSign + expStr,
|
|
1183
|
-
'printSymbol_': thePrintSymbol + '<sup>' + expStr + '</sup>'
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
1175
|
} // end if an original unit was found (without prefix and/or exponent)
|
|
1187
1176
|
} // end if an invalid exponent wasn't found
|
|
1188
1177
|
} // end if we didn't get a unit for the full unit code (w/out modifiers)
|
|
@@ -1190,6 +1179,75 @@ class UnitString {
|
|
|
1190
1179
|
return [retUnit, origString];
|
|
1191
1180
|
} // end _makeUnit
|
|
1192
1181
|
|
|
1182
|
+
/**
|
|
1183
|
+
* Checks whether an otherwise unresolved unit code matches a unit name.
|
|
1184
|
+
*
|
|
1185
|
+
* @param uCode the unit code or name to check
|
|
1186
|
+
* @param origString the original full string submitted to parseString
|
|
1187
|
+
* @returns an array containing the unit object found, or null, and origString
|
|
1188
|
+
*/
|
|
1189
|
+
_getUnitByName(uCode, origString) {
|
|
1190
|
+
let retUnit = null;
|
|
1191
|
+
let retUnitAry = this.utabs_.getUnitByName(uCode);
|
|
1192
|
+
if (retUnitAry && retUnitAry.length > 0) {
|
|
1193
|
+
retUnit = retUnitAry[0].clone();
|
|
1194
|
+
let mString = 'The UCUM code for ' + uCode + ' is ' + retUnit.csCode_ + '.\n' + this.vcMsgStart_ + retUnit.csCode_ + this.vcMsgEnd_;
|
|
1195
|
+
let dupMsg = false;
|
|
1196
|
+
for (let r = 0; r < this.retMsg_.length && !dupMsg; r++) dupMsg = this.retMsg_[r] === mString;
|
|
1197
|
+
if (!dupMsg) this.retMsg_.push(mString);
|
|
1198
|
+
const escapedCode = uCode.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1199
|
+
let rStr = new RegExp('(^|[./(])(' + escapedCode + ')($|[./)\\-\\d{])');
|
|
1200
|
+
const updatedOrigString = origString.replace(rStr, '$1' + retUnit.csCode_ + '$3');
|
|
1201
|
+
if (updatedOrigString == origString) {
|
|
1202
|
+
// This should not happen, if the processing has been correct. However, if it does happen, we
|
|
1203
|
+
// still have to change origString to signal that the input unit is invalid.
|
|
1204
|
+
// There is a test present to make sure this message does not appear from the top-level APIs in
|
|
1205
|
+
// ucumLhcUtils.js.
|
|
1206
|
+
// Ideally, this problem would be signalled some other way, but that would be a bigger change.
|
|
1207
|
+
origString += ' (Unable to update the unit expression with a suggested replacement.)';
|
|
1208
|
+
} else {
|
|
1209
|
+
origString = updatedOrigString;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
return [retUnit, origString];
|
|
1213
|
+
} // end _getUnitByName
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* Checks whether an otherwise unresolved unit code can be found after adding
|
|
1217
|
+
* square brackets, e.g., degF -> [degF]. If a bracketed unit is found,
|
|
1218
|
+
* origString is modified to include the suggested replacement.
|
|
1219
|
+
*
|
|
1220
|
+
* @param uCode the unit code to check
|
|
1221
|
+
* @param origString the original full string submitted to parseString
|
|
1222
|
+
* @returns an array containing the unit object found, or null, and the possibly
|
|
1223
|
+
* modified origString
|
|
1224
|
+
*/
|
|
1225
|
+
_getUnitAfterAddingBrackets(uCode, origString) {
|
|
1226
|
+
let retUnit = null;
|
|
1227
|
+
const addBrackets = '[' + uCode + ']';
|
|
1228
|
+
const bracketUnit = this.utabs_.getUnitByCode(addBrackets);
|
|
1229
|
+
if (bracketUnit) {
|
|
1230
|
+
retUnit = bracketUnit.clone();
|
|
1231
|
+
const escapedCode = uCode.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1232
|
+
const leadingUnitBoundary = '(^|[./(])';
|
|
1233
|
+
const trailingUnitBoundary = '($|[./)\\-\\d{])';
|
|
1234
|
+
const rStr = new RegExp(leadingUnitBoundary + '(' + escapedCode + ')' + trailingUnitBoundary);
|
|
1235
|
+
const updatedOrigString = origString.replace(rStr, '$1' + addBrackets + '$3');
|
|
1236
|
+
if (updatedOrigString == origString) {
|
|
1237
|
+
// This should not happen, if the processing has been correct. However, if it does happen, we
|
|
1238
|
+
// still have to change origString to signal that the input unit is invalid.
|
|
1239
|
+
// There is a test present to make sure this message does not appear from the top-level APIs in
|
|
1240
|
+
// ucumLhcUtils.js.
|
|
1241
|
+
// Ideally, this problem would be signalled some other way, but that would be a bigger change.
|
|
1242
|
+
origString += ' (Unable to update the unit expression with a suggested replacement.)';
|
|
1243
|
+
} else {
|
|
1244
|
+
origString = updatedOrigString;
|
|
1245
|
+
}
|
|
1246
|
+
this.retMsg_.push(`${uCode} is not a valid unit expression, but ` + `${addBrackets} is.\n` + this.vcMsgStart_ + `${addBrackets} (${retUnit.name_})${this.vcMsgEnd_}`);
|
|
1247
|
+
}
|
|
1248
|
+
return [retUnit, origString];
|
|
1249
|
+
} // end _getUnitAfterAddingBrackets
|
|
1250
|
+
|
|
1193
1251
|
/**
|
|
1194
1252
|
* This method handles unit creation when an annotation is included
|
|
1195
1253
|
* in the unit string. This basically isolates and retrieves the
|