@open-charging-cloud/chargy-core 0.5.0 → 0.6.2

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.
Files changed (54) hide show
  1. package/README.md +2 -2
  2. package/dist/ACrypt.d.ts +2 -2
  3. package/dist/ACrypt.d.ts.map +1 -1
  4. package/dist/Alfen.d.ts +6 -6
  5. package/dist/Alfen.d.ts.map +1 -1
  6. package/dist/BSMCrypt01.d.ts +8 -9
  7. package/dist/BSMCrypt01.d.ts.map +1 -1
  8. package/dist/EMHCrypt01.d.ts +8 -8
  9. package/dist/EMHCrypt01.d.ts.map +1 -1
  10. package/dist/GDFCrypt01.d.ts +8 -8
  11. package/dist/GDFCrypt01.d.ts.map +1 -1
  12. package/dist/Mennekes.d.ts +22 -22
  13. package/dist/Mennekes.d.ts.map +1 -1
  14. package/dist/OCMF.d.ts +25 -27
  15. package/dist/OCMF.d.ts.map +1 -1
  16. package/dist/OCPI.d.ts +2 -4
  17. package/dist/OCPI.d.ts.map +1 -1
  18. package/dist/PCDF.d.ts +1 -1
  19. package/dist/PCDF.d.ts.map +1 -1
  20. package/dist/QIDigital_DCC.d.ts +1 -1
  21. package/dist/QIDigital_DCC.d.ts.map +1 -1
  22. package/dist/QIDigital_DCoA.d.ts +1 -1
  23. package/dist/QIDigital_DCoA.d.ts.map +1 -1
  24. package/dist/QIDigital_DCoC.d.ts +1 -1
  25. package/dist/QIDigital_DCoC.d.ts.map +1 -1
  26. package/dist/SAFE_XML.d.ts +16 -16
  27. package/dist/SAFE_XML.d.ts.map +1 -1
  28. package/dist/XMLContainer.d.ts +2 -2
  29. package/dist/XMLContainer.d.ts.map +1 -1
  30. package/dist/browser/index.js +1216 -1116
  31. package/dist/browser/index.js.map +1 -1
  32. package/dist/chargeIT.d.ts +1 -3
  33. package/dist/chargeIT.d.ts.map +1 -1
  34. package/dist/chargePoint.d.ts +3 -3
  35. package/dist/chargePoint.d.ts.map +1 -1
  36. package/dist/chargy.d.ts +11 -7
  37. package/dist/chargy.d.ts.map +1 -1
  38. package/dist/chargyLib.d.ts +4 -0
  39. package/dist/chargyLib.d.ts.map +1 -1
  40. package/dist/interfaces/IChargeTransparencyRecord.d.ts +76 -76
  41. package/dist/interfaces/IChargeTransparencyRecord.d.ts.map +1 -1
  42. package/dist/interfaces/chargyInterfaces.d.ts +116 -114
  43. package/dist/interfaces/chargyInterfaces.d.ts.map +1 -1
  44. package/dist/node/index.js +1216 -1116
  45. package/dist/node/index.js.map +1 -1
  46. package/dist/pdfjs/browser.d.ts +2 -1
  47. package/dist/pdfjs/browser.d.ts.map +1 -1
  48. package/dist/qrCodeReader.d.ts.map +1 -1
  49. package/dist/secp224k1.d.ts +10 -11
  50. package/dist/secp224k1.d.ts.map +1 -1
  51. package/dist/verificationResults.d.ts +2 -1
  52. package/dist/verificationResults.d.ts.map +1 -1
  53. package/i18n.json +40 -0
  54. package/package.json +3 -3
@@ -9768,9 +9768,7 @@ var secp224k1 = class {
9768
9768
  N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
9769
9769
  // Number of points in the field
9770
9770
  Acurve = BigInt(0);
9771
- // These two are defined on the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve
9772
- Bcurve = BigInt(5);
9773
- // These two are defined on the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve
9771
+ // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
9774
9772
  Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
9775
9773
  Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
9776
9774
  GPoint = [this.Gx, this.Gy];
@@ -9867,16 +9865,19 @@ var secp224k1 = class {
9867
9865
  address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
9868
9866
  };
9869
9867
  }
9868
+ return void 0;
9870
9869
  }
9871
9870
  };
9872
9871
 
9873
9872
  // src/interfaces/chargyInterfaces.ts
9874
9873
  var chargyInterfaces_exports = {};
9875
9874
  __export(chargyInterfaces_exports, {
9875
+ CreateError: () => CreateError,
9876
9876
  CryptoAlgorithms: () => CryptoAlgorithms,
9877
9877
  CryptoHashAlgorithms: () => CryptoHashAlgorithms,
9878
9878
  DayOfWeek: () => DayOfWeek,
9879
9879
  DisplayPrefixes: () => DisplayPrefixes,
9880
+ ErrorLevel: () => ErrorLevel,
9880
9881
  IECCurves: () => IECCurves,
9881
9882
  IEncoding: () => IEncoding,
9882
9883
  InformationRelevance: () => InformationRelevance,
@@ -9980,14 +9981,26 @@ var WarningLevel = /* @__PURE__ */ ((WarningLevel2) => {
9980
9981
  WarningLevel2["high"] = "high";
9981
9982
  return WarningLevel2;
9982
9983
  })(WarningLevel || {});
9984
+ var ErrorLevel = /* @__PURE__ */ ((ErrorLevel2) => {
9985
+ ErrorLevel2["low"] = "low";
9986
+ ErrorLevel2["medium"] = "medium";
9987
+ ErrorLevel2["high"] = "high";
9988
+ return ErrorLevel2;
9989
+ })(ErrorLevel || {});
9990
+ function CreateError(message, level = "high" /* high */) {
9991
+ return {
9992
+ level,
9993
+ message
9994
+ };
9995
+ }
9983
9996
  function isISessionCryptoResult1(obj) {
9984
- return typeof obj === "object" && obj !== null && obj.status !== void 0;
9997
+ return isObject(obj) && obj["status"] !== void 0;
9985
9998
  }
9986
9999
  function isISessionCryptoResult2(obj) {
9987
- return typeof obj === "object" && obj !== null && obj.status !== void 0 && obj.status !== "InvalidSessionFormat" /* InvalidSessionFormat */;
10000
+ return isObject(obj) && obj["status"] !== void 0 && obj["status"] !== "InvalidSessionFormat" /* InvalidSessionFormat */;
9988
10001
  }
9989
10002
  function isICryptoResult(obj) {
9990
- return typeof obj === "object" && obj !== null && obj.status !== void 0;
10003
+ return isObject(obj) && obj["status"] !== void 0;
9991
10004
  }
9992
10005
  var InformationRelevance = /* @__PURE__ */ ((InformationRelevance2) => {
9993
10006
  InformationRelevance2["Unknown"] = "Unknown";
@@ -10075,6 +10088,26 @@ function toArrayBuffer(data) {
10075
10088
  function toUint8Array(data) {
10076
10089
  return data instanceof Uint8Array ? data : new Uint8Array(data);
10077
10090
  }
10091
+ function getArrayElement(values, index, message = "Missing array element") {
10092
+ const value = values[index];
10093
+ if (value === void 0)
10094
+ throw new Error(message + " at index " + index.toString());
10095
+ return value;
10096
+ }
10097
+ function getFirstArrayElement(values, message = "Missing first array element") {
10098
+ return getArrayElement(values, 0, message);
10099
+ }
10100
+ function getLastArrayElement(values, message = "Missing last array element") {
10101
+ return getArrayElement(values, values.length - 1, message);
10102
+ }
10103
+ function getArrayLikeElement(values, index, message = "Missing array-like element") {
10104
+ if (index < 0 || index >= values.length)
10105
+ throw new Error(message + " at index " + index.toString());
10106
+ const value = values[index];
10107
+ if (value === void 0)
10108
+ throw new Error(message + " at index " + index.toString());
10109
+ return value;
10110
+ }
10078
10111
  function normalizeXMLText(xmlText) {
10079
10112
  return (xmlText ?? "").replace(/^\uFEFF/, "").replace(/\r\n?/g, "\n").replace(/>\s+</g, "><").trim();
10080
10113
  }
@@ -10086,15 +10119,16 @@ function getDirectChildByLocalName(parent, localName) {
10086
10119
  }
10087
10120
  function getTrimmedTextContent(element) {
10088
10121
  const text = element?.textContent.trim();
10089
- return text && text.length > 0 ? text : void 0;
10122
+ return text != null && text.length > 0 ? text : void 0;
10090
10123
  }
10091
10124
  function parseDescription(parent) {
10092
10125
  const descriptions = getDirectChildrenByLocalName(parent, "description");
10093
10126
  const textMap = {};
10094
10127
  for (const description of descriptions) {
10095
- const language = description.getAttribute("language")?.trim() || "und";
10128
+ const languageAttribute = description.getAttribute("language")?.trim();
10129
+ const language = languageAttribute != null && languageAttribute.length > 0 ? languageAttribute : "und";
10096
10130
  const text = description.textContent.trim();
10097
- if (text)
10131
+ if (text.length > 0)
10098
10132
  textMap[language] = text;
10099
10133
  }
10100
10134
  return Object.keys(textMap).length > 0 ? textMap : void 0;
@@ -10130,12 +10164,14 @@ function ParseJSON_LD(Text, _Context = "") {
10130
10164
  function firstKey(obj) {
10131
10165
  for (const a in obj)
10132
10166
  return a;
10167
+ return void 0;
10133
10168
  }
10134
10169
  function firstValue(obj) {
10135
10170
  if (obj == void 0)
10136
10171
  return void 0;
10137
10172
  for (const a in obj)
10138
10173
  return obj[a];
10174
+ return void 0;
10139
10175
  }
10140
10176
  var uiLocale = typeof window !== "undefined" ? window.navigator.language : "de";
10141
10177
  function setUILocale(locale) {
@@ -10168,14 +10204,17 @@ function parseOBIS(OBIS) {
10168
10204
  return `${String(media)}-${String(channel)}:${String(indicator)}.${String(mode)}.${String(quantities)}*${String(storage)}`;
10169
10205
  }
10170
10206
  var OBIS_RegExpr = new RegExp("((\\d+)\\-)?((\\d+):)?((\\d+)\\.)(\\d+)(\\.(\\d+))?(\\*(\\d+))?");
10207
+ function optionalOBISMatchValue(value) {
10208
+ return value ?? "0";
10209
+ }
10171
10210
  function OBIS2Hex(OBIS) {
10172
10211
  const OBISElements = OBIS.match(OBIS_RegExpr);
10173
- return OBISElements == null ? "000000000000" : parseInt(OBISElements[2]).toString(16).padStart(2, "0") + // optional A
10174
- parseInt(OBISElements[4]).toString(16).padStart(2, "0") + // optional B
10175
- parseInt(OBISElements[6]).toString(16).padStart(2, "0") + // mandatory C
10176
- parseInt(OBISElements[7]).toString(16).padStart(2, "0") + // mandatory D
10177
- parseInt(OBISElements[9]).toString(16).padStart(2, "0") + // optional E
10178
- parseInt(OBISElements[11]).toString(16).padStart(2, "0");
10212
+ return OBISElements == null ? "000000000000" : parseInt(optionalOBISMatchValue(OBISElements[2])).toString(16).padStart(2, "0") + // optional A
10213
+ parseInt(optionalOBISMatchValue(OBISElements[4])).toString(16).padStart(2, "0") + // optional B
10214
+ parseInt(optionalOBISMatchValue(OBISElements[6])).toString(16).padStart(2, "0") + // mandatory C
10215
+ parseInt(optionalOBISMatchValue(OBISElements[7])).toString(16).padStart(2, "0") + // mandatory D
10216
+ parseInt(optionalOBISMatchValue(OBISElements[9])).toString(16).padStart(2, "0") + // optional E
10217
+ parseInt(optionalOBISMatchValue(OBISElements[11])).toString(16).padStart(2, "0");
10179
10218
  }
10180
10219
  function OBIS2MeasurementName(OBISString) {
10181
10220
  switch (OBISString) {
@@ -10218,15 +10257,15 @@ function measurementName2human(In) {
10218
10257
  }
10219
10258
  }
10220
10259
  function IsNullOrEmpty(value) {
10221
- return !value;
10260
+ return value == null || value.length === 0;
10222
10261
  }
10223
10262
  function WhenNullOrEmpty(value, replacement) {
10224
- if (!value)
10263
+ if (value == null || value.length === 0)
10225
10264
  return replacement;
10226
10265
  return value;
10227
10266
  }
10228
10267
  function hex2bin(hex, Reverse) {
10229
- if (Reverse) {
10268
+ if (Reverse === true) {
10230
10269
  const reversed = [];
10231
10270
  for (let i = 0; i < hex.length; i += 2)
10232
10271
  reversed.push(hex.substring(i, i + 2));
@@ -10340,7 +10379,7 @@ function SetHex(dv, hex, offset, reverse) {
10340
10379
  const bytes = parseHexString(hex);
10341
10380
  const buffer = new ArrayBuffer(bytes.length);
10342
10381
  const tv = new DataView(buffer);
10343
- if (reverse)
10382
+ if (reverse === true)
10344
10383
  bytes.reverse();
10345
10384
  for (let i = 0; i < bytes.length; i++) {
10346
10385
  dv.setUint8(offset + i, bytes[i] ?? 0);
@@ -10389,7 +10428,7 @@ function SetUInt32(dv, value, offset, reverse) {
10389
10428
  const bytes = getInt32Bytes(value);
10390
10429
  const buffer = new ArrayBuffer(bytes.length);
10391
10430
  const tv = new DataView(buffer);
10392
- if (reverse)
10431
+ if (reverse === true)
10393
10432
  bytes.reverse();
10394
10433
  for (let i = 0; i < bytes.length; i++) {
10395
10434
  dv.setUint8(offset + i, bytes[i] ?? 0);
@@ -10401,7 +10440,7 @@ function SetUInt64(dv, value, offset, reverse) {
10401
10440
  const bytes = getInt64Bytes(value);
10402
10441
  const buffer = new ArrayBuffer(bytes.length);
10403
10442
  const tv = new DataView(buffer);
10404
- if (reverse)
10443
+ if (reverse === true)
10405
10444
  bytes.reverse();
10406
10445
  for (let i = 0; i < bytes.length; i++) {
10407
10446
  dv.setUint8(offset + i, bytes[i] ?? 0);
@@ -10433,7 +10472,7 @@ function SetUInt32_withCode(dv, value, scale, obis, offset, reverse) {
10433
10472
  const obisBytes = getInt8Bytes(obis);
10434
10473
  const buffer = new ArrayBuffer(valueBytes.length + 2);
10435
10474
  const tv = new DataView(buffer);
10436
- if (reverse)
10475
+ if (reverse === true)
10437
10476
  valueBytes.reverse();
10438
10477
  for (let i = 0; i < valueBytes.length; i++) {
10439
10478
  dv.setUint8(offset + i, valueBytes[i] ?? 0);
@@ -10496,8 +10535,7 @@ function CreateDiv2(ParentDiv, ChildClassName, ChildAInnerHTML, ChildBInnerHTML)
10496
10535
  return childDiv;
10497
10536
  }
10498
10537
  function pad(text, paddingValue) {
10499
- if (text == void 0)
10500
- text = "";
10538
+ text ??= "";
10501
10539
  return (text + Array(2 * paddingValue).join("0")).substring(0, 2 * paddingValue);
10502
10540
  }
10503
10541
  async function sha256(message) {
@@ -10643,7 +10681,7 @@ function jsonPrettyPrinter(value, KeyLookup) {
10643
10681
  value,
10644
10682
  0,
10645
10683
  "",
10646
- KeyLookup ?? ((path, key) => key)
10684
+ KeyLookup ?? ((_path, key) => key)
10647
10685
  );
10648
10686
  }
10649
10687
  function _jsonPrettyPrinter(value, indentLevel, path, keyLookup) {
@@ -10722,13 +10760,15 @@ var ACrypt = class {
10722
10760
  }
10723
10761
  AddToVisualBuffer(valueHEX, bufferDiv, lineDiv) {
10724
10762
  const newText = CreateDiv(bufferDiv, "entry", valueHEX);
10763
+ const lineId = getArrayLikeElement(lineDiv.children, 0, "Missing visual buffer line id");
10764
+ const lineHex = getArrayLikeElement(lineDiv.children, 1, "Missing visual buffer line hex");
10725
10765
  newText.onmouseenter = function() {
10726
- lineDiv.children[0]?.classList.add("overEntry");
10727
- lineDiv.children[1]?.classList.add("overEntry");
10766
+ lineId.classList.add("overEntry");
10767
+ lineHex.classList.add("overEntry");
10728
10768
  };
10729
10769
  newText.onmouseleave = function() {
10730
- lineDiv.children[0]?.classList.remove("overEntry");
10731
- lineDiv.children[1]?.classList.remove("overEntry");
10770
+ lineId.classList.remove("overEntry");
10771
+ lineHex.classList.remove("overEntry");
10732
10772
  };
10733
10773
  lineDiv.onmouseenter = function() {
10734
10774
  newText.classList.add("overEntry");
@@ -10744,7 +10784,7 @@ var Alfen = class {
10744
10784
  this.chargy = chargy;
10745
10785
  }
10746
10786
  bufferToHex(buffer, Reverse) {
10747
- return (Reverse ? Array.from(new Uint8Array(buffer)).reverse() : Array.from(new Uint8Array(buffer))).map((b) => b.toString(16).padStart(2, "0")).join("");
10787
+ return (Reverse === true ? Array.from(new Uint8Array(buffer)).reverse() : Array.from(new Uint8Array(buffer))).map((b) => b.toString(16).padStart(2, "0")).join("");
10748
10788
  }
10749
10789
  bufferToNumber(buffer) {
10750
10790
  return parseInt(Array.from(new Uint8Array(buffer)).map((b) => b.toString(16).padStart(2, "0")).join(""), 16);
@@ -10779,31 +10819,32 @@ var Alfen = class {
10779
10819
  signedValues = Content;
10780
10820
  let previousTimestamp = "";
10781
10821
  for (let i = 0; i < signedValues.length; i++) {
10782
- const elements = signedValues[i]?.split(";");
10783
- if (elements?.length != 6 && elements?.length != 7)
10822
+ const elements = getArrayElement(signedValues, i, "Missing Alfen signed value").split(";");
10823
+ if (elements.length != 6 && elements.length != 7)
10784
10824
  return {
10785
10825
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10786
- message: this.chargy.GetLocalizedMessage("Invalid number of signed meter values!"),
10826
+ message: this.chargy.GetMultilanguageText("Invalid number of signed meter values!"),
10787
10827
  certainty: 0
10788
10828
  };
10789
- const FormatId = elements[0];
10790
- const Type = elements[1];
10791
- const BlobVersion = elements[2];
10792
- const PublicKey = this.chargy.base32Decode(elements[3] ?? "", "RFC4648");
10793
- const DataSet = this.chargy.base32Decode(elements[4] ?? "", "RFC4648");
10794
- const Signature = this.chargy.base32Decode(elements[5] ?? "", "RFC4648");
10829
+ const FormatId = getArrayElement(elements, 0, "Missing Alfen format id");
10830
+ const Type = getArrayElement(elements, 1, "Missing Alfen type");
10831
+ const BlobVersion = getArrayElement(elements, 2, "Missing Alfen blob version");
10832
+ const publicKeyValue = getArrayElement(elements, 3, "Missing Alfen public key");
10833
+ const PublicKey = this.chargy.base32Decode(publicKeyValue, "RFC4648");
10834
+ const DataSet = this.chargy.base32Decode(getArrayElement(elements, 4, "Missing Alfen data set"), "RFC4648");
10835
+ const Signature = this.chargy.base32Decode(getArrayElement(elements, 5, "Missing Alfen signature"), "RFC4648");
10795
10836
  if (common.PublicKey === "")
10796
- common.PublicKey = elements[3] ?? "";
10797
- else if (elements[3] !== common.PublicKey)
10837
+ common.PublicKey = publicKeyValue;
10838
+ else if (publicKeyValue !== common.PublicKey)
10798
10839
  return {
10799
10840
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10800
- message: this.chargy.GetLocalizedMessage("Inconsistent public keys!"),
10841
+ message: this.chargy.GetMultilanguageText("Inconsistent public keys!"),
10801
10842
  certainty: 0
10802
10843
  };
10803
- if (FormatId !== "AP" || Type?.length !== 1 || BlobVersion?.length !== 1 || BlobVersion !== "3" || PublicKey.byteLength !== 25 || DataSet.byteLength !== 82 || Signature.byteLength !== 48) {
10844
+ if (FormatId !== "AP" || Type.length !== 1 || BlobVersion.length !== 1 || BlobVersion !== "3" || PublicKey.byteLength !== 25 || DataSet.byteLength !== 82 || Signature.byteLength !== 48) {
10804
10845
  return {
10805
10846
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10806
- message: this.chargy.GetLocalizedMessage("Invalid charging session format!"),
10847
+ message: this.chargy.GetMultilanguageText("Invalid charging session format!"),
10807
10848
  certainty: 0
10808
10849
  };
10809
10850
  }
@@ -10828,7 +10869,7 @@ var Alfen = class {
10828
10869
  else if (AdapterId !== common.AdapterId)
10829
10870
  return {
10830
10871
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10831
- message: this.chargy.GetLocalizedMessage("Inconsistent Alfen adapter identification!"),
10872
+ message: this.chargy.GetMultilanguageText("Inconsistent Alfen adapter identification!"),
10832
10873
  certainty: 0
10833
10874
  };
10834
10875
  if (common.AdapterFWVersion === "")
@@ -10836,7 +10877,7 @@ var Alfen = class {
10836
10877
  else if (AdapterFWVersion !== common.AdapterFWVersion)
10837
10878
  return {
10838
10879
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10839
- message: this.chargy.GetLocalizedMessage("Inconsistent Alfen adapter firmware version!"),
10880
+ message: this.chargy.GetMultilanguageText("Inconsistent Alfen adapter firmware version!"),
10840
10881
  certainty: 0
10841
10882
  };
10842
10883
  if (common.AdapterFWChecksum === "")
@@ -10844,7 +10885,7 @@ var Alfen = class {
10844
10885
  else if (AdapterFWChecksum !== common.AdapterFWChecksum)
10845
10886
  return {
10846
10887
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10847
- message: this.chargy.GetLocalizedMessage("Inconsistent Alfen adapter firmware checksum!"),
10888
+ message: this.chargy.GetMultilanguageText("Inconsistent Alfen adapter firmware checksum!"),
10848
10889
  certainty: 0
10849
10890
  };
10850
10891
  if (common.MeterId === "")
@@ -10852,7 +10893,7 @@ var Alfen = class {
10852
10893
  else if (MeterId !== common.MeterId)
10853
10894
  return {
10854
10895
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10855
- message: this.chargy.GetLocalizedMessage("Inconsistent meter identification!"),
10896
+ message: this.chargy.GetMultilanguageText("Inconsistent meter identification!"),
10856
10897
  certainty: 0
10857
10898
  };
10858
10899
  if (common.ObisId === "")
@@ -10860,7 +10901,7 @@ var Alfen = class {
10860
10901
  else if (ObisId !== common.ObisId)
10861
10902
  return {
10862
10903
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10863
- message: this.chargy.GetLocalizedMessage("Inconsistent OBIS code!"),
10904
+ message: this.chargy.GetMultilanguageText("Inconsistent OBIS code!"),
10864
10905
  certainty: 0
10865
10906
  };
10866
10907
  if (common.UnitEncoded === 0)
@@ -10868,7 +10909,7 @@ var Alfen = class {
10868
10909
  else if (UnitEncoded !== common.UnitEncoded)
10869
10910
  return {
10870
10911
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10871
- message: this.chargy.GetLocalizedMessage("Inconsistent unit (encoded) value!"),
10912
+ message: this.chargy.GetMultilanguageText("Inconsistent unit (encoded) value!"),
10872
10913
  certainty: 0
10873
10914
  };
10874
10915
  if (common.Scalar === "")
@@ -10876,7 +10917,7 @@ var Alfen = class {
10876
10917
  else if (Scalar !== common.Scalar)
10877
10918
  return {
10878
10919
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10879
- message: this.chargy.GetLocalizedMessage("Inconsistent measurement scalar!"),
10920
+ message: this.chargy.GetMultilanguageText("Inconsistent measurement scalar!"),
10880
10921
  certainty: 0
10881
10922
  };
10882
10923
  if (common.UID === "")
@@ -10884,7 +10925,7 @@ var Alfen = class {
10884
10925
  else if (UID !== common.UID)
10885
10926
  return {
10886
10927
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10887
- message: this.chargy.GetLocalizedMessage("Inconsistent user identification!"),
10928
+ message: this.chargy.GetMultilanguageText("Inconsistent user identification!"),
10888
10929
  certainty: 0
10889
10930
  };
10890
10931
  if (common.InternalSessionId === 0)
@@ -10892,13 +10933,13 @@ var Alfen = class {
10892
10933
  else if (InternalSessionId !== common.InternalSessionId)
10893
10934
  return {
10894
10935
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10895
- message: this.chargy.GetLocalizedMessage("Inconsistent internal charging session identification!"),
10936
+ message: this.chargy.GetMultilanguageText("Inconsistent internal charging session identification!"),
10896
10937
  certainty: 0
10897
10938
  };
10898
10939
  if (previousTimestamp !== "" && previousTimestamp > Timestamp)
10899
10940
  return {
10900
10941
  status: "InconsistentTimestamps" /* InconsistentTimestamps */,
10901
- message: this.chargy.GetLocalizedMessage("Inconsistent timestamps!"),
10942
+ message: this.chargy.GetMultilanguageText("Inconsistent timestamps!"),
10902
10943
  certainty: 0
10903
10944
  };
10904
10945
  else
@@ -10917,14 +10958,8 @@ var Alfen = class {
10917
10958
  const evseId = asString(containerInfos["EVSEId"]) ?? "DE*GEF*EVSE*CHARGY*1";
10918
10959
  const chargingStationId = asString(containerInfos["ChargingStationId"]) ?? "DE*GEF*STATION*CHARGY*1";
10919
10960
  const chargingSessionId = asString(chargingSession?.["@id"]);
10920
- const firstDataSet = common.dataSets[0];
10921
- const lastDataSet = common.dataSets[common.dataSets.length - 1];
10922
- if (firstDataSet === void 0 || lastDataSet === void 0)
10923
- return {
10924
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
10925
- message: this.chargy.GetLocalizedMessage("Invalid number of signed meter values!"),
10926
- certainty: 0
10927
- };
10961
+ const firstDataSet = getFirstArrayElement(common.dataSets, "Missing first Alfen data set");
10962
+ const lastDataSet = getLastArrayElement(common.dataSets, "Missing last Alfen data set");
10928
10963
  const _CTR = {
10929
10964
  "@id": chargingSessionId ?? common.InternalSessionId.toString(),
10930
10965
  "@context": "https://open.charging.cloud/contexts/CTR+json",
@@ -11054,7 +11089,7 @@ var Alfen = class {
11054
11089
  } catch (exception) {
11055
11090
  return {
11056
11091
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
11057
- message: this.chargy.GetLocalizedMessage("Exception occured: ") + (exception instanceof Error ? exception.message : String(exception)),
11092
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
11058
11093
  certainty: 0
11059
11094
  };
11060
11095
  }
@@ -11205,62 +11240,62 @@ var AlfenCrypt01 = class extends ACrypt {
11205
11240
  }
11206
11241
  return {};
11207
11242
  }
11208
- async ViewMeasurement(measurementValue, errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
11243
+ async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
11209
11244
  const result = measurementValue.result;
11210
11245
  {
11211
11246
  introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "AlfenCrypt01").replace("{cryptoAlgorithm}", this.description);
11212
11247
  }
11213
11248
  {
11214
- if (PlainTextDiv.parentElement && PlainTextDiv.parentElement.children[0]) {
11215
- PlainTextDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Plain text") + " (320 Bytes, hex)";
11249
+ if (PlainTextDiv.parentElement) {
11250
+ getArrayLikeElement(PlainTextDiv.parentElement.children, 0, "Missing plain text header").innerHTML = this.chargy.GetLocalizedMessage("Plain text") + " (320 Bytes, hex)";
11216
11251
  }
11217
11252
  PlainTextDiv.style.fontFamily = "";
11218
11253
  PlainTextDiv.style.whiteSpace = "";
11219
11254
  PlainTextDiv.style.maxHeight = "";
11220
11255
  PlainTextDiv.style.overflowY = "";
11221
- this.CreateLocalizedLine("Adapter Id", measurementValue.measurement.adapterId, result.adapterId || "", infoDiv, PlainTextDiv);
11222
- this.CreateLocalizedLine("Adapter Firmware Version", measurementValue.measurement.adapterFWVersion, result.adapterFWVersion || "", infoDiv, PlainTextDiv);
11223
- this.CreateLocalizedLine("Adapter Firmware Checksum", measurementValue.measurement.adapterFWChecksum, result.adapterFWChecksum || "", infoDiv, PlainTextDiv);
11224
- this.CreateLocalizedLine("Meter number", measurementValue.measurement.energyMeterId, result.meterId || "", infoDiv, PlainTextDiv);
11256
+ this.CreateLocalizedLine("Adapter Id", measurementValue.measurement.adapterId, result.adapterId ?? "", infoDiv, PlainTextDiv);
11257
+ this.CreateLocalizedLine("Adapter Firmware Version", measurementValue.measurement.adapterFWVersion, result.adapterFWVersion ?? "", infoDiv, PlainTextDiv);
11258
+ this.CreateLocalizedLine("Adapter Firmware Checksum", measurementValue.measurement.adapterFWChecksum, result.adapterFWChecksum ?? "", infoDiv, PlainTextDiv);
11259
+ this.CreateLocalizedLine("Meter number", measurementValue.measurement.energyMeterId, result.meterId ?? "", infoDiv, PlainTextDiv);
11225
11260
  this.CreateLocalizedLine(
11226
11261
  "Meter status",
11227
11262
  hex2bin(measurementValue.statusMeter, true) + " (" + measurementValue.statusMeter + ' hex)<br /><span class="statusInfos">' + this.DecodeMeterStatus(measurementValue.statusMeter).join("<br />") + "</span>",
11228
- result.statusMeter || "",
11263
+ result.statusMeter ?? "",
11229
11264
  infoDiv,
11230
11265
  PlainTextDiv
11231
11266
  );
11232
11267
  this.CreateLocalizedLine(
11233
11268
  "Adapter status",
11234
11269
  hex2bin(measurementValue.statusAdapter, true) + " (" + measurementValue.statusAdapter + ' hex)<br /><span class="statusInfos">' + this.DecodeAdapterStatus(measurementValue.statusAdapter).join("<br />") + "</span>",
11235
- result.statusAdapter || "",
11270
+ result.statusAdapter ?? "",
11236
11271
  infoDiv,
11237
11272
  PlainTextDiv
11238
11273
  );
11239
- this.CreateLocalizedLine("Seconds index", measurementValue.secondsIndex, result.secondsIndex || "", infoDiv, PlainTextDiv);
11240
- this.CreateLocalizedLine("Timestamp", UTC2human(measurementValue.timestamp), result.timestamp || "", infoDiv, PlainTextDiv);
11241
- this.CreateLocalizedLine("OBIS code", measurementValue.measurement.obis, result.obisId || "", infoDiv, PlainTextDiv);
11242
- this.CreateLocalizedLine("Unit (encoded)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded || "", infoDiv, PlainTextDiv);
11243
- this.CreateLocalizedLine("Scaling", measurementValue.measurement.scale, result.scalar || "", infoDiv, PlainTextDiv);
11244
- this.CreateLocalizedLine("Measurement Value", measurementValue.value.toString() + " Wh", result.value || "", infoDiv, PlainTextDiv);
11245
- this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "") + " hex", pad(result.uid, 20) || "", infoDiv, PlainTextDiv);
11246
- this.CreateLocalizedLine("SessionId", measurementValue.measurement.chargingSession?.["@id"] ?? "", result.sessionId || "", infoDiv, PlainTextDiv);
11247
- this.CreateLocalizedLine("Pagination counter", measurementValue.paginationId, result.paging || "", infoDiv, PlainTextDiv);
11274
+ this.CreateLocalizedLine("Seconds index", measurementValue.secondsIndex, result.secondsIndex ?? "", infoDiv, PlainTextDiv);
11275
+ this.CreateLocalizedLine("Timestamp", UTC2human(measurementValue.timestamp), result.timestamp ?? "", infoDiv, PlainTextDiv);
11276
+ this.CreateLocalizedLine("OBIS code", measurementValue.measurement.obis, result.obisId ?? "", infoDiv, PlainTextDiv);
11277
+ this.CreateLocalizedLine("Unit (encoded)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded ?? "", infoDiv, PlainTextDiv);
11278
+ this.CreateLocalizedLine("Scaling", measurementValue.measurement.scale, result.scalar ?? "", infoDiv, PlainTextDiv);
11279
+ this.CreateLocalizedLine("Measurement Value", measurementValue.value.toString() + " Wh", result.value ?? "", infoDiv, PlainTextDiv);
11280
+ this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
11281
+ this.CreateLocalizedLine("SessionId", measurementValue.measurement.chargingSession?.["@id"] ?? "", result.sessionId ?? "", infoDiv, PlainTextDiv);
11282
+ this.CreateLocalizedLine("Pagination counter", measurementValue.paginationId, result.paging ?? "", infoDiv, PlainTextDiv);
11248
11283
  }
11249
11284
  {
11250
- if (HashedPlainTextDiv.parentElement && HashedPlainTextDiv.parentElement.children[0]) {
11251
- HashedPlainTextDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Hashed plain text") + " (SHA256, hex)";
11285
+ if (HashedPlainTextDiv.parentElement) {
11286
+ getArrayLikeElement(HashedPlainTextDiv.parentElement.children, 0, "Missing hashed plain text header").innerHTML = this.chargy.GetLocalizedMessage("Hashed plain text") + " (SHA256, hex)";
11252
11287
  }
11253
11288
  const hashValueText = typeof result.hashValue === "string" ? result.hashValue : result.hashValue?.toString(16) ?? "";
11254
11289
  HashedPlainTextDiv.innerHTML = hashValueText.match(/.{1,8}/g)?.join(" ") ?? "";
11255
11290
  }
11256
- if (result.publicKey && result.publicKey != "") {
11257
- if (PublicKeyDiv.parentElement && PublicKeyDiv.parentElement.children[0]) {
11258
- PublicKeyDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Public Key") + " (" + (result.publicKeyFormat ? result.publicKeyFormat + ", " : "") + "base32)";
11291
+ if (result.publicKey != null && result.publicKey.length > 0) {
11292
+ if (PublicKeyDiv.parentElement) {
11293
+ getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = this.chargy.GetLocalizedMessage("Public Key") + " (" + (result.publicKeyFormat != null && result.publicKeyFormat.length > 0 ? result.publicKeyFormat + ", " : "") + "base32)";
11259
11294
  }
11260
11295
  if (!IsNullOrEmpty(result.publicKey))
11261
11296
  PublicKeyDiv.innerHTML = result.publicKey.match(/.{1,4}/g)?.join(" ") ?? "";
11262
11297
  }
11263
- if (PublicKeyDiv.parentElement && PublicKeyDiv.parentElement.children[3]) {
11298
+ if (PublicKeyDiv.parentElement?.children[3]) {
11264
11299
  PublicKeyDiv.parentElement.children[3].innerHTML = "";
11265
11300
  if (result.publicKeySignatures) {
11266
11301
  for (const signature of result.publicKeySignatures) {
@@ -11279,14 +11314,14 @@ var AlfenCrypt01 = class extends ACrypt {
11279
11314
  }
11280
11315
  }
11281
11316
  if (result.signature != null) {
11282
- if (SignatureExpectedDiv.parentElement && SignatureExpectedDiv.parentElement.children[0]) {
11283
- SignatureExpectedDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (" + (result.signature.format ?? "") + ", hex)";
11317
+ if (SignatureExpectedDiv.parentElement) {
11318
+ getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (" + (result.signature.format ?? "") + ", hex)";
11284
11319
  }
11285
- if (result.signature.r && result.signature.s) {
11320
+ if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0) {
11286
11321
  const signatureR = result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
11287
11322
  const signatureS = result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
11288
11323
  SignatureExpectedDiv.innerHTML = "r: " + signatureR + "<br />s: " + signatureS;
11289
- } else if (result.signature.value)
11324
+ } else if (result.signature.value != null && result.signature.value.length > 0)
11290
11325
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
11291
11326
  }
11292
11327
  {
@@ -11379,18 +11414,18 @@ var BSMCrypt01 = class extends ACrypt {
11379
11414
  tryToParseBSM_WS36aMeasurements(CTR, ExpectedEVSEId, ExpectedCscSwVersion, Measurements) {
11380
11415
  if (!Array.isArray(Measurements)) return {
11381
11416
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
11382
- message: this.chargy.GetLocalizedMessage("MissingOrInvalidSignedMeterValues"),
11417
+ message: this.chargy.GetMultilanguageText("MissingOrInvalidSignedMeterValues"),
11383
11418
  certainty: 0
11384
11419
  };
11385
11420
  if (Measurements.length < 2) return {
11386
11421
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
11387
- message: this.chargy.GetLocalizedMessage("AtLeastTwoSignedMeterValuesRequired"),
11422
+ message: this.chargy.GetMultilanguageText("AtLeastTwoSignedMeterValuesRequired"),
11388
11423
  certainty: 0
11389
11424
  };
11390
11425
  const firstMeasurement = Measurements[0];
11391
11426
  if (!isMandatoryJSONObject(firstMeasurement)) return {
11392
11427
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
11393
- message: this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalidSignedMeterValueP", 1),
11428
+ message: this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalidSignedMeterValueP", 1),
11394
11429
  certainty: 0
11395
11430
  };
11396
11431
  const errors = new Array();
@@ -11399,51 +11434,51 @@ var BSMCrypt01 = class extends ACrypt {
11399
11434
  let secondaryErrors = 0;
11400
11435
  try {
11401
11436
  if (!isMandatoryString(firstMeasurement["@context"]))
11402
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_JSONContextP", 1));
11437
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_JSONContextP", 1)));
11403
11438
  const meterInfo = firstMeasurement["meterInfo"];
11404
11439
  if (!isMandatoryJSONObject(meterInfo)) {
11405
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfoP", 1));
11440
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfoP", 1)));
11406
11441
  secondaryErrors += 5;
11407
11442
  } else {
11408
11443
  if (!isMandatoryString(meterInfo["firmwareVersion"]))
11409
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1));
11444
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1)));
11410
11445
  if (!isMandatoryString(meterInfo["publicKey"]))
11411
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
11446
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
11412
11447
  if (!isMandatoryString(meterInfo["meterId"]))
11413
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1));
11448
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1)));
11414
11449
  if (!isMandatoryString(meterInfo["manufacturer"]))
11415
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
11450
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
11416
11451
  if (!isMandatoryString(meterInfo["type"]))
11417
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_TypeP", 1));
11452
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_TypeP", 1)));
11418
11453
  }
11419
11454
  const contract = firstMeasurement["contract"];
11420
11455
  if (!isMandatoryJSONObject(contract)) {
11421
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_ContractP", 1));
11456
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_ContractP", 1)));
11422
11457
  secondaryErrors += 2;
11423
11458
  } else {
11424
11459
  if (!isMandatoryString(contract["id"]))
11425
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_IdP", 1));
11460
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_IdP", 1)));
11426
11461
  if (!isOptionalString(contract["type"]))
11427
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TypeP", 1));
11462
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TypeP", 1)));
11428
11463
  }
11429
11464
  const value = firstMeasurement["value"];
11430
11465
  if (!isMandatoryJSONObject(value)) {
11431
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_ValueP", 1));
11466
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_ValueP", 1)));
11432
11467
  secondaryErrors += 8;
11433
11468
  } else {
11434
11469
  const measurand = value["measurand"];
11435
11470
  if (!isMandatoryJSONObject(measurand)) {
11436
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasurandP", 1));
11471
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasurandP", 1)));
11437
11472
  secondaryErrors += 2;
11438
11473
  } else {
11439
11474
  if (!isMandatoryString(measurand["id"]))
11440
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_Measurand_IdentificationP", 1));
11475
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_Measurand_IdentificationP", 1)));
11441
11476
  if (!isMandatoryString(measurand["name"]))
11442
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_Measurand_NameP", 1));
11477
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_Measurand_NameP", 1)));
11443
11478
  }
11444
11479
  const measuredValue = value["measuredValue"];
11445
11480
  if (!isMandatoryJSONObject(measuredValue)) {
11446
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValueP", 1));
11481
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValueP", 1)));
11447
11482
  secondaryErrors += 4;
11448
11483
  } else {
11449
11484
  }
@@ -11521,18 +11556,22 @@ var BSMCrypt01 = class extends ACrypt {
11521
11556
  if (currentMeasurement === void 0)
11522
11557
  throw new Error(`Invalid signed meter value #${String(measurementCounter)}!`);
11523
11558
  if (currentMeasurement["@context"] !== common.context)
11524
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_JSONContextP", measurementCounter));
11559
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_JSONContextP", measurementCounter)));
11525
11560
  const currentId = currentMeasurement["@id"];
11526
11561
  if (previousId !== "" && typeof currentId === "string") {
11527
11562
  if (typeof previousId !== "string")
11528
11563
  throw new Error(`Invalid identification of signed meter value #${String(measurementCounter - 1)}!`);
11529
11564
  const previousParts = previousId.split("-");
11530
11565
  const currentParts = currentId.split("-");
11531
- if (previousParts.length !== 2 || currentParts.length !== 2 || previousParts[0] !== currentParts[0] || previousParts[1] === void 0 || currentParts[1] === void 0 || // parseInt returns NaN in case parsing fails which in turn does not match
11566
+ const previousPrefix = previousParts.at(0);
11567
+ const previousCounter = previousParts.at(1);
11568
+ const currentPrefix = currentParts.at(0);
11569
+ const currentCounter = currentParts.at(1);
11570
+ if (previousParts.length !== 2 || currentParts.length !== 2 || previousPrefix !== currentPrefix || previousCounter === void 0 || currentCounter === void 0 || // parseInt returns NaN in case parsing fails which in turn does not match
11532
11571
  // anything (not even NaN). This way we are checking that both counter values
11533
11572
  // are numeric too.
11534
- parseInt(previousParts[1], 10) >= parseInt(currentParts[1], 10)) {
11535
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeasurementIdP", measurementCounter));
11573
+ parseInt(previousCounter, 10) >= parseInt(currentCounter, 10)) {
11574
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeasurementIdP", measurementCounter)));
11536
11575
  }
11537
11576
  }
11538
11577
  previousId = currentId;
@@ -11541,11 +11580,11 @@ var BSMCrypt01 = class extends ACrypt {
11541
11580
  const displayedFormatObj2 = asJSONObject(valueObj2?.["displayedFormat"]);
11542
11581
  const currentTime = asString(currentMeasurement["time"]) ?? "";
11543
11582
  if (previousTime !== "" && currentTime <= previousTime)
11544
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_TimestampP", measurementCounter));
11583
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_TimestampP", measurementCounter)));
11545
11584
  previousTime = currentTime;
11546
11585
  const currentValue = asNumber(measuredValueObj2?.["value"]);
11547
11586
  if (previousValue !== void 0 && currentValue !== void 0 && currentValue < previousValue)
11548
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_Measurement_ValueP", measurementCounter));
11587
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_Measurement_ValueP", measurementCounter)));
11549
11588
  previousValue = currentValue;
11550
11589
  const additionalValuesRaw = currentMeasurement["additionalValues"];
11551
11590
  if (!isMandatoryJSONArray(additionalValuesRaw))
@@ -11569,78 +11608,78 @@ var BSMCrypt01 = class extends ACrypt {
11569
11608
  precision: asNumber(displayedFormat?.["precision"])
11570
11609
  };
11571
11610
  });
11572
- if (currentMeasurement["meterInfo"]) {
11611
+ if (currentMeasurement["meterInfo"] != null) {
11573
11612
  const meterInfoObj2 = asJSONObject(currentMeasurement["meterInfo"]);
11574
11613
  if (meterInfoObj2?.["firmwareVersion"] !== common.meterInfo_firmwareVersion)
11575
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeterInfo_FirmwareVersionP", measurementCounter));
11614
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeterInfo_FirmwareVersionP", measurementCounter)));
11576
11615
  if (meterInfoObj2?.["publicKey"] !== common.meterInfo_publicKey)
11577
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeterInfo_PublicKeyP", measurementCounter));
11616
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeterInfo_PublicKeyP", measurementCounter)));
11578
11617
  if (meterInfoObj2?.["meterId"] !== common.meterInfo_meterId)
11579
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeterInfo_MeterIdP", measurementCounter));
11580
- if (meterInfoObj2?.["meterId"] !== additionalValues.filter((element) => element.measurandName === "MA1")[0]?.value)
11581
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeterInfo_MeterIdP", measurementCounter));
11618
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeterInfo_MeterIdP", measurementCounter)));
11619
+ if (meterInfoObj2?.["meterId"] !== additionalValues.find((element) => element.measurandName === "MA1")?.value)
11620
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeterInfo_MeterIdP", measurementCounter)));
11582
11621
  if (meterInfoObj2?.["manufacturer"] !== common.meterInfo_manufacturer)
11583
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeterInfo_ManufacturerP", measurementCounter));
11622
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeterInfo_ManufacturerP", measurementCounter)));
11584
11623
  if (meterInfoObj2?.["type"] !== common.meterInfo_type)
11585
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeterInfo_TypeP", measurementCounter));
11624
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeterInfo_TypeP", measurementCounter)));
11586
11625
  }
11587
- if (currentMeasurement["contract"]) {
11626
+ if (currentMeasurement["contract"] != null) {
11588
11627
  const contractObj2 = asJSONObject(currentMeasurement["contract"]);
11589
- if (additionalValues.filter((element) => element.measurandName?.startsWith("Meta") && asString(element.value)?.startsWith("contract-id:")).length == 0)
11590
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_Contract_IdP", measurementCounter));
11628
+ if (additionalValues.filter((element) => element.measurandName?.startsWith("Meta") === true && asString(element.value)?.startsWith("contract-id:") === true).length == 0)
11629
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_Contract_IdP", measurementCounter)));
11591
11630
  if (contractObj2?.["id"] !== common.contract_id)
11592
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_Contract_IdP", measurementCounter));
11631
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_Contract_IdP", measurementCounter)));
11593
11632
  if (contractObj2?.["type"] !== common.contract_type)
11594
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_Contract_TypeP", measurementCounter));
11595
- const contractInfo = additionalValues.filter((element) => element.measurandName?.startsWith("Meta") && asString(element.value)?.startsWith("contract-id:"))[0]?.value;
11633
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_Contract_TypeP", measurementCounter)));
11634
+ const contractInfo = additionalValues.find((element) => element.measurandName?.startsWith("Meta") === true && asString(element.value)?.startsWith("contract-id:") === true)?.value;
11596
11635
  if (contractInfo != null) {
11597
- if (contractObj2?.["type"] && contractInfo !== "contract-id: " + (common.contract_type ?? "-") + ":" + common.contract_id)
11598
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_Contract_IdP", measurementCounter));
11599
- if (!contractObj2?.["type"] && contractInfo !== "contract-id: " + common.contract_id)
11600
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_Contract_IdP", measurementCounter));
11636
+ if (contractObj2?.["type"] != null && contractInfo !== "contract-id: " + (common.contract_type ?? "-") + ":" + common.contract_id)
11637
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_Contract_IdP", measurementCounter)));
11638
+ if (contractObj2?.["type"] == null && contractInfo !== "contract-id: " + common.contract_id)
11639
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_Contract_IdP", measurementCounter)));
11601
11640
  }
11602
11641
  }
11603
11642
  const rcrInAdditional = additionalValues.find((element) => element.measurandName == "RCR");
11604
11643
  if (currentMeasurement["value"] == null)
11605
11644
  throw new Error(`Missing value within signed meter value #${String(measurementCounter)}!`);
11606
- if ((valueObj2?.["measurand"] || valueObj2?.["measuredValue"]) && rcrInAdditional === void 0)
11645
+ if ((valueObj2?.["measurand"] != null || valueObj2?.["measuredValue"] != null) && rcrInAdditional === void 0)
11607
11646
  throw new Error(`Missing 'RCR' within the additional values of signed meter value #${String(measurementCounter)}!`);
11608
- if (valueObj2?.["measurand"]) {
11647
+ if (valueObj2?.["measurand"] != null) {
11609
11648
  const measurandObj2 = asJSONObject(valueObj2["measurand"]);
11610
11649
  if (measurandObj2?.["id"] !== common.value_measurand_id || measurandObj2["id"] !== rcrInAdditional?.measurandId)
11611
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_Measurand_IdentificationP", measurementCounter));
11650
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_Measurand_IdentificationP", measurementCounter)));
11612
11651
  if (measurandObj2?.["name"] !== common.value_measurand_name || measurandObj2["name"] !== rcrInAdditional?.measurandName)
11613
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_Measurand_NameP", measurementCounter));
11652
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_Measurand_NameP", measurementCounter)));
11614
11653
  }
11615
- if (valueObj2?.["measuredValue"]) {
11654
+ if (valueObj2?.["measuredValue"] != null) {
11616
11655
  if (measuredValueObj2?.["value"] !== rcrInAdditional?.value)
11617
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValueP", measurementCounter));
11656
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValueP", measurementCounter)));
11618
11657
  if (measuredValueObj2?.["scale"] !== common.value_measuredValue_scale || measuredValueObj2?.["scale"] !== rcrInAdditional?.scale)
11619
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_ScaleP", measurementCounter));
11658
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_ScaleP", measurementCounter)));
11620
11659
  if (measuredValueObj2?.["unit"] !== common.value_measuredValue_unit || measuredValueObj2["unit"] !== rcrInAdditional?.unit)
11621
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_UnitP", measurementCounter));
11660
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_UnitP", measurementCounter)));
11622
11661
  if (measuredValueObj2?.["unitEncoded"] !== common.value_measuredValue_unitEncoded || measuredValueObj2?.["unitEncoded"] !== rcrInAdditional?.unitEncoded)
11623
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_UnitEncodedP", measurementCounter));
11662
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_UnitEncodedP", measurementCounter)));
11624
11663
  if (measuredValueObj2?.["valueType"] !== common.value_measuredValue_valueType || measuredValueObj2?.["valueType"] !== rcrInAdditional?.valueType)
11625
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_TypeP", measurementCounter));
11664
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_TypeP", measurementCounter)));
11626
11665
  }
11627
- if (currentMeasurement["chargePoint"] && asJSONObject(currentMeasurement["chargePoint"])?.["softwareVersion"] !== common.chargePoint_softwareVersion)
11628
- currentErrors.push(this.chargy.GetLocalizedMessage("Inconsistent_ChargingStation_FirmwareVersion"));
11629
- const signedEVSEId = additionalValues.filter((element) => element.measurandName?.startsWith("Meta") && asString(element.value)?.startsWith("evse-id:"));
11666
+ if (currentMeasurement["chargePoint"] != null && asJSONObject(currentMeasurement["chargePoint"])?.["softwareVersion"] !== common.chargePoint_softwareVersion)
11667
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageText("Inconsistent_ChargingStation_FirmwareVersion")));
11668
+ const signedEVSEId = additionalValues.filter((element) => element.measurandName?.startsWith("Meta") === true && asString(element.value)?.startsWith("evse-id:") === true);
11630
11669
  if (signedEVSEId.length == 1) {
11631
11670
  const evse__id = (asString(signedEVSEId[0]?.value) ?? "").replace("evse-id:", "").trim();
11632
11671
  if (evse__id !== "unknown" && ExpectedEVSEId !== evse__id)
11633
- currentErrors.push(this.chargy.GetLocalizedMessage("Inconsistent_EVSE_Identification"));
11672
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageText("Inconsistent_EVSE_Identification")));
11634
11673
  }
11635
- const signedCSCSWVersion = additionalValues.filter((element) => element.measurandName?.startsWith("Meta") && asString(element.value)?.startsWith("csc-sw-version:"));
11674
+ const signedCSCSWVersion = additionalValues.filter((element) => element.measurandName?.startsWith("Meta") === true && asString(element.value)?.startsWith("csc-sw-version:") === true);
11636
11675
  if (signedCSCSWVersion.length == 1) {
11637
11676
  const csc_sw_version = asString(signedCSCSWVersion[0]?.value)?.replace("csc-sw-version:", "").trim() ?? null;
11638
11677
  if (previousCscSwVersion !== null && previousCscSwVersion !== csc_sw_version)
11639
- currentErrors.push(this.chargy.GetLocalizedMessage("Inconsistent_ChargingStation_FirmwareVersion"));
11678
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageText("Inconsistent_ChargingStation_FirmwareVersion")));
11640
11679
  if (ExpectedCscSwVersion !== null && ExpectedCscSwVersion !== csc_sw_version)
11641
11680
  currentWarnings.push({
11642
11681
  level: "medium" /* medium */,
11643
- message: this.chargy.GetLocalizedMessage("Inconsistent_ChargingStation_FirmwareVersion")
11682
+ message: this.chargy.GetMultilanguageText("Inconsistent_ChargingStation_FirmwareVersion")
11644
11683
  });
11645
11684
  previousCscSwVersion = csc_sw_version;
11646
11685
  }
@@ -11697,36 +11736,38 @@ var BSMCrypt01 = class extends ACrypt {
11697
11736
  case "Evt":
11698
11737
  Evt = asNumber(additionalValue.value) ?? NaN;
11699
11738
  break;
11739
+ default:
11740
+ break;
11700
11741
  }
11701
11742
  }
11702
11743
  const currentRCRValue = asNumber(RCR?.value) ?? NaN;
11703
11744
  if (previousRCR !== -1 && currentRCRValue < previousRCR)
11704
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_Measurement_ValueP", measurementCounter));
11745
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_Measurement_ValueP", measurementCounter)));
11705
11746
  previousRCR = currentRCRValue;
11706
11747
  if (RCnt !== currentMeasurement["measurementId"])
11707
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeasurementIdP", measurementCounter));
11748
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeasurementIdP", measurementCounter)));
11708
11749
  if (previousRCnt !== -1 && RCnt != previousRCnt + 1)
11709
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_CounterP", measurementCounter));
11750
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_CounterP", measurementCounter)));
11710
11751
  previousRCnt = RCnt;
11711
11752
  if (previousOS !== -1 && OS <= previousOS)
11712
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_OperationSecondsCounterP", measurementCounter));
11753
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_OperationSecondsCounterP", measurementCounter)));
11713
11754
  previousOS = OS;
11714
11755
  if (previousEpoch !== -1 && Epoch <= previousEpoch)
11715
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_UNIXEpochP", measurementCounter));
11756
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_UNIXEpochP", measurementCounter)));
11716
11757
  previousEpoch = Epoch;
11717
11758
  const measurementTimestamp1 = new Date(Epoch * 1e3 + TZO * 6e4).toISOString();
11718
11759
  const measurementTimestamp2 = measurementTimestamp1.substring(0, measurementTimestamp1.indexOf("."));
11719
11760
  const measurementTimestamp3 = measurementTimestamp2 + (TZO > 0 ? "+" : "-") + (Math.abs(TZO) / 60).toString().padStart(2, "0") + ":" + (Math.abs(TZO) % 60).toString().padStart(2, "0");
11720
11761
  if (currentTime !== measurementTimestamp3)
11721
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_TimestampP", measurementCounter));
11762
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_TimestampP", measurementCounter)));
11722
11763
  if (common.MA1 !== null && MA1 !== common.MA1)
11723
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_MeterInfo_MeterIdP", measurementCounter));
11764
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_MeterInfo_MeterIdP", measurementCounter)));
11724
11765
  common.MA1 = MA1;
11725
11766
  if (common.epochSetCnt !== -1 && EpochSetCnt !== common.epochSetCnt)
11726
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_EpochSet_CounterP", measurementCounter));
11767
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_EpochSet_CounterP", measurementCounter)));
11727
11768
  common.epochSetCnt = EpochSetCnt;
11728
11769
  if (common.epochSetOS !== -1 && EpochSetOS !== common.epochSetOS)
11729
- currentErrors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_SignedMeterValue_EpochSet_OperationSecondsP", measurementCounter));
11770
+ currentErrors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_SignedMeterValue_EpochSet_OperationSecondsP", measurementCounter)));
11730
11771
  common.epochSetOS = EpochSetOS;
11731
11772
  common.dataSets.push({
11732
11773
  Typ,
@@ -11759,18 +11800,17 @@ var BSMCrypt01 = class extends ACrypt {
11759
11800
  });
11760
11801
  }
11761
11802
  const n = common.dataSets.length - 1;
11762
- const firstDataSet = common.dataSets[0];
11763
- const lastDataSet = common.dataSets[n];
11764
- if (firstDataSet === void 0 || firstDataSet.TypParsed !== "START" && firstDataSet.TypParsed !== "TURN ON")
11803
+ const firstDataSet = getFirstArrayElement(common.dataSets, "Missing first BSM data set");
11804
+ const lastDataSet = getArrayElement(common.dataSets, n, "Missing last BSM data set");
11805
+ if (firstDataSet.TypParsed !== "START" && firstDataSet.TypParsed !== "TURN ON")
11765
11806
  throw new Error(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_EnergyMeterValueP", 1));
11766
11807
  for (let i = 1; i < common.dataSets.length - 1; i++) {
11767
11808
  if (common.dataSets[i]?.TypParsed !== "CURRENT")
11768
- errors.push(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_EnergyMeterValueP", measurementCounter + 1));
11809
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Inconsistent_EnergyMeterValueP", measurementCounter + 1)));
11769
11810
  }
11770
- if (lastDataSet === void 0 || lastDataSet.TypParsed !== "END" && lastDataSet.TypParsed !== "TURN OFF")
11811
+ if (lastDataSet.TypParsed !== "END" && lastDataSet.TypParsed !== "TURN OFF")
11771
11812
  throw new Error(this.chargy.GetLocalizedMessageWithParameter("Inconsistent_EnergyMeterValueP", n + 1));
11772
- if (CTR.chargingSessions == null)
11773
- CTR.chargingSessions = [];
11813
+ CTR.chargingSessions ??= [];
11774
11814
  const ASN1_SignatureSchema = this.chargy.asn1.define("Signature", function() {
11775
11815
  this.seq().obj(
11776
11816
  this.key("r").int(),
@@ -11835,7 +11875,11 @@ var BSMCrypt01 = class extends ACrypt {
11835
11875
  try {
11836
11876
  ASN1Signature = ASN1_SignatureSchema.decode(Buffer.from(dataSet.signature, "hex"), "der");
11837
11877
  } catch (exception) {
11838
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_SignatureP", 1) + ": " + (exception instanceof Error ? exception.message : String(exception)));
11878
+ const signatureError = this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_SignatureP", 1);
11879
+ const exceptionText = ": " + (exception instanceof Error ? exception.message : String(exception));
11880
+ for (const language of Object.keys(signatureError))
11881
+ signatureError[language] = (signatureError[language] ?? "") + exceptionText;
11882
+ errors.push(CreateError(signatureError));
11839
11883
  }
11840
11884
  const bsmMeasurementValue = {
11841
11885
  timestamp: dataSet.time,
@@ -11883,12 +11927,12 @@ var BSMCrypt01 = class extends ACrypt {
11883
11927
  CTR.chargingSessions.push(session);
11884
11928
  CTR["@id"] = common.meterInfo_meterId + "-" + String(firstDataSet.Epoch);
11885
11929
  {
11886
- const firstChargingSession = CTR.chargingSessions[0];
11887
- const lastChargingSession = CTR.chargingSessions[CTR.chargingSessions.length - 1];
11888
- if (firstChargingSession !== void 0 && (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin)) {
11930
+ const firstChargingSession = getFirstArrayElement(CTR.chargingSessions, "Missing first BSM charging session");
11931
+ const lastChargingSession = getLastArrayElement(CTR.chargingSessions, "Missing last BSM charging session");
11932
+ if (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin) {
11889
11933
  CTR.begin = firstChargingSession.begin;
11890
11934
  }
11891
- if (lastChargingSession?.end !== void 0) {
11935
+ if (lastChargingSession.end !== void 0) {
11892
11936
  if (CTR.end == void 0 || CTR.end === "" || CTR.end < lastChargingSession.end)
11893
11937
  CTR.end = lastChargingSession.end;
11894
11938
  }
@@ -11928,7 +11972,9 @@ var BSMCrypt01 = class extends ACrypt {
11928
11972
  CTR.certainty = 1 - errors.length / numberOfFormatChecks;
11929
11973
  return CTR;
11930
11974
  } catch (exception) {
11931
- errors.push("Exception occured: " + (exception instanceof Error ? exception.message : String(exception)));
11975
+ errors.push(
11976
+ CreateError({ "en": "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)) })
11977
+ );
11932
11978
  }
11933
11979
  return {
11934
11980
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
@@ -12058,58 +12104,63 @@ var BSMCrypt01 = class extends ACrypt {
12058
12104
  }
12059
12105
  return {};
12060
12106
  }
12061
- async ViewMeasurement(measurementValue, errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
12107
+ async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
12062
12108
  if (measurementValue.measurement === void 0)
12063
12109
  return new Error("Invalid measurement!");
12064
12110
  const result = measurementValue.result;
12065
12111
  introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "BSMCrypt01").replace("{cryptoAlgorithm}", this.description);
12066
- if (PlainTextDiv.parentElement != void 0 && PlainTextDiv.parentElement.children[0] != void 0) {
12067
- PlainTextDiv.parentElement.children[0].innerHTML = "Plain text (" + measurementValue.result.ArraySize.toString() + " Bytes, hex)";
12112
+ if (PlainTextDiv.parentElement) {
12113
+ getArrayLikeElement(PlainTextDiv.parentElement.children, 0, "Missing plain text header").innerHTML = "Plain text (" + measurementValue.result.ArraySize.toString() + " Bytes, hex)";
12068
12114
  }
12069
12115
  PlainTextDiv.style.fontFamily = "";
12070
12116
  PlainTextDiv.style.whiteSpace = "";
12071
12117
  PlainTextDiv.style.maxHeight = "";
12072
12118
  PlainTextDiv.style.overflowY = "";
12073
- this.CreateLine("Snapshot-Typ", this.ParseTyp(measurementValue.Typ), result.Typ || "", infoDiv, PlainTextDiv);
12074
- this.CreateLine("RCR", (measurementValue.RCR * 10 ** measurementValue.RCR_SF).toString() + " " + measurementValue.RCR_Unit, result.RCR || "", infoDiv, PlainTextDiv);
12075
- this.CreateLine("TotWhImp", (measurementValue.TotWhImp * 10 ** measurementValue.TotWhImp_SF).toString() + " " + measurementValue.TotWhImp_Unit, result.TotWhImp || "", infoDiv, PlainTextDiv);
12076
- this.CreateLine("W", (measurementValue.W * 10 ** measurementValue.W_SF).toString() + " " + measurementValue.W_Unit, result.W || "", infoDiv, PlainTextDiv);
12077
- this.CreateLine("MA1", measurementValue.MA1, result.MA1 || "", infoDiv, PlainTextDiv);
12078
- this.CreateLine("RCnt", measurementValue.RCnt, result.RCnt || "", infoDiv, PlainTextDiv);
12079
- this.CreateLine("OS", measurementValue.OS, result.OS || "", infoDiv, PlainTextDiv);
12080
- this.CreateLine("Zeitstempel", UTC2human(measurementValue.Epoch), result.Epoch || "", infoDiv, PlainTextDiv);
12081
- this.CreateLine("TZO", measurementValue.TZO.toString() + " Minuten", result.TZO || "", infoDiv, PlainTextDiv);
12082
- this.CreateLine("EpochSetCnt", measurementValue.EpochSetCnt, result.EpochSetCnt || "", infoDiv, PlainTextDiv);
12083
- this.CreateLine("EpochSetOS", measurementValue.EpochSetOS, result.EpochSetOS || "", infoDiv, PlainTextDiv);
12084
- this.CreateLine("DI", measurementValue.DI, result.DI || "", infoDiv, PlainTextDiv);
12085
- this.CreateLine("DO", measurementValue.DO, result.DO || "", infoDiv, PlainTextDiv);
12086
- this.CreateLine("Meta1", measurementValue.Meta1, result.Meta1 || "", infoDiv, PlainTextDiv);
12087
- this.CreateLine("Meta2", measurementValue.Meta2, result.Meta2 || "", infoDiv, PlainTextDiv);
12088
- this.CreateLine("Meta3", measurementValue.Meta3, result.Meta3 || "", infoDiv, PlainTextDiv);
12089
- this.CreateLine("Evt", this.ParseEvents(measurementValue.Evt).join("<br>"), result.Evt || "", infoDiv, PlainTextDiv);
12090
- if (HashedPlainTextDiv.parentElement != void 0 && HashedPlainTextDiv.parentElement.children[0] != void 0) {
12091
- HashedPlainTextDiv.parentElement.children[0].innerHTML = "Hashed plain text (SHA256, hex)";
12119
+ this.CreateLine("Snapshot-Typ", this.ParseTyp(measurementValue.Typ), result.Typ, infoDiv, PlainTextDiv);
12120
+ this.CreateLine("RCR", (measurementValue.RCR * 10 ** measurementValue.RCR_SF).toString() + " " + measurementValue.RCR_Unit, result.RCR, infoDiv, PlainTextDiv);
12121
+ this.CreateLine("TotWhImp", (measurementValue.TotWhImp * 10 ** measurementValue.TotWhImp_SF).toString() + " " + measurementValue.TotWhImp_Unit, result.TotWhImp, infoDiv, PlainTextDiv);
12122
+ this.CreateLine("W", (measurementValue.W * 10 ** measurementValue.W_SF).toString() + " " + measurementValue.W_Unit, result.W, infoDiv, PlainTextDiv);
12123
+ this.CreateLine("MA1", measurementValue.MA1, result.MA1, infoDiv, PlainTextDiv);
12124
+ this.CreateLine("RCnt", measurementValue.RCnt, result.RCnt, infoDiv, PlainTextDiv);
12125
+ this.CreateLine("OS", measurementValue.OS, result.OS, infoDiv, PlainTextDiv);
12126
+ this.CreateLine("Zeitstempel", UTC2human(measurementValue.Epoch), result.Epoch, infoDiv, PlainTextDiv);
12127
+ this.CreateLine("TZO", measurementValue.TZO.toString() + " Minuten", result.TZO, infoDiv, PlainTextDiv);
12128
+ this.CreateLine("EpochSetCnt", measurementValue.EpochSetCnt, result.EpochSetCnt, infoDiv, PlainTextDiv);
12129
+ this.CreateLine("EpochSetOS", measurementValue.EpochSetOS, result.EpochSetOS, infoDiv, PlainTextDiv);
12130
+ this.CreateLine("DI", measurementValue.DI, result.DI, infoDiv, PlainTextDiv);
12131
+ this.CreateLine("DO", measurementValue.DO, result.DO, infoDiv, PlainTextDiv);
12132
+ this.CreateLine("Meta1", measurementValue.Meta1, result.Meta1, infoDiv, PlainTextDiv);
12133
+ this.CreateLine("Meta2", measurementValue.Meta2, result.Meta2, infoDiv, PlainTextDiv);
12134
+ this.CreateLine("Meta3", measurementValue.Meta3, result.Meta3, infoDiv, PlainTextDiv);
12135
+ this.CreateLine("Evt", this.ParseEvents(measurementValue.Evt).join("<br>"), result.Evt, infoDiv, PlainTextDiv);
12136
+ if (HashedPlainTextDiv.parentElement) {
12137
+ getArrayLikeElement(HashedPlainTextDiv.parentElement.children, 0, "Missing hashed plain text header").innerHTML = "Hashed plain text (SHA256, hex)";
12092
12138
  }
12093
12139
  HashedPlainTextDiv.innerHTML = result.sha256value?.match(/.{1,8}/g)?.join(" ") ?? "";
12094
12140
  if (result.publicKey != null && result.publicKey != "") {
12095
- if (PublicKeyDiv.parentElement != void 0 && PublicKeyDiv.parentElement.children[0] != void 0) {
12096
- PublicKeyDiv.parentElement.children[0].innerHTML = "Public Key (" + (result.publicKeyFormat ? result.publicKeyFormat + ", " : "") + "hex)";
12141
+ if (PublicKeyDiv.parentElement) {
12142
+ getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = "Public Key (" + (result.publicKeyFormat != null && result.publicKeyFormat.length > 0 ? result.publicKeyFormat + ", " : "") + "hex)";
12097
12143
  }
12098
12144
  if (!IsNullOrEmpty(result.publicKey))
12099
12145
  PublicKeyDiv.innerHTML = result.publicKey.startsWith("04") ? '<span class="leadingFour">04</span> ' + (result.publicKey.substring(2).match(/.{1,8}/g)?.join(" ") ?? "-") : result.publicKey.match(/.{1,8}/g)?.join(" ") ?? "-";
12100
- if (PublicKeyDiv.parentElement != void 0 && PublicKeyDiv.parentElement.children[3] != void 0) {
12101
- PublicKeyDiv.parentElement.children[3].innerHTML = "";
12146
+ const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
12147
+ if (publicKeySignatureContainer !== void 0) {
12148
+ publicKeySignatureContainer.innerHTML = "";
12102
12149
  }
12103
12150
  if (result.publicKeySignatures) {
12104
12151
  for (const signature of result.publicKeySignatures) {
12105
12152
  try {
12106
- const signatureDiv = PublicKeyDiv.parentElement?.children[3]?.appendChild(document.createElement("div"));
12107
- if (signatureDiv != null && measurementValue.measurement.chargingSession != null && measurementValue.measurement.chargingSession.EVSE != null && measurementValue.measurement.chargingSession.EVSE.meters.length > 0 && measurementValue.measurement.chargingSession.EVSE.meters[0] != null && measurementValue.measurement.chargingSession.EVSE.meters[0].publicKeys != null && measurementValue.measurement.chargingSession.EVSE.meters[0].publicKeys.length > 0) {
12153
+ const signatureDiv = publicKeySignatureContainer?.appendChild(document.createElement("div"));
12154
+ const chargingSession = measurementValue.measurement.chargingSession;
12155
+ const evse = chargingSession?.EVSE;
12156
+ const meter = evse?.meters.at(0);
12157
+ const publicKey = meter?.publicKeys?.at(0);
12158
+ if (signatureDiv != null && chargingSession != null && evse != null && meter != null && publicKey != null) {
12108
12159
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
12109
- measurementValue.measurement.chargingSession.chargingStation,
12110
- measurementValue.measurement.chargingSession.EVSE,
12111
- measurementValue.measurement.chargingSession.EVSE.meters[0],
12112
- measurementValue.measurement.chargingSession.EVSE.meters[0].publicKeys[0],
12160
+ chargingSession.chargingStation,
12161
+ evse,
12162
+ meter,
12163
+ publicKey,
12113
12164
  signature
12114
12165
  );
12115
12166
  }
@@ -12120,12 +12171,12 @@ var BSMCrypt01 = class extends ACrypt {
12120
12171
  }
12121
12172
  }
12122
12173
  if (result.signature != null) {
12123
- if (SignatureExpectedDiv.parentElement != void 0 && SignatureExpectedDiv.parentElement.children[0] != void 0) {
12124
- SignatureExpectedDiv.parentElement.children[0].innerHTML = "Erwartete Signatur (" + (result.signature.format || "") + ", hex)";
12174
+ if (SignatureExpectedDiv.parentElement) {
12175
+ getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
12125
12176
  }
12126
- if (result.signature.r && result.signature.s)
12177
+ if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
12127
12178
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-");
12128
- else if (result.signature.value)
12179
+ else if (result.signature.value != null && result.signature.value.length > 0)
12129
12180
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
12130
12181
  }
12131
12182
  switch (result.status) {
@@ -12151,6 +12202,7 @@ var BSMCrypt01 = class extends ACrypt {
12151
12202
  SignatureCheckDiv.innerHTML = '<i class="fas fa-times-circle"></i><div id="description">Ung\xFCltige Signatur</div>';
12152
12203
  break;
12153
12204
  }
12205
+ return void 0;
12154
12206
  }
12155
12207
  //#region Helper methods
12156
12208
  PrefixConverter(input) {
@@ -12229,30 +12281,35 @@ var BSMCrypt01 = class extends ACrypt {
12229
12281
  if ((value & 1 << 29) != 0) events.push("OEM 15");
12230
12282
  return events;
12231
12283
  }
12232
- DecodeStatus(statusValue) {
12233
- const statusArray = [];
12234
- try {
12235
- const status = parseInt(statusValue);
12236
- if ((status & 1) == 1)
12237
- statusArray.push("Fehler erkannt");
12238
- if ((status & 2) == 2)
12239
- statusArray.push("Synchrone Messwert\xFCbermittlung");
12240
- if ((status & 8) == 8)
12241
- statusArray.push("System-Uhr ist synchron");
12242
- else
12243
- statusArray.push("System-Uhr ist nicht synchron");
12244
- if ((status & 16) == 16)
12245
- statusArray.push("R\xFCcklaufsperre aktiv");
12246
- if ((status & 32) == 32)
12247
- statusArray.push("Energierichtung -A");
12248
- if ((status & 64) == 64)
12249
- statusArray.push("Magnetfeld erkannt");
12250
- } catch {
12251
- statusArray.push("Invalid status!");
12252
- }
12253
- return statusArray;
12254
- }
12255
- //#endregion
12284
+ // private DecodeStatus(statusValue: string) : Array<string>
12285
+ // {
12286
+ // const statusArray:string[] = [];
12287
+ // try
12288
+ // {
12289
+ // const status = parseInt(statusValue);
12290
+ // if ((status & 1) == 1)
12291
+ // statusArray.push("Fehler erkannt");
12292
+ // if ((status & 2) == 2)
12293
+ // statusArray.push("Synchrone Messwertübermittlung");
12294
+ // // Bit 3 is reserved!
12295
+ // if ((status & 8) == 8)
12296
+ // statusArray.push("System-Uhr ist synchron");
12297
+ // else
12298
+ // statusArray.push("System-Uhr ist nicht synchron");
12299
+ // if ((status & 16) == 16)
12300
+ // statusArray.push("Rücklaufsperre aktiv");
12301
+ // if ((status & 32) == 32)
12302
+ // statusArray.push("Energierichtung -A");
12303
+ // if ((status & 64) == 64)
12304
+ // statusArray.push("Magnetfeld erkannt");
12305
+ // }
12306
+ // catch
12307
+ // {
12308
+ // statusArray.push("Invalid status!");
12309
+ // }
12310
+ // return statusArray;
12311
+ // }
12312
+ // //#endregion
12256
12313
  };
12257
12314
 
12258
12315
  // src/CanonicalJSON.ts
@@ -12652,7 +12709,7 @@ var EMHCrypt01 = class extends ACrypt {
12652
12709
  measurementValue.result = cryptoResult;
12653
12710
  return cryptoResult;
12654
12711
  }
12655
- if (measurementValue.measurement === void 0 || measurementValue.measurement.chargingSession === void 0) {
12712
+ if (measurementValue.measurement?.chargingSession === void 0) {
12656
12713
  return {
12657
12714
  status: "InvalidMeasurement" /* InvalidMeasurement */
12658
12715
  };
@@ -12691,9 +12748,10 @@ var EMHCrypt01 = class extends ACrypt {
12691
12748
  cryptoResult.meter = meter;
12692
12749
  if (meter.publicKeys != null && meter.publicKeys.length > 0) {
12693
12750
  try {
12694
- cryptoResult.publicKey = meter.publicKeys[0]?.value?.toLowerCase();
12695
- cryptoResult.publicKeyFormat = meter.publicKeys[0]?.format;
12696
- cryptoResult.publicKeySignatures = meter.publicKeys[0]?.signatures;
12751
+ const publicKey = meter.publicKeys.at(0);
12752
+ cryptoResult.publicKey = publicKey?.value?.toLowerCase();
12753
+ cryptoResult.publicKeyFormat = publicKey?.format;
12754
+ cryptoResult.publicKeySignatures = publicKey?.signatures;
12697
12755
  try {
12698
12756
  if (this.curve.keyFromPublic(cryptoResult.publicKey ?? "", "hex").verify(
12699
12757
  cryptoResult.sha256value,
@@ -12718,59 +12776,60 @@ var EMHCrypt01 = class extends ACrypt {
12718
12776
  }
12719
12777
  return {};
12720
12778
  }
12721
- async ViewMeasurement(measurementValue, errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
12722
- if (measurementValue.measurement === void 0 || measurementValue.measurement.chargingSession === void 0 || measurementValue.measurement.chargingSession.authorizationStart.timestamp === void 0) {
12779
+ async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
12780
+ if (measurementValue.measurement?.chargingSession?.authorizationStart.timestamp === void 0) {
12723
12781
  return new Error("Invalid measurement!");
12724
12782
  }
12725
12783
  const result = measurementValue.result;
12726
12784
  introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "EMHCrypt01").replace("{cryptoAlgorithm}", this.description);
12727
12785
  {
12728
- if (PlainTextDiv.parentElement != void 0 && PlainTextDiv.parentElement.children[0] != void 0) {
12729
- PlainTextDiv.parentElement.children[0].innerHTML = "Plain text (320 Bytes, hex)";
12786
+ if (PlainTextDiv.parentElement) {
12787
+ getArrayLikeElement(PlainTextDiv.parentElement.children, 0, "Missing plain text header").innerHTML = "Plain text (320 Bytes, hex)";
12730
12788
  }
12731
12789
  PlainTextDiv.style.fontFamily = "";
12732
12790
  PlainTextDiv.style.whiteSpace = "";
12733
12791
  PlainTextDiv.style.maxHeight = "";
12734
12792
  PlainTextDiv.style.overflowY = "";
12735
- this.CreateLine("Z\xE4hlernummer", measurementValue.measurement.energyMeterId, result.meterId || "", infoDiv, PlainTextDiv);
12736
- this.CreateLine("Zeitstempel", UTC2human(measurementValue.timestamp), result.timestamp || "", infoDiv, PlainTextDiv);
12737
- this.CreateLine("Status", hex2bin(measurementValue.infoStatus) + " (" + measurementValue.infoStatus + ' hex)<br /><span class="statusInfos">' + this.DecodeStatus(measurementValue.infoStatus).join("<br />") + "</span>", result.infoStatus || "", infoDiv, PlainTextDiv);
12738
- this.CreateLine("Sekundenindex", measurementValue.secondsIndex, result.secondsIndex || "", infoDiv, PlainTextDiv);
12739
- this.CreateLine("Paginierungsz\xE4hler", parseInt(measurementValue.paginationId, 16), result.paginationId || "", infoDiv, PlainTextDiv);
12740
- this.CreateLine("OBIS-Kennzahl", measurementValue.measurement.obis, result.obis || "", infoDiv, PlainTextDiv);
12741
- this.CreateLine("Einheit (codiert)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded || "", infoDiv, PlainTextDiv);
12742
- this.CreateLine("Skalierung", measurementValue.measurement.scale, result.scale || "", infoDiv, PlainTextDiv);
12743
- this.CreateLine("Messwert", measurementValue.value.toString() + " Wh", result.value || "", infoDiv, PlainTextDiv);
12744
- this.CreateLine("Logbuchindex", measurementValue.logBookIndex + " hex", result.logBookIndex || "", infoDiv, PlainTextDiv);
12745
- this.CreateLine("Autorisierung", measurementValue.measurement.chargingSession.authorizationStart["@id"] + " hex", pad(result.authorizationStart, 128) || "", infoDiv, PlainTextDiv);
12746
- this.CreateLine("Autorisierungszeitpunkt", UTC2human(measurementValue.measurement.chargingSession.authorizationStart.timestamp), pad(result.authorizationStartTimestamp, 151) || "", infoDiv, PlainTextDiv);
12793
+ this.CreateLine("Z\xE4hlernummer", measurementValue.measurement.energyMeterId, result.meterId ?? "", infoDiv, PlainTextDiv);
12794
+ this.CreateLine("Zeitstempel", UTC2human(measurementValue.timestamp), result.timestamp ?? "", infoDiv, PlainTextDiv);
12795
+ this.CreateLine("Status", hex2bin(measurementValue.infoStatus) + " (" + measurementValue.infoStatus + ' hex)<br /><span class="statusInfos">' + this.DecodeStatus(measurementValue.infoStatus).join("<br />") + "</span>", result.infoStatus ?? "", infoDiv, PlainTextDiv);
12796
+ this.CreateLine("Sekundenindex", measurementValue.secondsIndex, result.secondsIndex ?? "", infoDiv, PlainTextDiv);
12797
+ this.CreateLine("Paginierungsz\xE4hler", parseInt(measurementValue.paginationId, 16), result.paginationId ?? "", infoDiv, PlainTextDiv);
12798
+ this.CreateLine("OBIS-Kennzahl", measurementValue.measurement.obis, result.obis ?? "", infoDiv, PlainTextDiv);
12799
+ this.CreateLine("Einheit (codiert)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded ?? "", infoDiv, PlainTextDiv);
12800
+ this.CreateLine("Skalierung", measurementValue.measurement.scale, result.scale ?? "", infoDiv, PlainTextDiv);
12801
+ this.CreateLine("Messwert", measurementValue.value.toString() + " Wh", result.value ?? "", infoDiv, PlainTextDiv);
12802
+ this.CreateLine("Logbuchindex", measurementValue.logBookIndex + " hex", result.logBookIndex ?? "", infoDiv, PlainTextDiv);
12803
+ this.CreateLine("Autorisierung", measurementValue.measurement.chargingSession.authorizationStart["@id"] + " hex", pad(result.authorizationStart, 128), infoDiv, PlainTextDiv);
12804
+ this.CreateLine("Autorisierungszeitpunkt", UTC2human(measurementValue.measurement.chargingSession.authorizationStart.timestamp), pad(result.authorizationStartTimestamp, 151), infoDiv, PlainTextDiv);
12747
12805
  }
12748
12806
  {
12749
- if (HashedPlainTextDiv.parentElement != void 0 && HashedPlainTextDiv.parentElement.children[0] != void 0) {
12750
- HashedPlainTextDiv.parentElement.children[0].innerHTML = "Hashed plain text (SHA256, 24 bytes, hex)";
12807
+ if (HashedPlainTextDiv.parentElement) {
12808
+ getArrayLikeElement(HashedPlainTextDiv.parentElement.children, 0, "Missing hashed plain text header").innerHTML = "Hashed plain text (SHA256, 24 bytes, hex)";
12751
12809
  }
12752
12810
  HashedPlainTextDiv.innerHTML = result.sha256value?.match(/.{1,8}/g)?.join(" ") ?? "";
12753
12811
  }
12754
12812
  if (result.publicKey != null && result.publicKey != "") {
12755
- if (PublicKeyDiv.parentElement != void 0 && PublicKeyDiv.parentElement.children[0] != void 0) {
12756
- PublicKeyDiv.parentElement.children[0].innerHTML = "Public Key (" + (result.publicKeyFormat ? result.publicKeyFormat + ", " : "") + "hex)";
12813
+ if (PublicKeyDiv.parentElement) {
12814
+ getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = "Public Key (" + (result.publicKeyFormat != null && result.publicKeyFormat.length > 0 ? result.publicKeyFormat + ", " : "") + "hex)";
12757
12815
  }
12758
12816
  if (!IsNullOrEmpty(result.publicKey))
12759
12817
  PublicKeyDiv.innerHTML = result.publicKey.startsWith("04") ? '<span class="leadingFour">04</span> ' + (result.publicKey.substring(2).match(/.{1,8}/g)?.join(" ") ?? "") : result.publicKey.match(/.{1,8}/g)?.join(" ") ?? "";
12760
- if (PublicKeyDiv.parentElement != void 0 && PublicKeyDiv.parentElement.children[3] != void 0) {
12761
- PublicKeyDiv.parentElement.children[3].innerHTML = "";
12818
+ const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
12819
+ if (publicKeySignatureContainer !== void 0) {
12820
+ publicKeySignatureContainer.innerHTML = "";
12762
12821
  }
12763
12822
  if (result.publicKeySignatures) {
12764
12823
  for (const signature of result.publicKeySignatures) {
12765
12824
  try {
12766
- const signatureDiv = PublicKeyDiv.parentElement?.children[3]?.appendChild(document.createElement("div"));
12825
+ const signatureDiv = publicKeySignatureContainer?.appendChild(document.createElement("div"));
12767
12826
  if (signatureDiv) {
12768
12827
  signatureDiv.classList.add("signature");
12769
12828
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
12770
12829
  measurementValue.measurement.chargingSession.chargingStation,
12771
12830
  measurementValue.measurement.chargingSession.EVSE,
12772
- measurementValue.measurement.chargingSession.EVSE?.meters[0],
12773
- measurementValue.measurement.chargingSession.EVSE?.meters[0]?.publicKeys?.[0],
12831
+ measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
12832
+ measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
12774
12833
  signature
12775
12834
  );
12776
12835
  signatureDiv.onclick = () => {
@@ -12784,12 +12843,12 @@ var EMHCrypt01 = class extends ACrypt {
12784
12843
  }
12785
12844
  }
12786
12845
  if (result.signature != null) {
12787
- if (SignatureExpectedDiv.parentElement != void 0 && SignatureExpectedDiv.parentElement.children[0] != void 0) {
12788
- SignatureExpectedDiv.parentElement.children[0].innerHTML = "Erwartete Signatur (" + (result.signature.format || "") + ", hex)";
12846
+ if (SignatureExpectedDiv.parentElement) {
12847
+ getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
12789
12848
  }
12790
- if (result.signature.r && result.signature.s)
12849
+ if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
12791
12850
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
12792
- else if (result.signature.value)
12851
+ else if (result.signature.value != null && result.signature.value.length > 0)
12793
12852
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
12794
12853
  }
12795
12854
  {
@@ -12817,6 +12876,7 @@ var EMHCrypt01 = class extends ACrypt {
12817
12876
  break;
12818
12877
  }
12819
12878
  }
12879
+ return void 0;
12820
12880
  }
12821
12881
  //#region Helper methods
12822
12882
  DecodeStatus(statusValue) {
@@ -12885,7 +12945,7 @@ var GDFCrypt01 = class extends ACrypt {
12885
12945
  measurementValue.result = cryptoResult;
12886
12946
  return cryptoResult;
12887
12947
  }
12888
- if (measurementValue.measurement === void 0 || measurementValue.measurement.chargingSession === void 0) {
12948
+ if (measurementValue.measurement?.chargingSession === void 0) {
12889
12949
  return {
12890
12950
  status: "InvalidMeasurement" /* InvalidMeasurement */
12891
12951
  };
@@ -12920,9 +12980,10 @@ var GDFCrypt01 = class extends ACrypt {
12920
12980
  cryptoResult.meter = meter;
12921
12981
  if (meter.publicKeys != null && meter.publicKeys.length > 0) {
12922
12982
  try {
12923
- cryptoResult.publicKey = meter.publicKeys[0]?.value?.toLowerCase();
12924
- cryptoResult.publicKeyFormat = meter.publicKeys[0]?.format;
12925
- cryptoResult.publicKeySignatures = meter.publicKeys[0]?.signatures;
12983
+ const publicKey = meter.publicKeys.at(0);
12984
+ cryptoResult.publicKey = publicKey?.value?.toLowerCase();
12985
+ cryptoResult.publicKeyFormat = publicKey?.format;
12986
+ cryptoResult.publicKeySignatures = publicKey?.signatures;
12926
12987
  try {
12927
12988
  if (this.curve.keyFromPublic(cryptoResult.publicKey ?? "", "hex").verify(
12928
12989
  cryptoResult.sha256value,
@@ -12947,54 +13008,55 @@ var GDFCrypt01 = class extends ACrypt {
12947
13008
  }
12948
13009
  return {};
12949
13010
  }
12950
- async ViewMeasurement(measurementValue, errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
12951
- if (measurementValue.measurement === void 0 || measurementValue.measurement.chargingSession === void 0 || measurementValue.measurement.chargingSession.authorizationStart.timestamp === void 0) {
13011
+ async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
13012
+ if (measurementValue.measurement?.chargingSession?.authorizationStart.timestamp === void 0) {
12952
13013
  return new Error("Invalid measurement!");
12953
13014
  }
12954
13015
  const result = measurementValue.result;
12955
13016
  introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "GDFCrypt01").replace("{cryptoAlgorithm}", this.description);
12956
13017
  {
12957
- if (PlainTextDiv.parentElement != void 0 && PlainTextDiv.parentElement.children[0] != void 0) {
12958
- PlainTextDiv.parentElement.children[0].innerHTML = "Plain text (320 Bytes, hex)";
13018
+ if (PlainTextDiv.parentElement) {
13019
+ getArrayLikeElement(PlainTextDiv.parentElement.children, 0, "Missing plain text header").innerHTML = "Plain text (320 Bytes, hex)";
12959
13020
  }
12960
13021
  PlainTextDiv.style.fontFamily = "";
12961
13022
  PlainTextDiv.style.whiteSpace = "";
12962
13023
  PlainTextDiv.style.maxHeight = "";
12963
13024
  PlainTextDiv.style.overflowY = "";
12964
- this.CreateLine("Z\xE4hlernummer", measurementValue.measurement.energyMeterId, result.meterId || "", infoDiv, PlainTextDiv);
12965
- this.CreateLine("Zeitstempel", UTC2human(measurementValue.timestamp), result.timestamp || "", infoDiv, PlainTextDiv);
12966
- this.CreateLine("OBIS-Kennzahl", measurementValue.measurement.obis, result.obis || "", infoDiv, PlainTextDiv);
12967
- this.CreateLine("Einheit (codiert)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded || "", infoDiv, PlainTextDiv);
12968
- this.CreateLine("Skalierung", measurementValue.measurement.scale, result.scale || "", infoDiv, PlainTextDiv);
12969
- this.CreateLine("Messwert", measurementValue.value.toString() + " Wh", result.value || "", infoDiv, PlainTextDiv);
12970
- this.CreateLine("Autorisierung", measurementValue.measurement.chargingSession.authorizationStart["@id"] + " hex", pad(result.authorizationStart, 128) || "", infoDiv, PlainTextDiv);
12971
- this.CreateLine("Autorisierungszeitpunkt", UTC2human(measurementValue.measurement.chargingSession.authorizationStart.timestamp), pad(result.authorizationStartTimestamp, 151) || "", infoDiv, PlainTextDiv);
13025
+ this.CreateLine("Z\xE4hlernummer", measurementValue.measurement.energyMeterId, result.meterId ?? "", infoDiv, PlainTextDiv);
13026
+ this.CreateLine("Zeitstempel", UTC2human(measurementValue.timestamp), result.timestamp ?? "", infoDiv, PlainTextDiv);
13027
+ this.CreateLine("OBIS-Kennzahl", measurementValue.measurement.obis, result.obis ?? "", infoDiv, PlainTextDiv);
13028
+ this.CreateLine("Einheit (codiert)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded ?? "", infoDiv, PlainTextDiv);
13029
+ this.CreateLine("Skalierung", measurementValue.measurement.scale, result.scale ?? "", infoDiv, PlainTextDiv);
13030
+ this.CreateLine("Messwert", measurementValue.value.toString() + " Wh", result.value ?? "", infoDiv, PlainTextDiv);
13031
+ this.CreateLine("Autorisierung", measurementValue.measurement.chargingSession.authorizationStart["@id"] + " hex", pad(result.authorizationStart, 128), infoDiv, PlainTextDiv);
13032
+ this.CreateLine("Autorisierungszeitpunkt", UTC2human(measurementValue.measurement.chargingSession.authorizationStart.timestamp), pad(result.authorizationStartTimestamp, 151), infoDiv, PlainTextDiv);
12972
13033
  }
12973
13034
  {
12974
- if (HashedPlainTextDiv.parentElement != void 0 && HashedPlainTextDiv.parentElement.children[0] != void 0) {
12975
- HashedPlainTextDiv.parentElement.children[0].innerHTML = "Hashed plain text (SHA256, 24 bytes, hex)";
13035
+ if (HashedPlainTextDiv.parentElement) {
13036
+ getArrayLikeElement(HashedPlainTextDiv.parentElement.children, 0, "Missing hashed plain text header").innerHTML = "Hashed plain text (SHA256, 24 bytes, hex)";
12976
13037
  }
12977
13038
  HashedPlainTextDiv.innerHTML = result.sha256value?.match(/.{1,8}/g)?.join(" ") ?? "";
12978
13039
  }
12979
13040
  if (result.publicKey != null && result.publicKey != "") {
12980
- if (PublicKeyDiv.parentElement != void 0 && PublicKeyDiv.parentElement.children[0] != void 0) {
12981
- PublicKeyDiv.parentElement.children[0].innerHTML = "Public Key (" + (result.publicKeyFormat ? result.publicKeyFormat + ", " : "") + "hex)";
13041
+ if (PublicKeyDiv.parentElement) {
13042
+ getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = "Public Key (" + (result.publicKeyFormat != null && result.publicKeyFormat.length > 0 ? result.publicKeyFormat + ", " : "") + "hex)";
12982
13043
  }
12983
13044
  if (!IsNullOrEmpty(result.publicKey))
12984
13045
  PublicKeyDiv.innerHTML = result.publicKey.startsWith("04") ? '<span class="leadingFour">04</span> ' + (result.publicKey.substring(2).match(/.{1,8}/g)?.join(" ") ?? "") : result.publicKey.match(/.{1,8}/g)?.join(" ") ?? "";
12985
- if (PublicKeyDiv.parentElement != void 0 && PublicKeyDiv.parentElement.children[3] != void 0) {
12986
- PublicKeyDiv.parentElement.children[3].innerHTML = "";
13046
+ const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
13047
+ if (publicKeySignatureContainer !== void 0) {
13048
+ publicKeySignatureContainer.innerHTML = "";
12987
13049
  }
12988
13050
  if (result.publicKeySignatures) {
12989
13051
  for (const signature of result.publicKeySignatures) {
12990
13052
  try {
12991
- const signatureDiv = PublicKeyDiv.parentElement?.children[3]?.appendChild(document.createElement("div"));
13053
+ const signatureDiv = publicKeySignatureContainer?.appendChild(document.createElement("div"));
12992
13054
  if (signatureDiv != null)
12993
13055
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
12994
13056
  measurementValue.measurement.chargingSession.chargingStation,
12995
13057
  measurementValue.measurement.chargingSession.EVSE,
12996
- measurementValue.measurement.chargingSession.EVSE?.meters[0],
12997
- measurementValue.measurement.chargingSession.EVSE?.meters[0]?.publicKeys?.[0],
13058
+ measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
13059
+ measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
12998
13060
  signature
12999
13061
  );
13000
13062
  } catch (exception) {
@@ -13004,12 +13066,12 @@ var GDFCrypt01 = class extends ACrypt {
13004
13066
  }
13005
13067
  }
13006
13068
  if (result.signature != null) {
13007
- if (SignatureExpectedDiv.parentElement != void 0 && SignatureExpectedDiv.parentElement.children[0] != void 0) {
13008
- SignatureExpectedDiv.parentElement.children[0].innerHTML = "Erwartete Signatur (" + (result.signature.format || "") + ", hex)";
13069
+ if (SignatureExpectedDiv.parentElement) {
13070
+ getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
13009
13071
  }
13010
- if (result.signature.r && result.signature.s)
13072
+ if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
13011
13073
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
13012
- else if (result.signature.value)
13074
+ else if (result.signature.value != null && result.signature.value.length > 0)
13013
13075
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
13014
13076
  }
13015
13077
  {
@@ -13037,6 +13099,7 @@ var GDFCrypt01 = class extends ACrypt {
13037
13099
  break;
13038
13100
  }
13039
13101
  }
13102
+ return void 0;
13040
13103
  }
13041
13104
  };
13042
13105
  var MENNEKES_EDL40_XMLNS = "http://www.mennekes.de/Mennekes.EdlVerification.xsd";
@@ -13053,14 +13116,14 @@ var Mennekes = class {
13053
13116
  if (chargingProcesses.length === 0)
13054
13117
  return {
13055
13118
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13056
- message: this.chargy.GetLocalizedMessage("UnknownOrInvalidChargingSessionFormat"),
13119
+ message: this.chargy.GetMultilanguageText("UnknownOrInvalidChargingSessionFormat"),
13057
13120
  certainty: 0
13058
13121
  };
13059
13122
  return await Promise.resolve(this.toChargeTransparencyRecord(chargingProcesses));
13060
13123
  } catch (exception) {
13061
13124
  return {
13062
13125
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13063
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
13126
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
13064
13127
  certainty: 0
13065
13128
  };
13066
13129
  }
@@ -13197,7 +13260,10 @@ var MennekesCrypt01 = class extends ACrypt {
13197
13260
  sessionResult = "InvalidSignature" /* InvalidSignature */;
13198
13261
  }
13199
13262
  if (sessionResult === "ValidSignature" /* ValidSignature */) {
13200
- const lawErrors = validateMennekesLawConformity(measurement.values);
13263
+ const lawErrors = validateMennekesLawConformity(
13264
+ measurement.values,
13265
+ this.chargy
13266
+ );
13201
13267
  if (lawErrors.length > 0) {
13202
13268
  measurement.verificationResult = {
13203
13269
  status: "InvalidMeasurement" /* InvalidMeasurement */,
@@ -13280,7 +13346,7 @@ var MennekesCrypt01 = class extends ACrypt {
13280
13346
  signedData.byteOffset + signedData.byteLength
13281
13347
  );
13282
13348
  cryptoResult.hashValue = (await sha256(new DataView(signedDataBuffer))).substring(0, 48);
13283
- const publicKey = cleanHex(meter.publicKeys[0]?.value ?? measurement.publicKey);
13349
+ const publicKey = cleanHex(meter.publicKeys.at(0)?.value ?? measurement.publicKey);
13284
13350
  if (publicKey.length !== 96)
13285
13351
  return setResult("InvalidPublicKey" /* InvalidPublicKey */);
13286
13352
  const result = this.curve192r1.keyFromPublic("04" + publicKey, "hex").verify(
@@ -13311,7 +13377,7 @@ var MennekesCrypt01 = class extends ACrypt {
13311
13377
  PublicKeyDiv.innerHTML = result.publicKey?.match(/.{1,8}/g)?.join(" ") ?? "";
13312
13378
  if (SignatureExpectedDiv.parentElement?.children[0])
13313
13379
  SignatureExpectedDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
13314
- SignatureExpectedDiv.innerHTML = result.signature?.r && result.signature.s ? "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") : "";
13380
+ SignatureExpectedDiv.innerHTML = result.signature?.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0 ? "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") : "";
13315
13381
  SignatureCheckDiv.innerHTML = result.status === "ValidSignature" /* ValidSignature */ ? '<i class="fas fa-check-circle"></i><div id="description">' + this.chargy.GetLocalizedMessage("Valid signature") + "</div>" : '<i class="fas fa-times-circle"></i><div id="description">' + this.chargy.GetLocalizedMessage("Invalid signature") + "</div>";
13316
13382
  return Promise.resolve(void 0);
13317
13383
  }
@@ -13330,10 +13396,7 @@ function parseMennekesXMLDocument(XMLDocument) {
13330
13396
  throw new Error("No Mennekes ChargingProcess element found!");
13331
13397
  if (isLocalName(XMLDocument.documentElement, "ChargingProcess")) {
13332
13398
  if (chargingProcesses.length > 1) {
13333
- const chargingProcess = chargingProcesses[0];
13334
- if (chargingProcess != void 0)
13335
- return chargingProcess;
13336
- throw new Error("No Mennekes ChargingProcess found!");
13399
+ return getFirstArrayElement(chargingProcesses, "No Mennekes ChargingProcess found!");
13337
13400
  }
13338
13401
  }
13339
13402
  return {
@@ -13454,18 +13517,20 @@ function toMennekesMeasurementValue(measurement) {
13454
13517
  "measurement": void 0
13455
13518
  };
13456
13519
  }
13457
- function validateMennekesLawConformity(measurementValues) {
13520
+ function validateMennekesLawConformity(measurementValues, chargy) {
13458
13521
  const errors = new Array();
13459
- const start = measurementValues[0];
13460
- const end = measurementValues[measurementValues.length - 1];
13522
+ const start = measurementValues.at(0);
13523
+ const end = measurementValues.at(-1);
13461
13524
  if (start == null || end == null)
13462
- return ["Mennekes EDL40 requires at least two measurement values."];
13525
+ return [
13526
+ CreateError(chargy.GetMultilanguageText("Mennekes EDL40 requires at least two measurement values."))
13527
+ ];
13463
13528
  if (start.eventCounter !== end.eventCounter)
13464
- errors.push("Event counter mismatch.");
13529
+ errors.push(CreateError(chargy.GetMultilanguageText("Event counter mismatch.")));
13465
13530
  if (Number(start.paginationId) >= Number(end.paginationId))
13466
- errors.push("Pagination must increase from start to end.");
13531
+ errors.push(CreateError(chargy.GetMultilanguageText("Pagination must increase from start to end.")));
13467
13532
  if (start.value.gt(end.value))
13468
- errors.push("Meter value must not decrease.");
13533
+ errors.push(CreateError(chargy.GetMultilanguageText("Meter value must not decrease.")));
13469
13534
  return errors;
13470
13535
  }
13471
13536
  function child(parent, localName) {
@@ -13585,9 +13650,9 @@ var OCMFv1_x = class extends ACrypt {
13585
13650
  }
13586
13651
  async VerifyMeasurement(measurementValue) {
13587
13652
  measurementValue.method = this;
13588
- return {
13653
+ return Promise.resolve({
13589
13654
  status: measurementValue.result?.status ?? "Unvalidated" /* Unvalidated */
13590
- };
13655
+ });
13591
13656
  }
13592
13657
  PayloadDictionary(Path, Key) {
13593
13658
  if (Path === "RD") {
@@ -13657,7 +13722,7 @@ var OCMFv1_x = class extends ACrypt {
13657
13722
  return Key;
13658
13723
  }
13659
13724
  }
13660
- SignatureDictionary(Path, Key) {
13725
+ SignatureDictionary(_Path, Key) {
13661
13726
  switch (Key) {
13662
13727
  case "SA":
13663
13728
  return "Signature Algorithm";
@@ -13671,16 +13736,16 @@ var OCMFv1_x = class extends ACrypt {
13671
13736
  return Key;
13672
13737
  }
13673
13738
  }
13674
- async ViewMeasurement(measurementValue, errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
13739
+ async ViewMeasurement(measurementValue, _errorDiv, introDiv, _infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
13675
13740
  if (!measurementValue.measurement || !measurementValue.ocmfDocument || !measurementValue.measurement.chargingSession) {
13676
13741
  return new Error("Invalid measurement!");
13677
13742
  }
13678
13743
  {
13679
- introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "OCMFCrypt01").replace("{cryptoAlgorithm}", measurementValue.ocmfDocument.publicKey && typeof measurementValue.ocmfDocument.publicKey !== "string" ? "(" + measurementValue.ocmfDocument.publicKey.algorithm + ") " : "");
13744
+ introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "OCMFCrypt01").replace("{cryptoAlgorithm}", measurementValue.ocmfDocument.publicKey != null && typeof measurementValue.ocmfDocument.publicKey !== "string" ? "(" + measurementValue.ocmfDocument.publicKey.algorithm + ") " : "");
13680
13745
  }
13681
13746
  {
13682
- if (PlainTextDiv.parentElement && PlainTextDiv.parentElement.children[0]) {
13683
- PlainTextDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Plain text") + " (OCMF|&lt;" + this.chargy.GetLocalizedMessage("payload") + "&gt;|&lt;" + this.chargy.GetLocalizedMessage("signature") + "&gt;)";
13747
+ if (PlainTextDiv.parentElement) {
13748
+ getArrayLikeElement(PlainTextDiv.parentElement.children, 0, "Missing plain text header").innerHTML = this.chargy.GetLocalizedMessage("Plain text") + " (OCMF|&lt;" + this.chargy.GetLocalizedMessage("payload") + "&gt;|&lt;" + this.chargy.GetLocalizedMessage("signature") + "&gt;)";
13684
13749
  }
13685
13750
  PlainTextDiv.innerText = "";
13686
13751
  const compactValueDiv = document.createElement("div");
@@ -13712,29 +13777,30 @@ var OCMFv1_x = class extends ACrypt {
13712
13777
  };
13713
13778
  }
13714
13779
  {
13715
- if (HashedPlainTextDiv.parentElement && HashedPlainTextDiv.parentElement.children[0]) {
13716
- HashedPlainTextDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Hashed payload") + " (" + measurementValue.ocmfDocument.hashAlgorithm + ")";
13780
+ if (HashedPlainTextDiv.parentElement) {
13781
+ getArrayLikeElement(HashedPlainTextDiv.parentElement.children, 0, "Missing hashed payload header").innerHTML = this.chargy.GetLocalizedMessage("Hashed payload") + " (" + measurementValue.ocmfDocument.hashAlgorithm + ")";
13717
13782
  }
13718
13783
  HashedPlainTextDiv.innerHTML = measurementValue.ocmfDocument.hashValue.match(/.{1,8}/g)?.join(" ") ?? "0x00000000000000000000000000000000000";
13719
13784
  }
13720
- if (measurementValue.ocmfDocument.publicKey) {
13721
- if (PublicKeyDiv.parentElement && PublicKeyDiv.parentElement.children[0]) {
13722
- PublicKeyDiv.parentElement.children[0].innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? this.chargy.GetLocalizedMessage("Public Key") : this.chargy.GetLocalizedMessage("Public Key") + " (" + measurementValue.ocmfDocument.publicKey.algorithm + ", " + measurementValue.ocmfDocument.publicKey.encoding + ")";
13785
+ if (measurementValue.ocmfDocument.publicKey != null) {
13786
+ if (PublicKeyDiv.parentElement) {
13787
+ getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? this.chargy.GetLocalizedMessage("Public Key") : this.chargy.GetLocalizedMessage("Public Key") + " (" + measurementValue.ocmfDocument.publicKey.algorithm + ", " + measurementValue.ocmfDocument.publicKey.encoding + ")";
13723
13788
  }
13724
13789
  PublicKeyDiv.innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? measurementValue.ocmfDocument.publicKey : "der: " + (measurementValue.ocmfDocument.publicKey.value?.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />x:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.publicKey.x.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />y:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.publicKey.y.match(/.{1,8}/g)?.join(" ") ?? "-");
13725
13790
  }
13726
- if (PublicKeyDiv.parentElement && PublicKeyDiv.parentElement.children[3]) {
13727
- PublicKeyDiv.parentElement.children[3].innerHTML = "";
13791
+ const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
13792
+ if (publicKeySignatureContainer !== void 0) {
13793
+ publicKeySignatureContainer.innerHTML = "";
13728
13794
  const result = measurementValue.result;
13729
13795
  if (result.publicKeySignatures) {
13730
13796
  for (const signature of result.publicKeySignatures) {
13731
13797
  try {
13732
- const signatureDiv = PublicKeyDiv.parentElement.children[3].appendChild(document.createElement("div"));
13798
+ const signatureDiv = publicKeySignatureContainer.appendChild(document.createElement("div"));
13733
13799
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
13734
13800
  measurementValue.measurement.chargingSession.chargingStation,
13735
13801
  measurementValue.measurement.chargingSession.EVSE,
13736
- measurementValue.measurement.chargingSession.EVSE?.meters[0],
13737
- measurementValue.measurement.chargingSession.EVSE?.meters[0]?.publicKeys?.[0],
13802
+ measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
13803
+ measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
13738
13804
  signature
13739
13805
  );
13740
13806
  } catch {
@@ -13744,8 +13810,8 @@ var OCMFv1_x = class extends ACrypt {
13744
13810
  }
13745
13811
  }
13746
13812
  if (measurementValue.ocmfDocument.signature.SD) {
13747
- if (SignatureExpectedDiv.parentElement && SignatureExpectedDiv.parentElement.children[0]) {
13748
- SignatureExpectedDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
13813
+ if (SignatureExpectedDiv.parentElement) {
13814
+ getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
13749
13815
  }
13750
13816
  SignatureExpectedDiv.innerHTML = "der: " + (measurementValue.ocmfDocument.signature.SD.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />r:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.signatureRS?.r?.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.signatureRS?.s?.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "-");
13751
13817
  }
@@ -13768,6 +13834,7 @@ var OCMFv1_x = class extends ACrypt {
13768
13834
  break;
13769
13835
  }
13770
13836
  }
13837
+ return void 0;
13771
13838
  }
13772
13839
  };
13773
13840
  var OCMFTransactionTypes = /* @__PURE__ */ ((OCMFTransactionTypes2) => {
@@ -13800,274 +13867,276 @@ var OCMF = class {
13800
13867
  const evseId = asString(containerInfos["EVSEId"]) ?? asString(evseInfo?.["@id"]) ?? "DE*GEF*EVSE*CHARGY*1";
13801
13868
  const stationDescription = asJSONObject(chargingStationInfo?.["description"]);
13802
13869
  const evseDescription = asJSONObject(evseInfo?.["description"]);
13803
- const firstOCMDJSONDocument = OCMFJSONDocuments[0];
13804
- if (firstOCMDJSONDocument != void 0) {
13805
- const formatVersion = firstOCMDJSONDocument.payload.FV;
13806
- const gatewayInformation = firstOCMDJSONDocument.payload.GI ?? firstOCMDJSONDocument.payload.VI;
13807
- const gatewaySerial = firstOCMDJSONDocument.payload.GS;
13808
- const gatewayVersion = firstOCMDJSONDocument.payload.GV ?? firstOCMDJSONDocument.payload.VV;
13809
- const paging = firstOCMDJSONDocument.payload.PG;
13810
- const meterVendor = firstOCMDJSONDocument.payload.MV;
13811
- const meterModel = firstOCMDJSONDocument.payload.MM;
13812
- const meterSerial = firstOCMDJSONDocument.payload.MS;
13813
- const effectiveMeterSerial = meterSerial ?? gatewaySerial;
13814
- const meterFirmware = firstOCMDJSONDocument.payload.MF;
13815
- const identificationStatus = firstOCMDJSONDocument.payload.IS;
13816
- const identificationLevel = firstOCMDJSONDocument.payload.IL;
13817
- const identificationFlags = firstOCMDJSONDocument.payload.IF;
13818
- const identificationType = firstOCMDJSONDocument.payload.IT;
13819
- const identificationData = firstOCMDJSONDocument.payload.ID;
13820
- const tariffText = firstOCMDJSONDocument.payload.TT;
13821
- const controlerFirmwareVersion = firstOCMDJSONDocument.payload.CF;
13822
- const lossCompensation = firstOCMDJSONDocument.payload.LC;
13823
- const chargePointIdType = firstOCMDJSONDocument.payload.CT;
13824
- const chargePointId = firstOCMDJSONDocument.payload.CI;
13825
- if (isOptionalString(formatVersion) && isOptionalString(gatewayInformation) && isOptionalString(gatewaySerial) && isOptionalString(gatewayVersion) && isMandatoryString(paging) && isOptionalString(meterVendor) && isOptionalString(meterModel) && // OCMF 1.0 table 3 lists MS as 1..1, but the later "Relation of Serial Numbers,
13826
- // Charge Point and Public Key" section makes the serial-number fields conditionally
13827
- // mandatory. KEBA KCP30 records identify the signing gateway via GS and omit MS.
13828
- // Therefore we keep meterSerial and gatewaySerial separate, but require at least one
13829
- // usable serial number for the CTR meter identity.
13830
- isMandatoryString(effectiveMeterSerial) && isOptionalString(meterFirmware) && // OCMF 1.x uses boolean IS values. OCMF 0.1 SAFE reference data used status strings
13831
- // such as "VERIFIED", so accept both forms and preserve the original value in the CTR.
13832
- (isMandatoryBoolean(identificationStatus) || isMandatoryString(identificationStatus)) && isOptionalString(identificationLevel) && //chargyLib.isMandatoryArrayOfStrings (identificationFlags) &&
13833
- isOptionalArrayOfStrings(identificationFlags) && // Note: Some vendors do not use this MANDATORY field!
13834
- // IT is 1..1 in the user-assignment table for transaction records. Some OCMF 1.0
13835
- // implementations omit it when no user is assigned (IS=false, ID empty). We tolerate
13836
- // this vendor compatibility case instead of rejecting otherwise valid signatures.
13837
- isOptionalString(identificationType) && isOptionalString(identificationData) && isOptionalString(tariffText) && isOptionalString(controlerFirmwareVersion) && isOptionalJSONObject(lossCompensation) && isOptionalString(chargePointIdType) && isOptionalString(chargePointId)) {
13838
- const paginationPrefix = paging.length > 0 ? paging[0]?.toLowerCase() : null;
13839
- const transactionType = paginationPrefix === "t" ? "transaction" /* transaction */ : paginationPrefix === "f" ? "fiscal" /* fiscal */ : "undefined" /* undefined */;
13840
- const pagination = paging.length > 1 ? parseNumber(paging.substring(1)) : null;
13841
- if (transactionType === "undefined" /* undefined */) return {
13842
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13843
- message: this.chargy.GetLocalizedMessage("The given OCMF data does not have a valid transaction type!"),
13844
- certainty: 0
13845
- };
13846
- if (!isMandatoryNumber(pagination)) return {
13847
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13848
- message: this.chargy.GetLocalizedMessage("The given OCMF data does not have a valid pagination counter!"),
13849
- certainty: 0
13850
- };
13851
- if (firstOCMDJSONDocument.payload.RD.length == 0) return {
13852
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13853
- message: this.chargy.GetLocalizedMessage("Each OCMF data set must have at least one meter reading!"),
13854
- certainty: 0
13855
- };
13856
- const CTR = {
13857
- "@id": "?",
13858
- "@context": "https://open.charging.cloud/contexts/CTR+json",
13859
- //"@context": [ "https://open.charging.cloud/contexts/CTR+json", "https://open.charging.cloud/contexts/CTR_OCMF+json" ],
13870
+ const firstOCMDJSONDocument = getFirstArrayElement(OCMFJSONDocuments, "Missing first OCMF JSON document");
13871
+ const formatVersion = firstOCMDJSONDocument.payload.FV;
13872
+ const gatewayInformation = firstOCMDJSONDocument.payload.GI ?? firstOCMDJSONDocument.payload.VI;
13873
+ const gatewaySerial = firstOCMDJSONDocument.payload.GS;
13874
+ const gatewayVersion = firstOCMDJSONDocument.payload.GV ?? firstOCMDJSONDocument.payload.VV;
13875
+ const paging = firstOCMDJSONDocument.payload.PG;
13876
+ const meterVendor = firstOCMDJSONDocument.payload.MV;
13877
+ const meterModel = firstOCMDJSONDocument.payload.MM;
13878
+ const meterSerial = firstOCMDJSONDocument.payload.MS;
13879
+ const effectiveMeterSerial = meterSerial ?? gatewaySerial;
13880
+ const meterFirmware = firstOCMDJSONDocument.payload.MF;
13881
+ const identificationStatus = firstOCMDJSONDocument.payload.IS;
13882
+ const identificationLevel = firstOCMDJSONDocument.payload.IL;
13883
+ const identificationFlags = firstOCMDJSONDocument.payload.IF;
13884
+ const identificationType = firstOCMDJSONDocument.payload.IT;
13885
+ const identificationData = firstOCMDJSONDocument.payload.ID;
13886
+ const tariffText = firstOCMDJSONDocument.payload.TT;
13887
+ const controlerFirmwareVersion = firstOCMDJSONDocument.payload.CF;
13888
+ const lossCompensation = firstOCMDJSONDocument.payload.LC;
13889
+ const chargePointIdType = firstOCMDJSONDocument.payload.CT;
13890
+ const chargePointId = firstOCMDJSONDocument.payload.CI;
13891
+ if (isOptionalString(formatVersion) && isOptionalString(gatewayInformation) && isOptionalString(gatewaySerial) && isOptionalString(gatewayVersion) && isMandatoryString(paging) && isOptionalString(meterVendor) && isOptionalString(meterModel) && // OCMF 1.0 table 3 lists MS as 1..1, but the later "Relation of Serial Numbers,
13892
+ // Charge Point and Public Key" section makes the serial-number fields conditionally
13893
+ // mandatory. KEBA KCP30 records identify the signing gateway via GS and omit MS.
13894
+ // Therefore we keep meterSerial and gatewaySerial separate, but require at least one
13895
+ // usable serial number for the CTR meter identity.
13896
+ isMandatoryString(effectiveMeterSerial) && isOptionalString(meterFirmware) && // OCMF 1.x uses boolean IS values. OCMF 0.1 SAFE reference data used status strings
13897
+ // such as "VERIFIED", so accept both forms and preserve the original value in the CTR.
13898
+ (isMandatoryBoolean(identificationStatus) || isMandatoryString(identificationStatus)) && isOptionalString(identificationLevel) && //chargyLib.isMandatoryArrayOfStrings (identificationFlags) &&
13899
+ isOptionalArrayOfStrings(identificationFlags) && // Note: Some vendors do not use this MANDATORY field!
13900
+ // IT is 1..1 in the user-assignment table for transaction records. Some OCMF 1.0
13901
+ // implementations omit it when no user is assigned (IS=false, ID empty). We tolerate
13902
+ // this vendor compatibility case instead of rejecting otherwise valid signatures.
13903
+ isOptionalString(identificationType) && isOptionalString(identificationData) && isOptionalString(tariffText) && isOptionalString(controlerFirmwareVersion) && isOptionalJSONObject(lossCompensation) && isOptionalString(chargePointIdType) && isOptionalString(chargePointId)) {
13904
+ const paginationPrefix = paging.length > 0 ? paging.charAt(0).toLowerCase() : null;
13905
+ const transactionType = paginationPrefix === "t" ? "transaction" /* transaction */ : paginationPrefix === "f" ? "fiscal" /* fiscal */ : "undefined" /* undefined */;
13906
+ const pagination = paging.length > 1 ? parseNumber(paging.substring(1)) : null;
13907
+ if (transactionType === "undefined" /* undefined */) return {
13908
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13909
+ message: this.chargy.GetMultilanguageText("The given OCMF data does not have a valid transaction type!"),
13910
+ certainty: 0
13911
+ };
13912
+ if (!isMandatoryNumber(pagination)) return {
13913
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13914
+ message: this.chargy.GetMultilanguageText("The given OCMF data does not have a valid pagination counter!"),
13915
+ certainty: 0
13916
+ };
13917
+ if (firstOCMDJSONDocument.payload.RD.length == 0) return {
13918
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13919
+ message: this.chargy.GetMultilanguageText("Each OCMF data set must have at least one meter reading!"),
13920
+ certainty: 0
13921
+ };
13922
+ const CTR = {
13923
+ "@id": "?",
13924
+ "@context": "https://open.charging.cloud/contexts/CTR+json",
13925
+ //"@context": [ "https://open.charging.cloud/contexts/CTR+json", "https://open.charging.cloud/contexts/CTR_OCMF+json" ],
13926
+ "begin": "?",
13927
+ "end": "?",
13928
+ "description": {
13929
+ "de": "Alle OCMF-Ladevorg\xE4nge"
13930
+ },
13931
+ "contract": {
13932
+ "@id": identificationData ?? "?",
13933
+ "type": identificationType ?? "?"
13934
+ },
13935
+ "ocmf": {
13936
+ "formatVersion": formatVersion,
13937
+ "gatewayInformation": gatewayInformation,
13938
+ "gatewaySerial": gatewaySerial,
13939
+ "gatewayVersion": gatewayVersion
13940
+ },
13941
+ // "chargingStationOperators": [{
13942
+ "chargingPools": [{
13943
+ "@id": "DE*GEF*POOL*CHARGY*1",
13944
+ "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
13945
+ "chargingStations": [{
13946
+ "@id": chargingStationId,
13947
+ "description": stationDescription && Object.keys(stationDescription).length > 0 ? stationDescription : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
13948
+ "firmwareVersion": asString(chargingStationInfo?.["softwareVersion"]) ?? asString(chargingStationInfo?.["firmwareVersion"]),
13949
+ "geoLocation": asJSONObject(chargingStationInfo?.["geoLocation"]),
13950
+ "address": asJSONObject(chargingStationInfo?.["address"]),
13951
+ "EVSEs": [{
13952
+ "@id": evseId,
13953
+ "description": evseDescription && Object.keys(evseDescription).length > 0 ? evseDescription : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
13954
+ "connectors": connectorInfo ? [{
13955
+ "type": asString(connectorInfo["type"]) ?? "",
13956
+ "looses": asNumber(connectorInfo["looses"]) ?? 0
13957
+ }] : void 0,
13958
+ "meters": [{
13959
+ "@id": effectiveMeterSerial,
13960
+ // The signed OCMF payload values always win,
13961
+ // the container infos only fill the gaps!
13962
+ "manufacturer": meterVendor ?? asString(energyMeterInfo?.["manufacturer"]),
13963
+ "manufacturerURL": asString(energyMeterInfo?.["manufacturerURL"]),
13964
+ "model": meterModel ?? asString(energyMeterInfo?.["model"]),
13965
+ "modelURL": asString(energyMeterInfo?.["modelURL"]),
13966
+ "hardwareVersion": asString(energyMeterInfo?.["hardwareVersion"]),
13967
+ "firmwareVersion": meterFirmware ?? asString(energyMeterInfo?.["firmwareVersion"]),
13968
+ "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
13969
+ "publicKeys": [{
13970
+ "algorithm": "?",
13971
+ "encoding": "?",
13972
+ "format": "?",
13973
+ "value": "?"
13974
+ }]
13975
+ }]
13976
+ }]
13977
+ }]
13978
+ }],
13979
+ "chargingSessions": [{
13980
+ "@id": "1554181214441:-1965658344385548683:2",
13981
+ "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
13860
13982
  "begin": "?",
13861
13983
  "end": "?",
13862
- "description": {
13863
- "de": "Alle OCMF-Ladevorg\xE4nge"
13864
- },
13865
- "contract": {
13984
+ "EVSEId": evseId,
13985
+ "authorizationStart": {
13866
13986
  "@id": identificationData ?? "?",
13867
- "type": identificationType ?? "?"
13868
- },
13869
- "ocmf": {
13870
- "formatVersion": formatVersion,
13871
- "gatewayInformation": gatewayInformation,
13872
- "gatewaySerial": gatewaySerial,
13873
- "gatewayVersion": gatewayVersion
13987
+ "type": identificationType ?? "?",
13988
+ "identificationStatus": identificationStatus,
13989
+ "identificationLevel": identificationLevel,
13990
+ "identificationFlags": identificationFlags ?? []
13991
+ // Note: The OCMF documentation expects an empty array!
13874
13992
  },
13875
- // "chargingStationOperators": [{
13876
- "chargingPools": [{
13877
- "@id": "DE*GEF*POOL*CHARGY*1",
13878
- "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
13879
- "chargingStations": [{
13880
- "@id": chargingStationId,
13881
- "description": stationDescription && Object.keys(stationDescription).length > 0 ? stationDescription : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
13882
- "firmwareVersion": asString(chargingStationInfo?.["softwareVersion"]) ?? asString(chargingStationInfo?.["firmwareVersion"]),
13883
- "geoLocation": asJSONObject(chargingStationInfo?.["geoLocation"]),
13884
- "address": asJSONObject(chargingStationInfo?.["address"]),
13885
- "EVSEs": [{
13886
- "@id": evseId,
13887
- "description": evseDescription && Object.keys(evseDescription).length > 0 ? evseDescription : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
13888
- "connectors": connectorInfo ? [{
13889
- "type": asString(connectorInfo["type"]) ?? "",
13890
- "looses": asNumber(connectorInfo["looses"]) ?? 0
13891
- }] : void 0,
13892
- "meters": [{
13893
- "@id": effectiveMeterSerial,
13894
- // The signed OCMF payload values always win,
13895
- // the container infos only fill the gaps!
13896
- "manufacturer": meterVendor ?? asString(energyMeterInfo?.["manufacturer"]),
13897
- "manufacturerURL": asString(energyMeterInfo?.["manufacturerURL"]),
13898
- "model": meterModel ?? asString(energyMeterInfo?.["model"]),
13899
- "modelURL": asString(energyMeterInfo?.["modelURL"]),
13900
- "hardwareVersion": asString(energyMeterInfo?.["hardwareVersion"]),
13901
- "firmwareVersion": meterFirmware ?? asString(energyMeterInfo?.["firmwareVersion"]),
13902
- "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
13903
- "publicKeys": [{
13904
- "algorithm": "?",
13905
- "encoding": "?",
13906
- "format": "?",
13907
- "value": "?"
13908
- }]
13909
- }]
13910
- }]
13911
- }]
13912
- }],
13913
- "chargingSessions": [{
13914
- "@id": "1554181214441:-1965658344385548683:2",
13915
- "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
13916
- "begin": "?",
13917
- "end": "?",
13918
- "EVSEId": evseId,
13919
- "authorizationStart": {
13920
- "@id": identificationData ?? "?",
13921
- "type": identificationType ?? "?",
13922
- "identificationStatus": identificationStatus,
13923
- "identificationLevel": identificationLevel,
13924
- "identificationFlags": identificationFlags ?? []
13925
- // Note: The OCMF documentation expects an empty array!
13926
- },
13927
- "measurements": []
13928
- }],
13929
- "certainty": 1
13930
- };
13931
- const measurementsByKey = /* @__PURE__ */ new Map();
13932
- for (const ocmfJSONDocument of OCMFJSONDocuments) {
13933
- let inheritedReading = {};
13934
- for (const reading of ocmfJSONDocument.payload.RD) {
13935
- const effectiveReading = { ...inheritedReading, ...reading };
13936
- const time = effectiveReading.TM;
13937
- const transaction = effectiveReading.TX;
13938
- const readingValue = effectiveReading.RV;
13939
- const readingIdentification = effectiveReading.RI;
13940
- const readingUnit = effectiveReading.RU;
13941
- const readingCurrentType = effectiveReading.RT;
13942
- const cumulatedLoss = effectiveReading.CL;
13943
- const errorFlags = effectiveReading.EF;
13944
- const status = effectiveReading.ST;
13945
- inheritedReading = effectiveReading;
13946
- if (isMandatoryString(time) && isOptionalString(transaction) && isMandatoryDecimal(readingValue) && // Note: Some vendors use a JSON string here!
13947
- isOptionalString(readingIdentification) && isMandatoryString(readingUnit) && isOptionalString(readingCurrentType) && isOptionalDecimal(cumulatedLoss) && isOptionalString(errorFlags) && isMandatoryString(status)) {
13948
- const timeSplit = time.split(" ");
13949
- if (timeSplit.length != 2) return {
13950
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13951
- message: this.chargy.GetLocalizedMessage("The given OCMF meter value does not have a valid time format!"),
13952
- certainty: 0
13953
- };
13954
- const timeRegEx = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2},\d{3}[+-]\d{4}$/;
13955
- const timeStamp = timeSplit[0];
13956
- if (!isMandatoryString(timeStamp) || !timeRegEx.test(timeStamp)) return {
13957
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13958
- message: this.chargy.GetLocalizedMessage("The given OCMF meter value does not have a valid time sync format!"),
13959
- certainty: 0
13960
- };
13961
- const timeStampISO8601 = this.convertToISO8601(timeStamp);
13962
- const timeSyncText = timeSplit[1];
13963
- let timeSync = "unknown" /* unknown */;
13964
- if (!isMandatoryString(timeSyncText) || !["U", "I", "S", "R"].includes(timeSyncText)) return {
13965
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13966
- message: this.chargy.GetLocalizedMessage("The given OCMF meter value does not have a valid time sync format!"),
13967
- certainty: 0
13968
- };
13969
- switch (timeSyncText) {
13970
- case "U":
13971
- timeSync = "unknown" /* unknown */;
13972
- break;
13973
- case "I":
13974
- timeSync = "informative" /* informative */;
13975
- break;
13976
- case "S":
13977
- timeSync = "syncronized" /* syncronized */;
13978
- break;
13979
- case "R":
13980
- timeSync = "relative" /* relative */;
13981
- break;
13982
- default:
13983
- return {
13984
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13985
- message: this.chargy.GetLocalizedMessage("The given OCMF meter value does not have a valid time sync format!"),
13986
- certainty: 0
13987
- };
13988
- }
13989
- if (transaction && !["B", "C", "X", "E", "L", "R", "A", "P", "S", "T"].includes(transaction)) return {
13990
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13991
- message: this.chargy.GetLocalizedMessage("The given OCMF meter value does not have a valid transaction type!"),
13992
- certainty: 0
13993
- };
13994
- if (!["kWh", "Wh", "mOhm", "uOhm"].includes(readingUnit)) return {
13995
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
13996
- message: this.chargy.GetLocalizedMessage("The given OCMF meter value does not have a valid current type!"),
13997
- certainty: 0
13998
- };
13999
- if (readingCurrentType && !["AC", "DC"].includes(readingCurrentType)) return {
14000
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14001
- message: this.chargy.GetLocalizedMessage("The given OCMF meter value does not have a valid current type!"),
14002
- certainty: 0
14003
- };
14004
- if (CTR.chargingSessions?.[0]?.begin === "?")
14005
- CTR.chargingSessions[0].begin = timeStampISO8601;
14006
- CTR.chargingSessions[0].end = timeStampISO8601;
14007
- const measurementKey = [
14008
- readingIdentification ?? "?",
14009
- readingUnit,
14010
- readingCurrentType ?? ""
14011
- ].join("|");
14012
- let measurement = measurementsByKey.get(measurementKey);
14013
- if (measurement == null) {
14014
- measurement = {
14015
- "name": OBIS2MeasurementName(readingIdentification ?? ""),
14016
- "scale": 0,
14017
- "energyMeterId": effectiveMeterSerial,
14018
- "@context": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
14019
- "obis": readingIdentification ?? "?",
14020
- // OBIS: "1-b:1.8.0"
14021
- "unit": readingUnit,
14022
- // "kWh"
14023
- "currentType": readingCurrentType,
14024
- // "AC"
14025
- "values": []
13993
+ "measurements": []
13994
+ }],
13995
+ "certainty": 1
13996
+ };
13997
+ const measurementsByKey = /* @__PURE__ */ new Map();
13998
+ for (const ocmfJSONDocument of OCMFJSONDocuments) {
13999
+ let inheritedReading = {};
14000
+ for (const reading of ocmfJSONDocument.payload.RD) {
14001
+ const effectiveReading = { ...inheritedReading, ...reading };
14002
+ const time = effectiveReading.TM;
14003
+ const transaction = effectiveReading.TX;
14004
+ const readingValue = effectiveReading.RV;
14005
+ const readingIdentification = effectiveReading.RI;
14006
+ const readingUnit = effectiveReading.RU;
14007
+ const readingCurrentType = effectiveReading.RT;
14008
+ const cumulatedLoss = effectiveReading.CL;
14009
+ const errorFlags = effectiveReading.EF;
14010
+ const status = effectiveReading.ST;
14011
+ inheritedReading = effectiveReading;
14012
+ if (isMandatoryString(time) && isOptionalString(transaction) && isMandatoryDecimal(readingValue) && // Note: Some vendors use a JSON string here!
14013
+ isOptionalString(readingIdentification) && isMandatoryString(readingUnit) && isOptionalString(readingCurrentType) && // chargyLib.isOptionalDecimal (cumulatedLoss) &&
14014
+ isOptionalString(errorFlags) && isMandatoryString(status)) {
14015
+ const timeSplit = time.split(" ");
14016
+ if (timeSplit.length != 2) return {
14017
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14018
+ message: this.chargy.GetMultilanguageText("The given OCMF meter value does not have a valid time format!"),
14019
+ certainty: 0
14020
+ };
14021
+ const timeRegEx = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2},\d{3}[+-]\d{4}$/;
14022
+ const timeStamp = timeSplit[0];
14023
+ if (!isMandatoryString(timeStamp) || !timeRegEx.test(timeStamp)) return {
14024
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14025
+ message: this.chargy.GetMultilanguageText("The given OCMF meter value does not have a valid time sync format!"),
14026
+ certainty: 0
14027
+ };
14028
+ const timeStampISO8601 = this.convertToISO8601(timeStamp);
14029
+ const timeSyncText = timeSplit[1];
14030
+ let timeSync = "unknown" /* unknown */;
14031
+ if (!isMandatoryString(timeSyncText) || !["U", "I", "S", "R"].includes(timeSyncText)) return {
14032
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14033
+ message: this.chargy.GetMultilanguageText("The given OCMF meter value does not have a valid time sync format!"),
14034
+ certainty: 0
14035
+ };
14036
+ switch (timeSyncText) {
14037
+ case "U":
14038
+ timeSync = "unknown" /* unknown */;
14039
+ break;
14040
+ case "I":
14041
+ timeSync = "informative" /* informative */;
14042
+ break;
14043
+ case "S":
14044
+ timeSync = "syncronized" /* syncronized */;
14045
+ break;
14046
+ case "R":
14047
+ timeSync = "relative" /* relative */;
14048
+ break;
14049
+ default:
14050
+ return {
14051
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14052
+ message: this.chargy.GetMultilanguageText("The given OCMF meter value does not have a valid time sync format!"),
14053
+ certainty: 0
14026
14054
  };
14027
- measurementsByKey.set(measurementKey, measurement);
14028
- CTR.chargingSessions[0].measurements.push(measurement);
14029
- }
14030
- measurement.values.push({
14031
- "timestamp": timeStampISO8601,
14032
- // "2019-06-26T08:57:44,337+0000"
14033
- "timeSync": timeSync,
14034
- // "U"|"I"|"S"|"R"
14035
- "transaction": transaction,
14036
- // "B"|"C"|"X"|"E"|"L"|"R"|"A"|"P"|"S"|"T"|null
14037
- "value": new Decimal(readingValue),
14038
- // 2935.6
14039
- "transactionType": transactionType,
14040
- // "T" ToDo: Serialize this to a string!
14041
- "pagination": pagination,
14042
- // "9289"
14043
- "errorFlags": errorFlags,
14044
- // ""
14045
- "cumulatedLoss": cumulatedLoss ? new Decimal(cumulatedLoss) : void 0,
14046
- "status": status,
14047
- // "G"
14048
- // "signatures": [{
14049
- // "value": ocmfJSONDocument.signature["SD"]
14050
- // }],
14051
- "result": {
14052
- "status": ocmfJSONDocument.validationStatus ?? "Unvalidated" /* Unvalidated */
14053
- },
14054
- "ocmfDocument": ocmfJSONDocument
14055
- });
14056
14055
  }
14056
+ if (transaction != null && transaction.length > 0 && !["B", "C", "X", "E", "L", "R", "A", "P", "S", "T"].includes(transaction)) return {
14057
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14058
+ message: this.chargy.GetMultilanguageText("The given OCMF meter value does not have a valid transaction type!"),
14059
+ certainty: 0
14060
+ };
14061
+ if (!["kWh", "Wh", "mOhm", "uOhm"].includes(readingUnit)) return {
14062
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14063
+ message: this.chargy.GetMultilanguageText("The given OCMF meter value does not have a valid current type!"),
14064
+ certainty: 0
14065
+ };
14066
+ if (readingCurrentType != null && readingCurrentType.length > 0 && !["AC", "DC"].includes(readingCurrentType)) return {
14067
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14068
+ message: this.chargy.GetMultilanguageText("The given OCMF meter value does not have a valid current type!"),
14069
+ certainty: 0
14070
+ };
14071
+ if (CTR.chargingSessions?.[0]?.begin === "?")
14072
+ CTR.chargingSessions[0].begin = timeStampISO8601;
14073
+ if (CTR.chargingSessions?.[0] !== void 0)
14074
+ CTR.chargingSessions[0].end = timeStampISO8601;
14075
+ const measurementKey = [
14076
+ readingIdentification ?? "?",
14077
+ readingUnit,
14078
+ readingCurrentType ?? ""
14079
+ ].join("|");
14080
+ let measurement = measurementsByKey.get(measurementKey);
14081
+ if (measurement == null) {
14082
+ measurement = {
14083
+ "name": OBIS2MeasurementName(readingIdentification ?? ""),
14084
+ "scale": 0,
14085
+ "energyMeterId": effectiveMeterSerial,
14086
+ "@context": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
14087
+ "obis": readingIdentification ?? "?",
14088
+ // OBIS: "1-b:1.8.0"
14089
+ "unit": readingUnit,
14090
+ // "kWh"
14091
+ "currentType": readingCurrentType,
14092
+ // "AC"
14093
+ "values": []
14094
+ };
14095
+ measurementsByKey.set(measurementKey, measurement);
14096
+ const firstChargingSession = CTR.chargingSessions?.[0];
14097
+ if (firstChargingSession !== void 0)
14098
+ firstChargingSession.measurements.push(measurement);
14099
+ }
14100
+ measurement.values.push({
14101
+ "timestamp": timeStampISO8601,
14102
+ // "2019-06-26T08:57:44,337+0000"
14103
+ "timeSync": timeSync,
14104
+ // "U"|"I"|"S"|"R"
14105
+ "transaction": transaction,
14106
+ // "B"|"C"|"X"|"E"|"L"|"R"|"A"|"P"|"S"|"T"|null
14107
+ "value": new Decimal(readingValue),
14108
+ // 2935.6
14109
+ "transactionType": transactionType,
14110
+ // "T" ToDo: Serialize this to a string!
14111
+ "pagination": pagination,
14112
+ // "9289"
14113
+ "errorFlags": errorFlags,
14114
+ // ""
14115
+ "cumulatedLoss": cumulatedLoss != null && cumulatedLoss !== 0 ? new Decimal(cumulatedLoss) : void 0,
14116
+ "status": status,
14117
+ // "G"
14118
+ // "signatures": [{
14119
+ // "value": ocmfJSONDocument.signature["SD"]
14120
+ // }],
14121
+ "result": {
14122
+ "status": ocmfJSONDocument.validationStatus ?? "Unvalidated" /* Unvalidated */
14123
+ },
14124
+ "ocmfDocument": ocmfJSONDocument
14125
+ });
14057
14126
  }
14058
14127
  }
14059
- CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
14060
- if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0] != null) {
14061
- CTR.begin = CTR.chargingSessions[0].begin;
14062
- CTR.end = CTR.chargingSessions[0].end;
14063
- return CTR;
14064
- }
14128
+ }
14129
+ CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
14130
+ if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0]) {
14131
+ CTR.begin = CTR.chargingSessions[0].begin;
14132
+ CTR.end = CTR.chargingSessions[0].end;
14133
+ return CTR;
14065
14134
  }
14066
14135
  }
14067
14136
  } catch (exception) {
14068
14137
  return {
14069
14138
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14070
- message: "Invalid OCMF data: " + (exception instanceof Error ? exception.message : String(exception)),
14139
+ message: this.chargy.GetMultilanguageText("Invalid OCMF data: " + (exception instanceof Error ? exception.message : String(exception))),
14071
14140
  certainty: 0
14072
14141
  };
14073
14142
  }
@@ -14078,113 +14147,121 @@ var OCMF = class {
14078
14147
  }
14079
14148
  //#endregion
14080
14149
  //#region (private) mergeOCMFSessions(CTRs)
14081
- mergeOCMFSessions(CTRs) {
14082
- const mergedCTR = {
14083
- "@id": "",
14084
- "@context": "",
14085
- certainty: 1
14086
- };
14087
- for (const ctr of CTRs) {
14088
- if (mergedCTR["@id"] === "")
14089
- mergedCTR["@id"] = ctr["@id"];
14090
- if (mergedCTR["@context"] === "")
14091
- mergedCTR["@context"] = ctr["@context"];
14092
- if (!mergedCTR.begin || mergedCTR.begin && ctr.begin && mergedCTR.begin > ctr.begin)
14093
- mergedCTR.begin = ctr.begin;
14094
- if (!mergedCTR.end || mergedCTR.end && ctr.end && mergedCTR.end < ctr.end)
14095
- mergedCTR.end = ctr.end;
14096
- if (!mergedCTR.description)
14097
- mergedCTR.description = ctr.description;
14098
- if (!mergedCTR.contract)
14099
- mergedCTR.contract = ctr.contract;
14100
- if (!mergedCTR.chargingStationOperators)
14101
- mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
14102
- else if (ctr.chargingStationOperators)
14103
- for (const chargingStationOperator of ctr.chargingStationOperators)
14104
- mergedCTR.chargingStationOperators.push(chargingStationOperator);
14105
- if (!mergedCTR.chargingPools)
14106
- mergedCTR.chargingPools = ctr.chargingPools;
14107
- else if (ctr.chargingPools)
14108
- for (const chargingPool of ctr.chargingPools)
14109
- mergedCTR.chargingPools.push(chargingPool);
14110
- if (!mergedCTR.chargingStations)
14111
- mergedCTR.chargingStations = ctr.chargingStations;
14112
- else if (ctr.chargingStations)
14113
- for (const chargingStation of ctr.chargingStations)
14114
- mergedCTR.chargingStations.push(chargingStation);
14115
- if (!mergedCTR.chargingSessions)
14116
- mergedCTR.chargingSessions = ctr.chargingSessions;
14117
- else if (ctr.chargingSessions)
14118
- for (const chargingSession of ctr.chargingSessions)
14119
- mergedCTR.chargingSessions.push(chargingSession);
14120
- if (!mergedCTR.eMobilityProviders)
14121
- mergedCTR.eMobilityProviders = ctr.eMobilityProviders;
14122
- else if (ctr.eMobilityProviders)
14123
- for (const eMobilityProvider of ctr.eMobilityProviders)
14124
- mergedCTR.eMobilityProviders.push(eMobilityProvider);
14125
- if (!mergedCTR.mediationServices)
14126
- mergedCTR.mediationServices = ctr.mediationServices;
14127
- else if (ctr.mediationServices)
14128
- for (const mediationService of ctr.mediationServices)
14129
- mergedCTR.mediationServices.push(mediationService);
14130
- }
14131
- return mergedCTR;
14132
- }
14150
+ // private mergeOCMFSessions(CTRs: Array<IOCMFChargeTransparencyRecord>): IOCMFChargeTransparencyRecord
14151
+ // {
14152
+ // const mergedCTR:IOCMFChargeTransparencyRecord = {
14153
+ // "@id": "",
14154
+ // "@context": "",
14155
+ // certainty: 1
14156
+ // };
14157
+ // for (const ctr of CTRs)
14158
+ // {
14159
+ // if (mergedCTR["@id"] === "")
14160
+ // mergedCTR["@id"] = ctr["@id"];
14161
+ // if (mergedCTR["@context"] === "")
14162
+ // mergedCTR["@context"] = ctr["@context"];
14163
+ // if (!mergedCTR.begin || (mergedCTR.begin && ctr.begin && mergedCTR.begin > ctr.begin))
14164
+ // mergedCTR.begin = ctr.begin;
14165
+ // if (!mergedCTR.end || (mergedCTR.end && ctr.end && mergedCTR.end < ctr.end))
14166
+ // mergedCTR.end = ctr.end;
14167
+ // if (!mergedCTR.description)
14168
+ // mergedCTR.description = ctr.description;
14169
+ // //ToDo: Is this a really good idea? Or should we fail, whenever this information is different?
14170
+ // if (!mergedCTR.contract)
14171
+ // mergedCTR.contract = ctr.contract;
14172
+ // if (!mergedCTR.chargingStationOperators)
14173
+ // mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
14174
+ // else if (ctr.chargingStationOperators)
14175
+ // for (const chargingStationOperator of ctr.chargingStationOperators)
14176
+ // mergedCTR.chargingStationOperators.push(chargingStationOperator);
14177
+ // if (!mergedCTR.chargingPools)
14178
+ // mergedCTR.chargingPools = ctr.chargingPools;
14179
+ // else if (ctr.chargingPools)
14180
+ // for (const chargingPool of ctr.chargingPools)
14181
+ // mergedCTR.chargingPools.push(chargingPool);
14182
+ // if (!mergedCTR.chargingStations)
14183
+ // mergedCTR.chargingStations = ctr.chargingStations;
14184
+ // else if (ctr.chargingStations)
14185
+ // for (const chargingStation of ctr.chargingStations)
14186
+ // mergedCTR.chargingStations.push(chargingStation);
14187
+ // // publicKeys
14188
+ // if (!mergedCTR.chargingSessions)
14189
+ // mergedCTR.chargingSessions = ctr.chargingSessions;
14190
+ // else if (ctr.chargingSessions)
14191
+ // for (const chargingSession of ctr.chargingSessions)
14192
+ // mergedCTR.chargingSessions.push(chargingSession);
14193
+ // if (!mergedCTR.eMobilityProviders)
14194
+ // mergedCTR.eMobilityProviders = ctr.eMobilityProviders;
14195
+ // else if (ctr.eMobilityProviders)
14196
+ // for (const eMobilityProvider of ctr.eMobilityProviders)
14197
+ // mergedCTR.eMobilityProviders.push(eMobilityProvider);
14198
+ // if (!mergedCTR.mediationServices)
14199
+ // mergedCTR.mediationServices = ctr.mediationServices;
14200
+ // else if (ctr.mediationServices)
14201
+ // for (const mediationService of ctr.mediationServices)
14202
+ // mergedCTR.mediationServices.push(mediationService);
14203
+ // }
14204
+ // return mergedCTR;
14205
+ // }
14133
14206
  //#endregion
14134
14207
  //#region (private) mergeChargeTransparencyRecords(CTRs)
14135
- mergeChargeTransparencyRecords(CTRs) {
14136
- const mergedCTR = {
14137
- "@id": "",
14138
- "@context": "",
14139
- certainty: 1
14140
- };
14141
- for (const ctr of CTRs) {
14142
- if (mergedCTR["@id"] === "")
14143
- mergedCTR["@id"] = ctr["@id"];
14144
- if (mergedCTR["@context"] === "")
14145
- mergedCTR["@context"] = ctr["@context"];
14146
- if (!mergedCTR.begin || mergedCTR.begin && ctr.begin && mergedCTR.begin > ctr.begin)
14147
- mergedCTR.begin = ctr.begin;
14148
- if (!mergedCTR.end || mergedCTR.end && ctr.end && mergedCTR.end < ctr.end)
14149
- mergedCTR.end = ctr.end;
14150
- if (!mergedCTR.description)
14151
- mergedCTR.description = ctr.description;
14152
- if (!mergedCTR.contract)
14153
- mergedCTR.contract = ctr.contract;
14154
- if (!mergedCTR.chargingStationOperators)
14155
- mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
14156
- else if (ctr.chargingStationOperators)
14157
- for (const chargingStationOperator of ctr.chargingStationOperators)
14158
- mergedCTR.chargingStationOperators.push(chargingStationOperator);
14159
- if (!mergedCTR.chargingPools)
14160
- mergedCTR.chargingPools = ctr.chargingPools;
14161
- else if (ctr.chargingPools)
14162
- for (const chargingPool of ctr.chargingPools)
14163
- mergedCTR.chargingPools.push(chargingPool);
14164
- if (!mergedCTR.chargingStations)
14165
- mergedCTR.chargingStations = ctr.chargingStations;
14166
- else if (ctr.chargingStations)
14167
- for (const chargingStation of ctr.chargingStations)
14168
- mergedCTR.chargingStations.push(chargingStation);
14169
- if (!mergedCTR.chargingSessions)
14170
- mergedCTR.chargingSessions = ctr.chargingSessions;
14171
- else if (ctr.chargingSessions)
14172
- for (const chargingSession of ctr.chargingSessions)
14173
- mergedCTR.chargingSessions.push(chargingSession);
14174
- if (!mergedCTR.eMobilityProviders)
14175
- mergedCTR.eMobilityProviders = ctr.eMobilityProviders;
14176
- else if (ctr.eMobilityProviders)
14177
- for (const eMobilityProvider of ctr.eMobilityProviders)
14178
- mergedCTR.eMobilityProviders.push(eMobilityProvider);
14179
- if (!mergedCTR.mediationServices)
14180
- mergedCTR.mediationServices = ctr.mediationServices;
14181
- else if (ctr.mediationServices)
14182
- for (const mediationService of ctr.mediationServices)
14183
- mergedCTR.mediationServices.push(mediationService);
14184
- }
14185
- return mergedCTR;
14186
- }
14187
- //#endregion
14208
+ // private mergeChargeTransparencyRecords(CTRs: Array<IOCMFChargeTransparencyRecord>): IOCMFChargeTransparencyRecord
14209
+ // {
14210
+ // const mergedCTR:IOCMFChargeTransparencyRecord = {
14211
+ // "@id": "",
14212
+ // "@context": "",
14213
+ // certainty: 1
14214
+ // };
14215
+ // for (const ctr of CTRs)
14216
+ // {
14217
+ // if (mergedCTR["@id"] === "")
14218
+ // mergedCTR["@id"] = ctr["@id"];
14219
+ // if (mergedCTR["@context"] === "")
14220
+ // mergedCTR["@context"] = ctr["@context"];
14221
+ // if (!mergedCTR.begin || (mergedCTR.begin && ctr.begin && mergedCTR.begin > ctr.begin))
14222
+ // mergedCTR.begin = ctr.begin;
14223
+ // if (!mergedCTR.end || (mergedCTR.end && ctr.end && mergedCTR.end < ctr.end))
14224
+ // mergedCTR.end = ctr.end;
14225
+ // if (!mergedCTR.description)
14226
+ // mergedCTR.description = ctr.description;
14227
+ // //ToDo: Is this a really good idea? Or should we fail, whenever this information is different?
14228
+ // if (!mergedCTR.contract)
14229
+ // mergedCTR.contract = ctr.contract;
14230
+ // if (!mergedCTR.chargingStationOperators)
14231
+ // mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
14232
+ // else if (ctr.chargingStationOperators)
14233
+ // for (const chargingStationOperator of ctr.chargingStationOperators)
14234
+ // mergedCTR.chargingStationOperators.push(chargingStationOperator);
14235
+ // if (!mergedCTR.chargingPools)
14236
+ // mergedCTR.chargingPools = ctr.chargingPools;
14237
+ // else if (ctr.chargingPools)
14238
+ // for (const chargingPool of ctr.chargingPools)
14239
+ // mergedCTR.chargingPools.push(chargingPool);
14240
+ // if (!mergedCTR.chargingStations)
14241
+ // mergedCTR.chargingStations = ctr.chargingStations;
14242
+ // else if (ctr.chargingStations)
14243
+ // for (const chargingStation of ctr.chargingStations)
14244
+ // mergedCTR.chargingStations.push(chargingStation);
14245
+ // // publicKeys
14246
+ // if (!mergedCTR.chargingSessions)
14247
+ // mergedCTR.chargingSessions = ctr.chargingSessions;
14248
+ // else if (ctr.chargingSessions)
14249
+ // for (const chargingSession of ctr.chargingSessions)
14250
+ // mergedCTR.chargingSessions.push(chargingSession);
14251
+ // if (!mergedCTR.eMobilityProviders)
14252
+ // mergedCTR.eMobilityProviders = ctr.eMobilityProviders;
14253
+ // else if (ctr.eMobilityProviders)
14254
+ // for (const eMobilityProvider of ctr.eMobilityProviders)
14255
+ // mergedCTR.eMobilityProviders.push(eMobilityProvider);
14256
+ // if (!mergedCTR.mediationServices)
14257
+ // mergedCTR.mediationServices = ctr.mediationServices;
14258
+ // else if (ctr.mediationServices)
14259
+ // for (const mediationService of ctr.mediationServices)
14260
+ // mergedCTR.mediationServices.push(mediationService);
14261
+ // }
14262
+ // return mergedCTR;
14263
+ // }
14264
+ // //#endregion
14188
14265
  //#region (private) validateOCMFSignature(OCMFJSONDocument, PublicKey, PublicKeyEncoding?)
14189
14266
  async validateOCMFSignature(OCMFJSONDocument, PublicKey, PublicKeyEncoding) {
14190
14267
  try {
@@ -14243,7 +14320,7 @@ var OCMF = class {
14243
14320
  this.key("pubKey").bitstr()
14244
14321
  );
14245
14322
  });
14246
- if (PublicKeyEncoding) {
14323
+ if (PublicKeyEncoding != null && PublicKeyEncoding.length > 0) {
14247
14324
  switch (PublicKeyEncoding.toLowerCase()) {
14248
14325
  case "hex":
14249
14326
  publicKeyBytes = Buffer.from(OCMFJSONDocument.publicKey, "hex");
@@ -14271,11 +14348,12 @@ var OCMF = class {
14271
14348
  publicKeyBytes = Buffer.from(OCMFJSONDocument.publicKey, "base64");
14272
14349
  }
14273
14350
  }
14274
- if (!publicKeyBytes) {
14351
+ if (publicKeyBytes == null) {
14275
14352
  OCMFJSONDocument.validationStatus = "UnknownPublicKeyFormat" /* UnknownPublicKeyFormat */;
14276
14353
  return OCMFJSONDocument.validationStatus;
14277
14354
  }
14278
- const publicKeyASN1 = ECPoint.decode(publicKeyBytes, "der");
14355
+ const decodedPublicKeyASN1 = ECPoint.decode(publicKeyBytes, "der");
14356
+ const publicKeyASN1 = decodedPublicKeyASN1;
14279
14357
  const coordinates = publicKeyASN1.pubKey.data.subarray(1);
14280
14358
  const halfLength = coordinates.length / 2;
14281
14359
  const publicKeyXY = {
@@ -14284,7 +14362,7 @@ var OCMF = class {
14284
14362
  };
14285
14363
  publicKey = curve.keyFromPublic(publicKeyXY, "hex");
14286
14364
  OCMFJSONDocument.publicKey = {
14287
- algorithm: OCMFJSONDocument.signature.SA ? OCMFJSONDocument.signature.SA.substring(
14365
+ algorithm: OCMFJSONDocument.signature.SA != null && OCMFJSONDocument.signature.SA.length > 0 ? OCMFJSONDocument.signature.SA.substring(
14288
14366
  OCMFJSONDocument.signature.SA.indexOf("-") + 1,
14289
14367
  OCMFJSONDocument.signature.SA.lastIndexOf("-")
14290
14368
  ) : "secp256r1",
@@ -14435,7 +14513,7 @@ var OCMF = class {
14435
14513
  hashValue,
14436
14514
  publicKey: PublicKey,
14437
14515
  publicKeyEncoding: PublicKeyEncoding,
14438
- validationStatus: validationStatus ? validationStatus : PublicKey ? "Unvalidated" /* Unvalidated */ : "PublicKeyNotFound" /* PublicKeyNotFound */
14516
+ validationStatus: validationStatus ?? (PublicKey != null ? "Unvalidated" /* Unvalidated */ : "PublicKeyNotFound" /* PublicKeyNotFound */)
14439
14517
  };
14440
14518
  try {
14441
14519
  const ECDSASignature = this.chargy.asn1.define("ECDSASignature", function() {
@@ -14457,7 +14535,8 @@ var OCMF = class {
14457
14535
  default:
14458
14536
  ocmfJSONDocument.validationStatus = "UnknownSignatureFormat" /* UnknownSignatureFormat */;
14459
14537
  }
14460
- const signatureObj = ECDSASignature.decode(Buffer.from(ocmfJSONDocument.signature.SD, bufferEncoding), "der");
14538
+ const decodedSignatureObj = ECDSASignature.decode(Buffer.from(ocmfJSONDocument.signature.SD, bufferEncoding), "der");
14539
+ const signatureObj = decodedSignatureObj;
14461
14540
  ocmfJSONDocument.signatureRS = {
14462
14541
  value: ocmfJSONDocument.signature.SD,
14463
14542
  r: signatureObj.r.toString(16),
@@ -14466,7 +14545,7 @@ var OCMF = class {
14466
14545
  } catch {
14467
14546
  ocmfJSONDocument.validationStatus = "InvalidSignature" /* InvalidSignature */;
14468
14547
  }
14469
- if (PublicKey && ocmfJSONDocument.validationStatus === "Unvalidated" /* Unvalidated */)
14548
+ if (PublicKey != null && ocmfJSONDocument.validationStatus === "Unvalidated" /* Unvalidated */)
14470
14549
  await this.validateOCMFSignature(
14471
14550
  ocmfJSONDocument,
14472
14551
  PublicKey,
@@ -14495,14 +14574,14 @@ var OCMF = class {
14495
14574
  //#endregion
14496
14575
  //#region TryToParseOCMFDocument (OCMFDocument, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
14497
14576
  async TryToParseOCMFDocument(OCMFDocument, PublicKey, PublicKeyEncoding, ContainerInfos) {
14498
- return await this.TryToParseOCMFDocuments([OCMFDocument], PublicKey, PublicKeyEncoding, ContainerInfos);
14577
+ return this.TryToParseOCMFDocuments([OCMFDocument], PublicKey, PublicKeyEncoding, ContainerInfos);
14499
14578
  }
14500
14579
  //#endregion
14501
14580
  //#region TryToParseOCMFDocuments(OCMFDocuments, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
14502
14581
  async TryToParseOCMFDocuments(OCMFDocuments, PublicKey, PublicKeyEncoding, ContainerInfos) {
14503
14582
  if (OCMFDocuments.length == 0) return {
14504
14583
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14505
- message: this.chargy.GetLocalizedMessage("The given OCMF data could not be parsed") + "!",
14584
+ message: this.chargy.GetMultilanguageText(this.chargy.GetLocalizedMessage("The given OCMF data could not be parsed") + "!"),
14506
14585
  certainty: 0
14507
14586
  };
14508
14587
  const ocmfJSONDocumentGroups = /* @__PURE__ */ new Map();
@@ -14515,20 +14594,21 @@ var OCMF = class {
14515
14594
  if (typeof ocmfJSONDocuments !== "string") {
14516
14595
  for (const ocmfJSONDocument of ocmfJSONDocuments) {
14517
14596
  try {
14518
- const groupingKey = (ocmfJSONDocument.payload.FV ?? "") + "|" + (ocmfJSONDocument.payload.GI ?? "") + "|" + (ocmfJSONDocument.payload.GS ?? "") + "|" + (ocmfJSONDocument.payload.GV ?? "") + "|" + (ocmfJSONDocument.payload.MV ?? "") + "|" + (ocmfJSONDocument.payload.MM ?? "") + "|" + (ocmfJSONDocument.payload.MS ?? "") + "|" + (ocmfJSONDocument.payload.MF ?? "") + "|" + (ocmfJSONDocument.payload.IS ? "1|" : "0|") + (ocmfJSONDocument.payload.IL ?? "") + "|" + (ocmfJSONDocument.payload.IF ?? "") + "|" + (ocmfJSONDocument.payload.IT ?? "") + "|" + (ocmfJSONDocument.payload.ID ?? "") + "|" + (ocmfJSONDocument.payload.TT ?? "") + "|" + (ocmfJSONDocument.payload.CF ?? "") + "|" + (ocmfJSONDocument.payload.CT ?? "") + "|" + (ocmfJSONDocument.payload.CI ?? "");
14597
+ const groupingKey = (ocmfJSONDocument.payload.FV ?? "") + "|" + (ocmfJSONDocument.payload.GI ?? "") + "|" + (ocmfJSONDocument.payload.GS ?? "") + "|" + (ocmfJSONDocument.payload.GV ?? "") + "|" + (ocmfJSONDocument.payload.MV ?? "") + "|" + (ocmfJSONDocument.payload.MM ?? "") + "|" + (ocmfJSONDocument.payload.MS ?? "") + "|" + (ocmfJSONDocument.payload.MF ?? "") + "|" + (ocmfJSONDocument.payload.IS === true ? "1|" : "0|") + (ocmfJSONDocument.payload.IL ?? "") + "|" + //(ocmfJSONDocument.payload.IF ?? "") + "|" +
14598
+ (ocmfJSONDocument.payload.IT ?? "") + "|" + (ocmfJSONDocument.payload.ID ?? "") + "|" + (ocmfJSONDocument.payload.TT ?? "") + "|" + (ocmfJSONDocument.payload.CF ?? "") + "|" + (ocmfJSONDocument.payload.CT ?? "") + "|" + (ocmfJSONDocument.payload.CI ?? "");
14519
14599
  if (!ocmfJSONDocumentGroups.has(groupingKey))
14520
14600
  ocmfJSONDocumentGroups.set(groupingKey, new Array());
14521
14601
  ocmfJSONDocumentGroups.get(groupingKey)?.push(ocmfJSONDocument);
14522
14602
  } catch (exception) {
14523
14603
  return {
14524
14604
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14525
- message: this.chargy.GetLocalizedMessage("The given OCMF data could not be parsed") + ": " + (exception instanceof Error ? exception.message : String(exception)),
14605
+ message: this.chargy.GetMultilanguageText(this.chargy.GetLocalizedMessage("The given OCMF data could not be parsed") + ": " + (exception instanceof Error ? exception.message : String(exception))),
14526
14606
  certainty: 0
14527
14607
  };
14528
14608
  }
14529
14609
  }
14530
14610
  for (const ocmfJSONDocumentGroup of ocmfJSONDocumentGroups.values()) {
14531
- if (PublicKey) {
14611
+ if (PublicKey != null) {
14532
14612
  for (const ocmfJSONDocument of ocmfJSONDocumentGroup)
14533
14613
  if (ocmfJSONDocument.validationStatus === "Unvalidated" /* Unvalidated */)
14534
14614
  await this.validateOCMFSignature(ocmfJSONDocument, PublicKey);
@@ -14550,7 +14630,7 @@ var OCMF = class {
14550
14630
  default:
14551
14631
  ocmfCTRs.push({
14552
14632
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14553
- message: this.chargy.GetLocalizedMessage("Unknown OCMF version!"),
14633
+ message: this.chargy.GetMultilanguageText("Unknown OCMF version!"),
14554
14634
  certainty: 0
14555
14635
  });
14556
14636
  break;
@@ -14562,7 +14642,7 @@ var OCMF = class {
14562
14642
  }
14563
14643
  return {
14564
14644
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14565
- message: this.chargy.GetLocalizedMessage("The given OCMF data could not be parsed") + (typeof ocmfJSONDocuments === "string" ? ": " + ocmfJSONDocuments : "!"),
14645
+ message: this.chargy.GetMultilanguageText(this.chargy.GetLocalizedMessage("The given OCMF data could not be parsed") + (typeof ocmfJSONDocuments === "string" ? ": " + ocmfJSONDocuments : "!")),
14566
14646
  certainty: 0
14567
14647
  };
14568
14648
  }
@@ -14580,12 +14660,6 @@ var OCPI = class {
14580
14660
  constructor(chargy) {
14581
14661
  this.chargy = chargy;
14582
14662
  }
14583
- bufferToHex(buffer, Reverse) {
14584
- return (Reverse ? Array.from(new Uint8Array(buffer)).reverse() : Array.from(new Uint8Array(buffer))).map((b) => b.toString(16).padStart(2, "0")).join("");
14585
- }
14586
- bufferToNumber(buffer) {
14587
- return parseInt(Array.from(new Uint8Array(buffer)).map((b) => b.toString(16).padStart(2, "0")).join(""), 16);
14588
- }
14589
14663
  //#region tryToParseChargeITContainerFormat(SomeJSON)
14590
14664
  // The chargeIT mobility data format does not always provide context information or format identifiers!
14591
14665
  async tryToParseOCPIFormat(SomeJSON) {
@@ -14605,11 +14679,11 @@ var OCPI = class {
14605
14679
  const public_key = SomeJSON["public_key"];
14606
14680
  const signed_values = SomeJSON["signed_values"];
14607
14681
  if (!isMandatoryString(encoding_method))
14608
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidEncodingMethod"));
14682
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidEncodingMethod")));
14609
14683
  if (!isMandatoryString(public_key))
14610
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidPublicKey"));
14684
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidPublicKey")));
14611
14685
  if (!isMandatoryJSONArray(signed_values))
14612
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidSignedValues"));
14686
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidSignedValues")));
14613
14687
  if (errors.length > 0)
14614
14688
  return {
14615
14689
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
@@ -14619,7 +14693,7 @@ var OCPI = class {
14619
14693
  };
14620
14694
  if (encoding_method === "OCMF" && isMandatoryJSONArray(signed_values) && signed_values.length > 0) {
14621
14695
  const firstSignedData = asString(asJSONObject(signed_values[0])?.["signed_data"]);
14622
- if (firstSignedData) {
14696
+ if (firstSignedData != null && firstSignedData.length > 0) {
14623
14697
  const placeInfo = asJSONObject(SomeJSON["placeInfo"]);
14624
14698
  const geoLocation = asJSONObject(placeInfo?.["geoLocation"]);
14625
14699
  const address = asJSONObject(placeInfo?.["address"]);
@@ -14638,7 +14712,7 @@ var OCPI = class {
14638
14712
  },
14639
14713
  energyMeter: asJSONObject(SomeJSON["meterInfo"])
14640
14714
  };
14641
- return await new OCMF(this.chargy).TryToParseOCMFDocument(
14715
+ return new OCMF(this.chargy).TryToParseOCMFDocument(
14642
14716
  firstSignedData,
14643
14717
  asString(public_key),
14644
14718
  encoding_method,
@@ -14711,138 +14785,138 @@ var OCPI = class {
14711
14785
  const chargingCostsInfo_flat_cost = chargingCostsInfo_flat?.["cost"];
14712
14786
  const signedMeterValues = SomeJSON["signedMeterValues"];
14713
14787
  if (!isMandatoryString(chargingSessionId))
14714
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid charge transparency record identification!"));
14788
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid charge transparency record identification!")));
14715
14789
  if (!isMandatoryJSONObject(chargePointInfo)) {
14716
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidChargePointInfo"));
14790
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidChargePointInfo")));
14717
14791
  secondaryErrors += 19;
14718
14792
  } else {
14719
14793
  if (!isMandatoryString(evseId))
14720
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidEVSEIdentification"));
14794
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidEVSEIdentification")));
14721
14795
  if (!isMandatoryJSONObject(placeInfo)) {
14722
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidPlaceInfo"));
14796
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidPlaceInfo")));
14723
14797
  secondaryErrors += 8;
14724
14798
  } else {
14725
14799
  if (!isMandatoryJSONObject(geoLocation)) {
14726
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocation"));
14800
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocation")));
14727
14801
  secondaryErrors += 2;
14728
14802
  } else {
14729
14803
  if (!isMandatoryNumber(geoLocation_lat))
14730
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocationLatitude"));
14804
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocationLatitude")));
14731
14805
  if (!isMandatoryNumber(geoLocation_lon))
14732
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocationLongitude"));
14806
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocationLongitude")));
14733
14807
  }
14734
14808
  if (!isMandatoryJSONObject(address)) {
14735
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddress"));
14809
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddress")));
14736
14810
  secondaryErrors += 4;
14737
14811
  } else {
14738
14812
  if (!isMandatoryString(address_street))
14739
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressStreetName"));
14813
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressStreetName")));
14740
14814
  if (!isMandatoryString(address_zipCode))
14741
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressZIPCode"));
14815
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressZIPCode")));
14742
14816
  if (!isMandatoryString(address_town))
14743
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressCityName"));
14817
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressCityName")));
14744
14818
  if (!isMandatoryString(address_country))
14745
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressCountryName"));
14819
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressCountryName")));
14746
14820
  }
14747
14821
  }
14748
14822
  }
14749
14823
  if (!isMandatoryJSONObject(chargingStationInfo)) {
14750
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidChargingStationInfo"));
14824
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidChargingStationInfo")));
14751
14825
  secondaryErrors += 5;
14752
14826
  } else {
14753
14827
  if (!isOptionalString(chargingStation_manufacturer))
14754
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station manufacturer!"));
14828
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station manufacturer!")));
14755
14829
  if (!isOptionalString(chargingStation_type))
14756
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station type!"));
14830
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station type!")));
14757
14831
  if (!isOptionalString(chargingStation_serialNumber))
14758
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station serial number!"));
14832
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station serial number!")));
14759
14833
  if (!isOptionalString(chargingStation_controllerSoftwareVersion))
14760
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station controller software version!"));
14834
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station controller software version!")));
14761
14835
  if (!isOptionalString(chargingStation_compliance))
14762
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station compliance!"));
14836
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station compliance!")));
14763
14837
  if (!isOptionalURL(chargingStation_complianceURL))
14764
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station compliance URL!"));
14838
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station compliance URL!")));
14765
14839
  if (!isOptionalString(chargingStation_conformity))
14766
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station conformity!"));
14840
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station conformity!")));
14767
14841
  if (!isOptionalURL(chargingStation_conformity_URL))
14768
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station conformity URL!"));
14842
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station conformity URL!")));
14769
14843
  if (!isOptionalURL(chargingStation_conformity_certificateId))
14770
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station conformity certificate identification!"));
14844
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station conformity certificate identification!")));
14771
14845
  if (!isOptionalString(chargingStation_calibration))
14772
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station calibration!"));
14846
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station calibration!")));
14773
14847
  if (!isOptionalURL(chargingStation_calibration_URL))
14774
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station calibration URL!"));
14848
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station calibration URL!")));
14775
14849
  if (!isOptionalURL(chargingStation_calibration_certificateId))
14776
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station calibration certificate identification!"));
14850
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station calibration certificate identification!")));
14777
14851
  }
14778
14852
  if (meterInfo) {
14779
14853
  if (!isOptionalString(meterInfo_meterId))
14780
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1));
14854
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1)));
14781
14855
  if (!isOptionalString(meterInfo_manufacturer))
14782
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
14856
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
14783
14857
  if (!isOptionalString(meterInfo_manufacturerURL))
14784
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
14858
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
14785
14859
  if (!isOptionalString(meterInfo_model))
14786
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
14860
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
14787
14861
  if (!isOptionalString(meterInfo_modelURL))
14788
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
14862
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
14789
14863
  if (!isOptionalString(meterInfo_firmwareVersion))
14790
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1));
14864
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1)));
14791
14865
  if (!isOptionalString(meterInfo_hardwareVersion))
14792
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1));
14866
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1)));
14793
14867
  if (!isOptionalString(meterInfo_publicKey))
14794
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
14868
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
14795
14869
  if (!isOptionalString(meterInfo_publicKeyFormat))
14796
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
14870
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
14797
14871
  if (!isOptionalString(meterInfo_publicKeyEncoding))
14798
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
14872
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
14799
14873
  if (!isOptionalString(meterInfo_signatureFormat))
14800
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
14874
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
14801
14875
  if (!isOptionalString(meterInfo_signatureEncoding))
14802
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
14876
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
14803
14877
  }
14804
14878
  if (connectorInfo) {
14805
14879
  if (!isOptionalString(connectorInfo_type))
14806
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1));
14880
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1)));
14807
14881
  if (!isOptionalString(connectorInfo_losses))
14808
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1));
14882
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1)));
14809
14883
  }
14810
14884
  if (chargingCostsInfo) {
14811
14885
  if (!isMandatoryNumber(chargingCostsInfo_total))
14812
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid total costs within the charging costs!"));
14886
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid total costs within the charging costs!")));
14813
14887
  if (!isMandatoryString(chargingCostsInfo_currency))
14814
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid currency within the charging costs!"));
14888
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid currency within the charging costs!")));
14815
14889
  if (chargingCostsInfo_reservation) {
14816
14890
  if (!isMandatoryNumber(chargingCostsInfo_reservation_cost))
14817
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid reservation cost within the charging costs!"));
14891
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid reservation cost within the charging costs!")));
14818
14892
  if (!isMandatoryString(chargingCostsInfo_reservation_unit))
14819
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid reservation unit within the charging costs!"));
14893
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid reservation unit within the charging costs!")));
14820
14894
  }
14821
14895
  if (chargingCostsInfo_energy) {
14822
14896
  if (!isMandatoryNumber(chargingCostsInfo_energy_cost))
14823
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid energy cost within the charging costs!"));
14897
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid energy cost within the charging costs!")));
14824
14898
  if (!isMandatoryString(chargingCostsInfo_energy_unit))
14825
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid energy unit within the charging costs!"));
14899
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid energy unit within the charging costs!")));
14826
14900
  }
14827
14901
  if (chargingCostsInfo_time) {
14828
14902
  if (!isMandatoryNumber(chargingCostsInfo_time_cost))
14829
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid time cost within the charging costs!"));
14903
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid time cost within the charging costs!")));
14830
14904
  if (!isMandatoryString(chargingCostsInfo_time_unit))
14831
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid time unit within the charging costs!"));
14905
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid time unit within the charging costs!")));
14832
14906
  }
14833
14907
  if (chargingCostsInfo_idle) {
14834
14908
  if (!isMandatoryNumber(chargingCostsInfo_idle_cost))
14835
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid idle cost within the charging costs!"));
14909
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid idle cost within the charging costs!")));
14836
14910
  if (!isMandatoryString(chargingCostsInfo_idle_unit))
14837
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid idle unit within the charging costs!"));
14911
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid idle unit within the charging costs!")));
14838
14912
  }
14839
14913
  if (chargingCostsInfo_flat) {
14840
14914
  if (!isMandatoryNumber(chargingCostsInfo_flat_cost))
14841
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid flat cost within the charging costs!"));
14915
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid flat cost within the charging costs!")));
14842
14916
  }
14843
14917
  }
14844
14918
  if (!isMandatoryJSONArray(signedMeterValues) || signedMeterValues.length < 2) {
14845
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidSignedMeterValues"));
14919
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidSignedMeterValues")));
14846
14920
  secondaryErrors += 2 * 39;
14847
14921
  } else {
14848
14922
  const firstSMV = asJSONObject(signedMeterValues[0]);
@@ -14852,7 +14926,7 @@ var OCPI = class {
14852
14926
  const context = asString(currentSMV?.["@context"])?.trim() ?? asString(currentSMV?.["format"])?.trim() ?? null;
14853
14927
  if (smvContext !== context) return {
14854
14928
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14855
- message: "Inconsistent signed meter value format!",
14929
+ message: this.chargy.GetMultilanguageText("Inconsistent signed meter value format!"),
14856
14930
  certainty: 1
14857
14931
  };
14858
14932
  }
@@ -14956,9 +15030,9 @@ var OCPI = class {
14956
15030
  ],
14957
15031
  certainty: 0
14958
15032
  };
14959
- if (smvContext?.startsWith("https://www.chargeit-mobility.com/contexts/bsm-ws36a-json"))
15033
+ if (smvContext?.startsWith("https://www.chargeit-mobility.com/contexts/bsm-ws36a-json") === true)
14960
15034
  return new BSMCrypt01(this.chargy).tryToParseBSM_WS36aMeasurements(CTR, evseIdStr, asString(chargingStation_controllerSoftwareVersion) ?? null, signedMeterValues);
14961
- if (smvContext?.startsWith("ALFEN"))
15035
+ if (smvContext?.startsWith("ALFEN") === true)
14962
15036
  return new Alfen(this.chargy).TryToParseALFENFormat(
14963
15037
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
14964
15038
  {
@@ -14997,7 +15071,7 @@ var OCPI = class {
14997
15071
  } catch (exception) {
14998
15072
  return {
14999
15073
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15000
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
15074
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
15001
15075
  errors,
15002
15076
  warnings,
15003
15077
  certainty: (numberOfFormatChecks - errors.length - secondaryErrors) / numberOfFormatChecks
@@ -15006,7 +15080,7 @@ var OCPI = class {
15006
15080
  }
15007
15081
  return {
15008
15082
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15009
- message: "No chargeIT charge transparency record",
15083
+ message: this.chargy.GetMultilanguageText("No chargeIT charge transparency record"),
15010
15084
  errors,
15011
15085
  warnings,
15012
15086
  certainty: 0
@@ -15105,9 +15179,9 @@ function parsePCDFDocument(input) {
15105
15179
  }
15106
15180
  const fields = {};
15107
15181
  for (let i = 0; i < PCDF_FIELD_ORDER.length; i++) {
15108
- const value = match[i + 1];
15109
- const field = PCDF_FIELD_ORDER[i];
15110
- if (field == null || value == null)
15182
+ const value = getArrayElement(match, i + 1, "Missing PCDF field value");
15183
+ const field = getArrayElement(PCDF_FIELD_ORDER, i, "Missing PCDF field name");
15184
+ if (value.length === 0)
15111
15185
  throw new PCDFParseError("MISSING_FIELDS", "Missing fields in the data tuple", field);
15112
15186
  fields[field] = value;
15113
15187
  }
@@ -15292,7 +15366,7 @@ var PCDF = class {
15292
15366
  if (externalPublicKey != null && normalizePCDFPublicKeyHex(externalPublicKey) !== publicKey) {
15293
15367
  return {
15294
15368
  status: "InvalidPublicKey" /* InvalidPublicKey */,
15295
- message: "Wrong Public Key",
15369
+ message: this.chargy.GetMultilanguageText("Wrong Public Key"),
15296
15370
  certainty: 1
15297
15371
  };
15298
15372
  }
@@ -15313,7 +15387,7 @@ var PCDF = class {
15313
15387
  } catch (exception) {
15314
15388
  return {
15315
15389
  status: exception instanceof PCDFParseError ? "InvalidSessionFormat" /* InvalidSessionFormat */ : "InvalidSessionFormat" /* InvalidSessionFormat */,
15316
- message: exception instanceof Error ? exception.message : String(exception),
15390
+ message: this.chargy.GetMultilanguageText(exception instanceof Error ? exception.message : String(exception)),
15317
15391
  certainty: 0
15318
15392
  };
15319
15393
  }
@@ -15479,8 +15553,10 @@ function parsePCDFReadingValue(value, errors) {
15479
15553
  errors.push("Session information is invalid");
15480
15554
  return void 0;
15481
15555
  }
15556
+ const integralPart = getArrayElement(match, 1, "Missing PCDF reading integral part");
15557
+ const fractionalPart = getArrayElement(match, 2, "Missing PCDF reading fractional part");
15482
15558
  return {
15483
- value: new Decimal(String(match[1]) + "." + String(match[2])),
15559
+ value: new Decimal(integralPart + "." + fractionalPart),
15484
15560
  unit: "kWh"
15485
15561
  };
15486
15562
  }
@@ -15515,9 +15591,9 @@ function hexToBytes2(hex, errorMessage) {
15515
15591
  }
15516
15592
  function readDERLength(bytes, getOffset, setOffset) {
15517
15593
  let offset = getOffset();
15518
- const b = bytes[offset++];
15519
- if (b == null)
15594
+ if (offset >= bytes.length)
15520
15595
  throw new Error("Invalid signature");
15596
+ const b = getArrayElement(bytes, offset++, "Invalid signature");
15521
15597
  if ((b & 128) === 0) {
15522
15598
  setOffset(offset);
15523
15599
  return b;
@@ -15527,9 +15603,9 @@ function readDERLength(bytes, getOffset, setOffset) {
15527
15603
  throw new Error("Invalid signature");
15528
15604
  let length = 0;
15529
15605
  for (let i = 0; i < octets; i++) {
15530
- const value = bytes[offset++];
15531
- if (value == null)
15606
+ if (offset >= bytes.length)
15532
15607
  throw new Error("Invalid signature");
15608
+ const value = getArrayElement(bytes, offset++, "Invalid signature");
15533
15609
  length = (length << 8) + value;
15534
15610
  }
15535
15611
  setOffset(offset);
@@ -15558,30 +15634,33 @@ var SAFEXML = class _SAFEXML {
15558
15634
  this.chargy = chargy;
15559
15635
  }
15560
15636
  static ParseChargingStationContext(XMLDocument) {
15561
- const chargingStationElement = getElementsByLocalName(XMLDocument, "chargingStation")[0];
15562
- if (!chargingStationElement)
15637
+ const chargingStationElement = getElementsByLocalName(XMLDocument, "chargingStation").at(0);
15638
+ if (chargingStationElement === void 0)
15563
15639
  return {};
15564
- const chargingStationId = chargingStationElement.getAttribute("id")?.trim() || getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "id"));
15640
+ const chargingStationAttributeId = chargingStationElement.getAttribute("id")?.trim();
15641
+ const chargingStationId = chargingStationAttributeId != null && chargingStationAttributeId.length > 0 ? chargingStationAttributeId : getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "id"));
15565
15642
  const softwareVersion = getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "softwareVersion"));
15566
15643
  const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
15567
15644
  const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "latitude")) ?? "");
15568
15645
  const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "longitude")) ?? "");
15569
15646
  const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
15570
- if (getDirectChildByLocalName(chargingStationElement, "EVSEs"))
15647
+ if (getDirectChildByLocalName(chargingStationElement, "EVSEs") !== void 0)
15571
15648
  throw new Error("The SAFE chargingStation XML element must contain EVSE directly and no EVSEs container element!");
15572
15649
  const evseElements = getDirectChildrenByLocalName(chargingStationElement, "EVSE");
15573
15650
  if (evseElements.length > 1)
15574
15651
  throw new Error("The SAFE chargingStation XML element must not contain more than one EVSE element!");
15575
- const evseElement = evseElements[0];
15576
- const evseId = evseElement?.getAttribute("id")?.trim() || getTrimmedTextContent(getDirectChildByLocalName(evseElement ?? chargingStationElement, "id")) || "";
15577
- const connectorElements = evseElement ? getDirectChildrenByLocalName(evseElement, "connector") : [];
15652
+ const evseElement = evseElements.at(0);
15653
+ const evseAttributeId = evseElement?.getAttribute("id")?.trim();
15654
+ const evseTextId = getTrimmedTextContent(getDirectChildByLocalName(evseElement ?? chargingStationElement, "id"));
15655
+ const evseId = evseAttributeId != null && evseAttributeId.length > 0 ? evseAttributeId : evseTextId ?? "";
15656
+ const connectorElements = evseElement !== void 0 ? getDirectChildrenByLocalName(evseElement, "connector") : [];
15578
15657
  if (connectorElements.length > 1)
15579
15658
  throw new Error("The SAFE EVSE XML element must not contain more than one connector element!");
15580
- const connectorElement = connectorElements[0];
15659
+ const connectorElement = connectorElements.at(0);
15581
15660
  const connectorId = connectorElement?.getAttribute("id")?.trim();
15582
15661
  const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement ?? evseElement ?? chargingStationElement, "type"));
15583
- const connector = connectorType ? { "@id": connectorId, type: connectorType, looses: 0 } : void 0;
15584
- const parsedEVSE = evseElement ? {
15662
+ const connector = connectorType != null && connectorType.length > 0 ? { "@id": connectorId, type: connectorType, looses: 0 } : void 0;
15663
+ const parsedEVSE = evseElement !== void 0 ? {
15585
15664
  "@id": evseId,
15586
15665
  "description": parseDescription(evseElement),
15587
15666
  "meters": [],
@@ -15619,7 +15698,7 @@ var SAFEXML = class _SAFEXML {
15619
15698
  if (signedData == null)
15620
15699
  return {
15621
15700
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15622
- message: "Each value within the given XML container must contain signed data!",
15701
+ message: this.chargy.GetMultilanguageText("Each value within the given XML container must contain signed data!"),
15623
15702
  certainty: 0
15624
15703
  };
15625
15704
  const signedDataFormat = signedData.attributes.getNamedItem("format")?.value.trim().toLowerCase() ?? "";
@@ -15628,7 +15707,7 @@ var SAFEXML = class _SAFEXML {
15628
15707
  else if (signedDataFormat !== commonSignedDataFormat)
15629
15708
  return {
15630
15709
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15631
- message: "Invalid mixture of different signed data formats within the given XML container!",
15710
+ message: this.chargy.GetMultilanguageText("Invalid mixture of different signed data formats within the given XML container!"),
15632
15711
  certainty: 0
15633
15712
  };
15634
15713
  const signedDataEncoding = signedData.attributes.getNamedItem("encoding")?.value.trim().toLowerCase() ?? "";
@@ -15637,14 +15716,14 @@ var SAFEXML = class _SAFEXML {
15637
15716
  else if (signedDataEncoding !== commonSignedDataEncoding)
15638
15717
  return {
15639
15718
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15640
- message: "Invalid mixture of different signed data encodings within the given XML container!",
15719
+ message: this.chargy.GetMultilanguageText("Invalid mixture of different signed data encodings within the given XML container!"),
15641
15720
  certainty: 0
15642
15721
  };
15643
15722
  const signedDataValue = signedData.textContent.trim();
15644
15723
  if (IsNullOrEmpty(signedDataValue))
15645
15724
  return {
15646
15725
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15647
- message: "The signed data value within the given XML container must not be empty!",
15726
+ message: this.chargy.GetMultilanguageText("The signed data value within the given XML container must not be empty!"),
15648
15727
  certainty: 0
15649
15728
  };
15650
15729
  const publicKeyEncoding = publicKey?.attributes.getNamedItem("encoding")?.value.trim().toLowerCase() ?? "";
@@ -15653,7 +15732,7 @@ var SAFEXML = class _SAFEXML {
15653
15732
  else if (publicKeyEncoding !== commonPublicKeyEncoding)
15654
15733
  return {
15655
15734
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15656
- message: "Invalid mixture of different public key encodings within the given XML container!",
15735
+ message: this.chargy.GetMultilanguageText("Invalid mixture of different public key encodings within the given XML container!"),
15657
15736
  certainty: 0
15658
15737
  };
15659
15738
  const publicKeyValue = publicKey?.textContent.trim().replace(/\s+/g, "") ?? "";
@@ -15662,7 +15741,7 @@ var SAFEXML = class _SAFEXML {
15662
15741
  else if (publicKeyValue !== commonPublicKey)
15663
15742
  return {
15664
15743
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15665
- message: "Invalid mixture of different public keys within the given XML container!",
15744
+ message: this.chargy.GetMultilanguageText("Invalid mixture of different public keys within the given XML container!"),
15666
15745
  certainty: 0
15667
15746
  };
15668
15747
  switch (commonSignedDataEncoding) {
@@ -15682,7 +15761,7 @@ var SAFEXML = class _SAFEXML {
15682
15761
  default:
15683
15762
  return {
15684
15763
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15685
- message: "Unkown signed data encoding within the given SAFE XML!",
15764
+ message: this.chargy.GetMultilanguageText("Unkown signed data encoding within the given SAFE XML!"),
15686
15765
  certainty: 0
15687
15766
  };
15688
15767
  }
@@ -15704,7 +15783,7 @@ var SAFEXML = class _SAFEXML {
15704
15783
  default:
15705
15784
  return {
15706
15785
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15707
- message: this.chargy.GetLocalizedMessage("UnknownOrInvalidChargingSessionFormat"),
15786
+ message: this.chargy.GetMultilanguageText("UnknownOrInvalidChargingSessionFormat"),
15708
15787
  certainty: 0
15709
15788
  };
15710
15789
  }
@@ -15713,13 +15792,13 @@ var SAFEXML = class _SAFEXML {
15713
15792
  } catch (exception) {
15714
15793
  return {
15715
15794
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15716
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
15795
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
15717
15796
  certainty: 0
15718
15797
  };
15719
15798
  }
15720
15799
  return {
15721
15800
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15722
- message: this.chargy.GetLocalizedMessage("UnknownOrInvalidChargingSessionFormat"),
15801
+ message: this.chargy.GetMultilanguageText("UnknownOrInvalidChargingSessionFormat"),
15723
15802
  certainty: 0
15724
15803
  };
15725
15804
  }
@@ -15746,8 +15825,8 @@ var XMLContainer = class {
15746
15825
  if (values.length == 1) {
15747
15826
  const valueList = values[0]?.querySelectorAll("signedMeterValue");
15748
15827
  if (valueList != null && valueList.length >= 1) {
15749
- for (let i = 0; i < valueList.length; i++) {
15750
- const publicKey = valueList[i]?.querySelector("publicKey");
15828
+ for (const valueElement of valueList) {
15829
+ const publicKey = valueElement.querySelector("publicKey");
15751
15830
  if (publicKey != null) {
15752
15831
  const publicKeyEncoding = publicKey.attributes.getNamedItem("encoding")?.value.trim().toLowerCase() ?? "";
15753
15832
  let publicKeyValue = publicKey.textContent.trim();
@@ -15768,14 +15847,14 @@ var XMLContainer = class {
15768
15847
  default:
15769
15848
  return {
15770
15849
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15771
- message: "Unkown public key encoding within the given XML container!",
15850
+ message: this.chargy.GetMultilanguageText("Unkown public key encoding within the given XML container!"),
15772
15851
  certainty: 0
15773
15852
  };
15774
15853
  }
15775
15854
  if (IsNullOrEmpty(publicKeyValue))
15776
15855
  return {
15777
15856
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15778
- message: "The public key within the given XML container must not be empty!",
15857
+ message: this.chargy.GetMultilanguageText("The public key within the given XML container must not be empty!"),
15779
15858
  certainty: 0
15780
15859
  };
15781
15860
  else if (common.publicKey == "")
@@ -15783,11 +15862,11 @@ var XMLContainer = class {
15783
15862
  else if (publicKeyValue != common.publicKey)
15784
15863
  return {
15785
15864
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15786
- message: "Invalid mixture of different public keys within the given XML container!",
15865
+ message: this.chargy.GetMultilanguageText("Invalid mixture of different public keys within the given XML container!"),
15787
15866
  certainty: 0
15788
15867
  };
15789
15868
  }
15790
- const meterValueSignature = valueList[i]?.querySelector("meterValueSignature");
15869
+ const meterValueSignature = valueElement.querySelector("meterValueSignature");
15791
15870
  if (meterValueSignature != null) {
15792
15871
  const meterValueSignatureEncoding = meterValueSignature.attributes.getNamedItem("encoding")?.value.trim().toLowerCase() ?? "";
15793
15872
  let meterValueSignatureValue = meterValueSignature.textContent.trim();
@@ -15808,37 +15887,37 @@ var XMLContainer = class {
15808
15887
  default:
15809
15888
  return {
15810
15889
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15811
- message: "Unkown meter value signature encoding within the given XML container!",
15890
+ message: this.chargy.GetMultilanguageText("Unkown meter value signature encoding within the given XML container!"),
15812
15891
  certainty: 0
15813
15892
  };
15814
15893
  }
15815
15894
  if (IsNullOrEmpty(meterValueSignatureValue))
15816
15895
  return {
15817
15896
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15818
- message: "The meter value signature within the given XML container must not be empty!",
15897
+ message: this.chargy.GetMultilanguageText("The meter value signature within the given XML container must not be empty!"),
15819
15898
  certainty: 0
15820
15899
  };
15821
15900
  common.meterValueSignatures.push(meterValueSignatureValue);
15822
15901
  }
15823
- const signatureMethod = valueList[i]?.querySelector("signatureMethod")?.textContent.trim().toLowerCase() ?? "";
15902
+ const signatureMethod = valueElement.querySelector("signatureMethod")?.textContent.trim().toLowerCase() ?? "";
15824
15903
  if (common.signatureMethod == "")
15825
15904
  common.signatureMethod = signatureMethod;
15826
15905
  else if (common.signatureMethod != signatureMethod)
15827
15906
  return {
15828
15907
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15829
- message: "Invalid mixture of different signature methods within the given XML container!",
15908
+ message: this.chargy.GetMultilanguageText("Invalid mixture of different signature methods within the given XML container!"),
15830
15909
  certainty: 0
15831
15910
  };
15832
- const encodingMethod = valueList[i]?.querySelector("encodingMethod")?.textContent.trim().toLowerCase() ?? "";
15911
+ const encodingMethod = valueElement.querySelector("encodingMethod")?.textContent.trim().toLowerCase() ?? "";
15833
15912
  if (common.encodingMethod == "")
15834
15913
  common.encodingMethod = encodingMethod;
15835
15914
  else if (common.encodingMethod != encodingMethod)
15836
15915
  return {
15837
15916
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15838
- message: "Invalid mixture of different signed data formats within the given XML container!",
15917
+ message: this.chargy.GetMultilanguageText("Invalid mixture of different signed data formats within the given XML container!"),
15839
15918
  certainty: 0
15840
15919
  };
15841
- const encodedMeterValue = valueList[i]?.querySelector("encodedMeterValue");
15920
+ const encodedMeterValue = valueElement.querySelector("encodedMeterValue");
15842
15921
  if (encodedMeterValue != null) {
15843
15922
  const signedDataEncoding = encodedMeterValue.attributes.getNamedItem("encoding")?.value.trim() ?? "";
15844
15923
  let signedDataValue = encodedMeterValue.textContent.trim();
@@ -15859,21 +15938,21 @@ var XMLContainer = class {
15859
15938
  default:
15860
15939
  return {
15861
15940
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15862
- message: "Unkown signed data encoding within the given XML container!",
15941
+ message: this.chargy.GetMultilanguageText("Unkown signed data encoding within the given XML container!"),
15863
15942
  certainty: 0
15864
15943
  };
15865
15944
  }
15866
15945
  if (IsNullOrEmpty(signedDataValue))
15867
15946
  return {
15868
15947
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15869
- message: "The signed data value within the given XML container must not be empty!",
15948
+ message: this.chargy.GetMultilanguageText("The signed data value within the given XML container must not be empty!"),
15870
15949
  certainty: 0
15871
15950
  };
15872
15951
  common.encodedMeterValues.push(signedDataValue);
15873
15952
  } else
15874
15953
  return {
15875
15954
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15876
- message: "The signed data tag within the given XML container must not be empty!",
15955
+ message: this.chargy.GetMultilanguageText("The signed data tag within the given XML container must not be empty!"),
15877
15956
  certainty: 0
15878
15957
  };
15879
15958
  }
@@ -15881,13 +15960,13 @@ var XMLContainer = class {
15881
15960
  }
15882
15961
  return {
15883
15962
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15884
- message: this.chargy.GetLocalizedMessage("UnknownOrInvalidChargingSessionFormat"),
15963
+ message: this.chargy.GetMultilanguageText("UnknownOrInvalidChargingSessionFormat"),
15885
15964
  certainty: 0
15886
15965
  };
15887
15966
  } catch (exception) {
15888
15967
  return {
15889
15968
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15890
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
15969
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
15891
15970
  certainty: 0
15892
15971
  };
15893
15972
  }
@@ -15899,12 +15978,6 @@ var ChargeIT = class {
15899
15978
  constructor(chargy) {
15900
15979
  this.chargy = chargy;
15901
15980
  }
15902
- bufferToHex(buffer, Reverse) {
15903
- return (Reverse ? Array.from(new Uint8Array(buffer)).reverse() : Array.from(new Uint8Array(buffer))).map((b) => b.toString(16).padStart(2, "0")).join("");
15904
- }
15905
- bufferToNumber(buffer) {
15906
- return parseInt(Array.from(new Uint8Array(buffer)).map((b) => b.toString(16).padStart(2, "0")).join(""), 16);
15907
- }
15908
15981
  //#region TryToParseOldChargeITMeterValuesFormat(CTR, evseId, address, geoLocation, signedMeterValues)
15909
15982
  TryToParseOldChargeITMeterValuesFormat(CTR, evseId, address, geoLocation, signedMeterValues) {
15910
15983
  const CTRArray = new Array();
@@ -16004,14 +16077,8 @@ var ChargeIT = class {
16004
16077
  });
16005
16078
  }
16006
16079
  }
16007
- const firstMeterValue = CTRArray[0];
16008
- const lastMeterValue = CTRArray[CTRArray.length - 1];
16009
- if (firstMeterValue === void 0 || lastMeterValue === void 0)
16010
- return {
16011
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
16012
- message: this.chargy.GetLocalizedMessage("UnknownOrInvalidChargingSessionFormat"),
16013
- certainty: 0
16014
- };
16080
+ const firstMeterValue = getFirstArrayElement(CTRArray, "Missing first chargeIT meter value");
16081
+ const lastMeterValue = getLastArrayElement(CTRArray, "Missing last chargeIT meter value");
16015
16082
  CTR["@id"] = lastMeterValue["transactionId"];
16016
16083
  CTR.begin = this.chargy.moment.unix(firstMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
16017
16084
  CTR.end = this.chargy.moment.unix(lastMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
@@ -16194,38 +16261,38 @@ var ChargeIT = class {
16194
16261
  {
16195
16262
  const placeInfo = asJSONObject(SomeJSON["placeInfo"]);
16196
16263
  if (placeInfo === void 0) {
16197
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidPlaceInfo"));
16264
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidPlaceInfo")));
16198
16265
  secondaryErrors += 13;
16199
16266
  } else {
16200
16267
  const evseId = placeInfo["evseId"];
16201
16268
  if (!isMandatoryString(evseId))
16202
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidEVSEId"));
16269
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidEVSEId")));
16203
16270
  const address = asJSONObject(placeInfo["address"]);
16204
16271
  if (address === void 0) {
16205
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddress"));
16272
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddress")));
16206
16273
  secondaryErrors += 3;
16207
16274
  } else {
16208
16275
  if (!isMandatoryString(address["street"]))
16209
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressStreetName"));
16276
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressStreetName")));
16210
16277
  if (!isMandatoryString(address["zipCode"]))
16211
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressZIPCode"));
16278
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressZIPCode")));
16212
16279
  if (!isMandatoryString(address["town"]))
16213
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressCityName"));
16280
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressCityName")));
16214
16281
  }
16215
16282
  const geoLocation = asJSONObject(placeInfo["geoLocation"]);
16216
16283
  if (geoLocation === void 0) {
16217
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocation"));
16284
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocation")));
16218
16285
  secondaryErrors += 2;
16219
16286
  } else {
16220
16287
  if (!isMandatoryNumber(geoLocation["lat"]))
16221
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocationLatitude"));
16288
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocationLatitude")));
16222
16289
  if (!isMandatoryNumber(geoLocation["lon"]))
16223
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocationLongitude"));
16290
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocationLongitude")));
16224
16291
  }
16225
16292
  }
16226
16293
  const signedMeterValues = SomeJSON["signedMeterValues"];
16227
16294
  if (!isMandatoryJSONArray(signedMeterValues) || signedMeterValues.length < 2) {
16228
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidSignedMeterValues"));
16295
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidSignedMeterValues")));
16229
16296
  secondaryErrors += 2 * 39;
16230
16297
  } else {
16231
16298
  numberOfFormatChecks += 39 * (signedMeterValues.length - 2);
@@ -16234,135 +16301,134 @@ var ChargeIT = class {
16234
16301
  for (const signedMeterValue of signedMeterValues.map((smv) => asJSONObject(smv))) {
16235
16302
  if ((signedMeterValue?.["@context"] ?? oldChargeITMeterValueFormat) !== signedMeterValueContext) {
16236
16303
  if (consistent)
16237
- errors.push(this.chargy.GetLocalizedMessage("InconsistentJSONContextInformation"));
16304
+ errors.push(CreateError(this.chargy.GetMultilanguageText("InconsistentJSONContextInformation")));
16238
16305
  consistent = false;
16239
16306
  }
16240
16307
  }
16241
16308
  if (consistent) {
16242
16309
  if (signedMeterValueContext === "https://www.lichtblick.de/contexts/bsm-ws36a-json-v0" || signedMeterValueContext === "https://www.lichtblick.de/contexts/bsm-ws36a-json-v1" || signedMeterValueContext === "https://www.eneco.com/contexts/bsm-ws36a-json-v0" || signedMeterValueContext === "https://www.eneco.com/contexts/bsm-ws36a-json-v1" || signedMeterValueContext === "https://www.chargeit-mobility.com/contexts/bsm-ws36a-json-v0" || signedMeterValueContext === "https://www.chargeit-mobility.com/contexts/bsm-ws36a-json-v1") {
16243
16310
  } else if (signedMeterValueContext.startsWith("ALFEN")) {
16244
- } else if (containerFormat === oldChargeITContainerFormat) {
16245
16311
  } else if (signedMeterValueContext === oldChargeITMeterValueFormat) {
16246
16312
  let measurementCounter = 0;
16247
16313
  for (const signedMeterValue of signedMeterValues) {
16248
16314
  measurementCounter++;
16249
16315
  if (!isMandatoryJSONObject(signedMeterValue)) {
16250
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalidSignedMeterValueP", measurementCounter));
16316
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalidSignedMeterValueP", measurementCounter)));
16251
16317
  secondaryErrors += 38;
16252
16318
  } else {
16253
16319
  if (!isMandatoryString(signedMeterValue["measurementId"]))
16254
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasurementIdP", measurementCounter));
16320
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasurementIdP", measurementCounter)));
16255
16321
  if (!isMandatoryNumber(signedMeterValue["timestamp"]))
16256
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_TimestampP", measurementCounter));
16322
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_TimestampP", measurementCounter)));
16257
16323
  if (!isMandatoryString(signedMeterValue["transactionId"]))
16258
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_TransactionIdP", measurementCounter));
16324
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_TransactionIdP", measurementCounter)));
16259
16325
  if (!isMandatoryString(signedMeterValue["signature"]))
16260
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_SignatureP", measurementCounter));
16326
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_SignatureP", measurementCounter)));
16261
16327
  const meterInfo = signedMeterValue["meterInfo"];
16262
16328
  if (!isMandatoryJSONObject(meterInfo)) {
16263
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfoP", measurementCounter));
16329
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfoP", measurementCounter)));
16264
16330
  secondaryErrors += 5;
16265
16331
  } else {
16266
16332
  if (!isMandatoryString(meterInfo["meterId"]))
16267
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", measurementCounter));
16333
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", measurementCounter)));
16268
16334
  if (!isMandatoryString(meterInfo["type"]))
16269
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_TypeP", measurementCounter));
16335
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_TypeP", measurementCounter)));
16270
16336
  if (!isMandatoryString(meterInfo["firmwareVersion"]))
16271
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", measurementCounter));
16337
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", measurementCounter)));
16272
16338
  if (!isMandatoryString(meterInfo["publicKey"]))
16273
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", measurementCounter));
16339
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", measurementCounter)));
16274
16340
  if (!isMandatoryString(meterInfo["manufacturer"]))
16275
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", measurementCounter));
16341
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", measurementCounter)));
16276
16342
  if (isOptionalJSONArrayError(meterInfo["publicKeySignatures"]))
16277
- errors.push(this.chargy.GetLocalizedMessageWithParameter("Invalid_SignedMeterValue_MeterInfo_PublicKeySignaturesP", measurementCounter));
16343
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("Invalid_SignedMeterValue_MeterInfo_PublicKeySignaturesP", measurementCounter)));
16278
16344
  }
16279
16345
  const contract = signedMeterValue["contract"];
16280
16346
  if (!isMandatoryJSONObject(contract)) {
16281
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_ContractP", measurementCounter));
16347
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_ContractP", measurementCounter)));
16282
16348
  secondaryErrors += 7;
16283
16349
  } else {
16284
16350
  if (!isMandatoryString(contract["id"]))
16285
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_IdP", measurementCounter));
16351
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_IdP", measurementCounter)));
16286
16352
  if (!isMandatoryString(contract["type"]))
16287
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TypeP", measurementCounter));
16353
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TypeP", measurementCounter)));
16288
16354
  if (!isMandatoryNumber(contract["timestamp"]))
16289
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampP", measurementCounter));
16355
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampP", measurementCounter)));
16290
16356
  const timestampLocal = contract["timestampLocal"];
16291
16357
  if (!isMandatoryJSONObject(timestampLocal)) {
16292
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampLocalP", measurementCounter));
16358
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampLocalP", measurementCounter)));
16293
16359
  secondaryErrors += 3;
16294
16360
  } else {
16295
16361
  if (!isMandatoryNumber(timestampLocal["timestamp"]))
16296
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampLocal_TimestampP", measurementCounter));
16362
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampLocal_TimestampP", measurementCounter)));
16297
16363
  if (!isMandatoryNumber(timestampLocal["localOffset"]))
16298
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampLocal_LocalOffsetP", measurementCounter));
16364
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampLocal_LocalOffsetP", measurementCounter)));
16299
16365
  if (!isMandatoryNumber(timestampLocal["seasonOffset"]))
16300
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampLocal_SeasonOffsetP", measurementCounter));
16366
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Contract_TimestampLocal_SeasonOffsetP", measurementCounter)));
16301
16367
  }
16302
16368
  }
16303
16369
  const measuredValue = signedMeterValue["measuredValue"];
16304
16370
  if (!isMandatoryJSONObject(measuredValue)) {
16305
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValueP", measurementCounter));
16371
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValueP", measurementCounter)));
16306
16372
  secondaryErrors += 9;
16307
16373
  } else {
16308
16374
  if (!isMandatoryString(measuredValue["value"]))
16309
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_ValueP", measurementCounter));
16375
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_ValueP", measurementCounter)));
16310
16376
  if (!isMandatoryString(measuredValue["unit"]))
16311
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_UnitP", measurementCounter));
16377
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_UnitP", measurementCounter)));
16312
16378
  if (!isMandatoryNumber(measuredValue["scale"]))
16313
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_ScaleP", measurementCounter));
16379
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_ScaleP", measurementCounter)));
16314
16380
  if (!isMandatoryString(measuredValue["valueType"]))
16315
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_ValueTypeP", measurementCounter));
16381
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_ValueTypeP", measurementCounter)));
16316
16382
  if (!isMandatoryNumber(measuredValue["unitEncoded"]))
16317
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_UnitEncodedP", measurementCounter));
16383
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasuredValue_UnitEncodedP", measurementCounter)));
16318
16384
  const timestampLocal = measuredValue["timestampLocal"];
16319
16385
  if (!isMandatoryJSONObject(timestampLocal)) {
16320
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalidMeasuredValueTimestampLocalP", measurementCounter));
16386
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalidMeasuredValueTimestampLocalP", measurementCounter)));
16321
16387
  secondaryErrors += 3;
16322
16388
  } else {
16323
16389
  if (!isMandatoryNumber(timestampLocal["timestamp"]))
16324
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalidMeasuredValueTimestampLocalTimestampP", measurementCounter));
16390
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalidMeasuredValueTimestampLocalTimestampP", measurementCounter)));
16325
16391
  if (!isMandatoryNumber(timestampLocal["localOffset"]))
16326
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalidMeasuredValueTimestampLocalOffsetP", measurementCounter));
16392
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalidMeasuredValueTimestampLocalOffsetP", measurementCounter)));
16327
16393
  if (!isMandatoryNumber(timestampLocal["seasonOffset"]))
16328
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalidMeasuredValueTimestampSeasonOffsetP", measurementCounter));
16394
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalidMeasuredValueTimestampSeasonOffsetP", measurementCounter)));
16329
16395
  }
16330
16396
  }
16331
16397
  const measurand = signedMeterValue["measurand"];
16332
16398
  if (!isMandatoryJSONObject(measurand)) {
16333
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeasurandP", measurementCounter));
16399
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeasurandP", measurementCounter)));
16334
16400
  secondaryErrors += 2;
16335
16401
  } else {
16336
16402
  if (!isMandatoryString(measurand["id"]))
16337
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Measurand_IdP", measurementCounter));
16403
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Measurand_IdP", measurementCounter)));
16338
16404
  if (!isMandatoryString(measurand["name"]))
16339
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_Measurand_NameP", measurementCounter));
16405
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_Measurand_NameP", measurementCounter)));
16340
16406
  }
16341
16407
  const additionalInfo = signedMeterValue["additionalInfo"];
16342
16408
  if (!isMandatoryJSONObject(additionalInfo)) {
16343
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformationP", measurementCounter));
16409
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformationP", measurementCounter)));
16344
16410
  secondaryErrors += 4;
16345
16411
  } else {
16346
16412
  if (!isMandatoryString(additionalInfo["status"]))
16347
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformation_StatusP", measurementCounter));
16413
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformation_StatusP", measurementCounter)));
16348
16414
  const indexes = additionalInfo["indexes"];
16349
16415
  if (!isMandatoryJSONObject(indexes)) {
16350
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformation_IndexesP", measurementCounter));
16416
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformation_IndexesP", measurementCounter)));
16351
16417
  secondaryErrors += 2;
16352
16418
  } else {
16353
16419
  if (!isMandatoryNumber(indexes["timer"]))
16354
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformation_Indexes_TimerP", measurementCounter));
16420
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformation_Indexes_TimerP", measurementCounter)));
16355
16421
  if (!isMandatoryString(indexes["logBook"]))
16356
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformation_Indexes_LogBookP", measurementCounter));
16422
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_AdditionalInformation_Indexes_LogBookP", measurementCounter)));
16357
16423
  }
16358
16424
  }
16359
16425
  const chargePoint = signedMeterValue["chargePoint"];
16360
- if (!isMandatoryJSONObject(chargePoint)) {
16361
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_ChargePointInformationP", measurementCounter));
16426
+ if (chargePoint !== void 0 && !isMandatoryJSONObject(chargePoint)) {
16427
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_ChargePointInformationP", measurementCounter)));
16362
16428
  secondaryErrors += 1;
16363
- } else {
16429
+ } else if (isMandatoryJSONObject(chargePoint)) {
16364
16430
  if (!isMandatoryString(chargePoint["softwareVersion"]))
16365
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_ChargePointInformation_SoftwareVersionP", measurementCounter));
16431
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_ChargePointInformation_SoftwareVersionP", measurementCounter)));
16366
16432
  }
16367
16433
  }
16368
16434
  }
@@ -16508,19 +16574,17 @@ var ChargeIT = class {
16508
16574
  }
16509
16575
  );
16510
16576
  }
16511
- if (containerFormat === oldChargeITContainerFormat) {
16512
- if (asJSONObject(signedMeterValues[0])?.["format"] == "ALFEN")
16513
- return new Alfen(this.chargy).TryToParseALFENFormat(
16514
- signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
16515
- {
16516
- EVSEId: evseId,
16517
- chargingStation: {
16518
- geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
16519
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
16520
- }
16577
+ if (asJSONObject(signedMeterValues[0])?.["format"] == "ALFEN")
16578
+ return new Alfen(this.chargy).TryToParseALFENFormat(
16579
+ signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
16580
+ {
16581
+ EVSEId: evseId,
16582
+ chargingStation: {
16583
+ geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
16584
+ address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
16521
16585
  }
16522
- );
16523
- }
16586
+ }
16587
+ );
16524
16588
  if (signedMeterValueContext === oldChargeITMeterValueFormat)
16525
16589
  return this.TryToParseOldChargeITMeterValuesFormat(
16526
16590
  CTR,
@@ -16540,7 +16604,7 @@ var ChargeIT = class {
16540
16604
  } catch (exception) {
16541
16605
  return {
16542
16606
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
16543
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
16607
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
16544
16608
  errors,
16545
16609
  warnings,
16546
16610
  certainty: (numberOfFormatChecks - errors.length - secondaryErrors) / numberOfFormatChecks
@@ -16613,142 +16677,140 @@ var ChargeIT = class {
16613
16677
  const totalCosts_flat_cost = totalCosts_flat?.["cost"];
16614
16678
  const signedMeterValues = SomeJSON["signedMeterValues"];
16615
16679
  if (!isMandatoryString(chargingSessionId))
16616
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid charge transparency record identification!"));
16680
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid charge transparency record identification!")));
16617
16681
  if (!isMandatoryJSONObject(chargePointInfo)) {
16618
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidChargePointInfo"));
16682
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidChargePointInfo")));
16619
16683
  secondaryErrors += 19;
16620
16684
  } else {
16621
16685
  if (!isMandatoryString(evseId))
16622
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidEVSEIdentification"));
16686
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidEVSEIdentification")));
16623
16687
  if (!isMandatoryJSONObject(placeInfo)) {
16624
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidPlaceInfo"));
16688
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidPlaceInfo")));
16625
16689
  secondaryErrors += 8;
16626
16690
  } else {
16627
16691
  if (!isMandatoryJSONObject(geoLocation)) {
16628
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocation"));
16692
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocation")));
16629
16693
  secondaryErrors += 2;
16630
16694
  } else {
16631
16695
  if (!isMandatoryNumber(geoLocation_lat))
16632
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocationLatitude"));
16696
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocationLatitude")));
16633
16697
  if (!isMandatoryNumber(geoLocation_lon))
16634
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidGeoLocationLongitude"));
16698
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidGeoLocationLongitude")));
16635
16699
  }
16636
16700
  if (!isMandatoryJSONObject(address)) {
16637
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddress"));
16701
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddress")));
16638
16702
  secondaryErrors += 4;
16639
16703
  } else {
16640
16704
  if (!isMandatoryString(address_street))
16641
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressStreetName"));
16705
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressStreetName")));
16642
16706
  if (!isMandatoryString(address_zipCode))
16643
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressZIPCode"));
16707
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressZIPCode")));
16644
16708
  if (!isMandatoryString(address_town))
16645
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressCityName"));
16709
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressCityName")));
16646
16710
  if (!isMandatoryString(address_country))
16647
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidAddressCountryName"));
16711
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidAddressCountryName")));
16648
16712
  }
16649
16713
  }
16650
16714
  }
16651
16715
  if (!isMandatoryJSONObject(chargingStationInfo)) {
16652
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidChargingStationInfo"));
16716
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidChargingStationInfo")));
16653
16717
  secondaryErrors += 5;
16654
16718
  } else {
16655
16719
  if (!isOptionalString(chargingStation_manufacturer))
16656
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station manufacturer!"));
16720
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station manufacturer!")));
16657
16721
  if (!isOptionalString(chargingStation_type))
16658
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station type!"));
16722
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station type!")));
16659
16723
  if (!isOptionalString(chargingStation_serialNumber))
16660
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station serial number!"));
16724
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station serial number!")));
16661
16725
  if (!isOptionalString(chargingStation_controllerSoftwareVersion))
16662
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station controller software version!"));
16726
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station controller software version!")));
16663
16727
  if (!isOptionalString(chargingStation_compliance))
16664
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station compliance!"));
16728
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station compliance!")));
16665
16729
  if (!isOptionalURL(chargingStation_complianceURL))
16666
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station compliance URL!"));
16730
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station compliance URL!")));
16667
16731
  if (!isOptionalString(chargingStation_conformity))
16668
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station conformity!"));
16732
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station conformity!")));
16669
16733
  if (!isOptionalURL(chargingStation_conformity_URL))
16670
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station conformity URL!"));
16734
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station conformity URL!")));
16671
16735
  if (!isOptionalURL(chargingStation_conformity_certificateId))
16672
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station conformity certificate identification!"));
16736
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station conformity certificate identification!")));
16673
16737
  if (!isOptionalString(chargingStation_calibration))
16674
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station calibration!"));
16738
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station calibration!")));
16675
16739
  if (!isOptionalURL(chargingStation_calibration_URL))
16676
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station calibration URL!"));
16740
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station calibration URL!")));
16677
16741
  if (!isOptionalURL(chargingStation_calibration_certificateId))
16678
- errors.push(this.chargy.GetLocalizedMessage("Invalid charging station calibration certificate identification!"));
16742
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Invalid charging station calibration certificate identification!")));
16679
16743
  }
16680
16744
  if (meterInfo) {
16681
16745
  if (!isOptionalString(meterInfo_meterId))
16682
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1));
16746
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1)));
16683
16747
  if (!isOptionalString(meterInfo_manufacturer))
16684
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
16748
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
16685
16749
  if (!isOptionalString(meterInfo_manufacturerURL))
16686
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
16750
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
16687
16751
  if (!isOptionalString(meterInfo_model))
16688
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
16752
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
16689
16753
  if (!isOptionalString(meterInfo_modelURL))
16690
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1));
16754
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_ManufacturerP", 1)));
16691
16755
  if (!isOptionalString(meterInfo_firmwareVersion))
16692
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1));
16756
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1)));
16693
16757
  if (!isOptionalString(meterInfo_hardwareVersion))
16694
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1));
16758
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_FirmwareVersionP", 1)));
16695
16759
  if (!isOptionalString(meterInfo_publicKey))
16696
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
16760
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
16697
16761
  if (!isOptionalString(meterInfo_publicKeyFormat))
16698
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
16762
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
16699
16763
  if (!isOptionalString(meterInfo_publicKeyEncoding))
16700
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
16764
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
16701
16765
  if (!isOptionalString(meterInfo_signatureFormat))
16702
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
16766
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
16703
16767
  if (!isOptionalString(meterInfo_signatureEncoding))
16704
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1));
16768
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_PublicKeyP", 1)));
16705
16769
  }
16706
16770
  if (connectorInfo) {
16707
16771
  if (!isOptionalString(connectorInfo_type))
16708
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1));
16772
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1)));
16709
16773
  if (!isOptionalString(connectorInfo_losses))
16710
- errors.push(this.chargy.GetLocalizedMessageWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1));
16774
+ errors.push(CreateError(this.chargy.GetMultilanguageTextWithParameter("MissingOrInvalid_SignedMeterValue_MeterInfo_MeterIdP", 1)));
16711
16775
  }
16712
16776
  if (isMandatoryJSONArray(chargingTariffs)) {
16713
- for (let i = 0; i < chargingTariffs.length; i++) {
16714
- }
16715
16777
  }
16716
16778
  if (totalCosts) {
16717
16779
  if (!isMandatoryNumber(totalCosts_total))
16718
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid total costs within the charging costs!"));
16780
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid total costs within the charging costs!")));
16719
16781
  if (!isMandatoryString(totalCosts_currency))
16720
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid currency within the charging costs!"));
16782
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid currency within the charging costs!")));
16721
16783
  if (totalCosts_reservation) {
16722
16784
  if (!isMandatoryNumber(totalCosts_reservation_cost))
16723
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid reservation cost within the charging costs!"));
16785
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid reservation cost within the charging costs!")));
16724
16786
  if (!isMandatoryString(totalCosts_reservation_unit))
16725
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid reservation unit within the charging costs!"));
16787
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid reservation unit within the charging costs!")));
16726
16788
  }
16727
16789
  if (totalCosts_energy) {
16728
16790
  if (!isMandatoryNumber(totalCosts_energy_cost))
16729
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid energy cost within the charging costs!"));
16791
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid energy cost within the charging costs!")));
16730
16792
  if (!isMandatoryString(totalCosts_energy_unit))
16731
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid energy unit within the charging costs!"));
16793
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid energy unit within the charging costs!")));
16732
16794
  }
16733
16795
  if (totalCosts_time) {
16734
16796
  if (!isMandatoryNumber(totalCosts_time_cost))
16735
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid time cost within the charging costs!"));
16797
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid time cost within the charging costs!")));
16736
16798
  if (!isMandatoryString(totalCosts_time_unit))
16737
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid time unit within the charging costs!"));
16799
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid time unit within the charging costs!")));
16738
16800
  }
16739
16801
  if (totalCosts_idle) {
16740
16802
  if (!isMandatoryNumber(totalCosts_idle_cost))
16741
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid idle cost within the charging costs!"));
16803
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid idle cost within the charging costs!")));
16742
16804
  if (!isMandatoryString(totalCosts_idle_unit))
16743
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid idle unit within the charging costs!"));
16805
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid idle unit within the charging costs!")));
16744
16806
  }
16745
16807
  if (totalCosts_flat) {
16746
16808
  if (!isMandatoryNumber(totalCosts_flat_cost))
16747
- errors.push(this.chargy.GetLocalizedMessage("Missing or invalid flat cost within the charging costs!"));
16809
+ errors.push(CreateError(this.chargy.GetMultilanguageText("Missing or invalid flat cost within the charging costs!")));
16748
16810
  }
16749
16811
  }
16750
16812
  if (!isMandatoryJSONArray(signedMeterValues) || signedMeterValues.length < 2) {
16751
- errors.push(this.chargy.GetLocalizedMessage("MissingOrInvalidSignedMeterValues"));
16813
+ errors.push(CreateError(this.chargy.GetMultilanguageText("MissingOrInvalidSignedMeterValues")));
16752
16814
  secondaryErrors += 2 * 39;
16753
16815
  } else {
16754
16816
  const firstSMV = asJSONObject(signedMeterValues[0]);
@@ -16758,7 +16820,7 @@ var ChargeIT = class {
16758
16820
  const context = asString(currentSMV?.["@context"])?.trim() ?? asString(currentSMV?.["format"])?.trim() ?? null;
16759
16821
  if (smvContext !== context) return {
16760
16822
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
16761
- message: "Inconsistent signed meter value format!",
16823
+ message: this.chargy.GetMultilanguageText("Inconsistent signed meter value format!"),
16762
16824
  certainty: 1
16763
16825
  };
16764
16826
  }
@@ -16864,9 +16926,9 @@ var ChargeIT = class {
16864
16926
  ],
16865
16927
  certainty: 0
16866
16928
  };
16867
- if (smvContext?.startsWith("https://www.chargeit-mobility.com/contexts/bsm-ws36a-json"))
16929
+ if (smvContext?.startsWith("https://www.chargeit-mobility.com/contexts/bsm-ws36a-json") === true)
16868
16930
  return new BSMCrypt01(this.chargy).tryToParseBSM_WS36aMeasurements(CTR, evseIdStr, asString(chargingStation_controllerSoftwareVersion) ?? null, signedMeterValues);
16869
- if (smvContext?.startsWith("ALFEN"))
16931
+ if (smvContext?.startsWith("ALFEN") === true)
16870
16932
  return new Alfen(this.chargy).TryToParseALFENFormat(
16871
16933
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
16872
16934
  {
@@ -16907,7 +16969,7 @@ var ChargeIT = class {
16907
16969
  } catch (exception) {
16908
16970
  return {
16909
16971
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
16910
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
16972
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
16911
16973
  errors,
16912
16974
  warnings,
16913
16975
  certainty: (numberOfFormatChecks - errors.length - secondaryErrors) / numberOfFormatChecks
@@ -16916,7 +16978,7 @@ var ChargeIT = class {
16916
16978
  }
16917
16979
  return {
16918
16980
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
16919
- message: "No chargeIT charge transparency record",
16981
+ message: this.chargy.GetMultilanguageText("No chargeIT charge transparency record"),
16920
16982
  errors,
16921
16983
  warnings,
16922
16984
  certainty: 0
@@ -16935,7 +16997,7 @@ var ChargePoint = class {
16935
16997
  if (!isMandatoryJSONObject(SomeJSON))
16936
16998
  return {
16937
16999
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
16938
- message: this.chargy.GetLocalizedMessage("UnknownOrInvalidChargingSessionFormat"),
17000
+ message: this.chargy.GetMultilanguageText("UnknownOrInvalidChargingSessionFormat"),
16939
17001
  certainty: 0
16940
17002
  };
16941
17003
  if (SomeJSON["company_name"] !== void 0 && SomeJSON["display_unit"] !== void 0 && //SomeJSON["energy"] !== undefined &&
@@ -16969,10 +17031,8 @@ var ChargePoint = class {
16969
17031
  if (startTimeUTC !== void 0 && (parkingEnd === void 0 || startTimeUTC > parkingEnd))
16970
17032
  parkingEnd = endTimeUTC;
16971
17033
  }
16972
- if (chargingStart === void 0)
16973
- chargingStart = parkingStart;
16974
- if (chargingEnd === void 0)
16975
- chargingEnd = parkingEnd;
17034
+ chargingStart ??= parkingStart;
17035
+ chargingEnd ??= parkingEnd;
16976
17036
  let sessionStart = parkingStart !== void 0 && (chargingStart === void 0 || parkingStart < chargingStart) ? parkingStart : chargingStart;
16977
17037
  if (sessionStart === void 0 && parkingStart !== void 0)
16978
17038
  sessionStart = parkingStart;
@@ -17121,7 +17181,7 @@ var ChargePoint = class {
17121
17181
  "status": "Unvalidated" /* Unvalidated */
17122
17182
  };
17123
17183
  if (parking && parking.length > 0 && CTR.chargingSessions && CTR.chargingSessions.length > 0) {
17124
- const chargingSession = CTR.chargingSessions[0];
17184
+ const chargingSession = getFirstArrayElement(CTR.chargingSessions, "Missing ChargePoint charging session");
17125
17185
  chargingSession.parking = [];
17126
17186
  for (const parkingItem of parking) {
17127
17187
  const parkingObj = asJSONObject(parkingItem);
@@ -17258,13 +17318,13 @@ var ChargePoint = class {
17258
17318
  } catch (exception) {
17259
17319
  return {
17260
17320
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
17261
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
17321
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
17262
17322
  certainty: 0
17263
17323
  };
17264
17324
  }
17265
17325
  return {
17266
17326
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
17267
- message: this.chargy.GetLocalizedMessage("UnknownOrInvalidChargingSessionFormat"),
17327
+ message: this.chargy.GetMultilanguageText("UnknownOrInvalidChargingSessionFormat"),
17268
17328
  certainty: 0
17269
17329
  };
17270
17330
  }
@@ -17287,7 +17347,7 @@ var ChargePointCrypt01 = class extends ACrypt {
17287
17347
  if (chargingSession.ctr === void 0) {
17288
17348
  return {
17289
17349
  status: "InvalidSignature" /* InvalidSignature */,
17290
- message: this.chargy.GetLocalizedMessage("InvalidSignature"),
17350
+ message: this.chargy.GetMultilanguageText("InvalidSignature"),
17291
17351
  certainty: 0
17292
17352
  };
17293
17353
  }
@@ -17323,7 +17383,7 @@ var ChargePointCrypt01 = class extends ACrypt {
17323
17383
  if (publicKeys.length == 0)
17324
17384
  return {
17325
17385
  status: "PublicKeyNotFound" /* PublicKeyNotFound */,
17326
- message: this.chargy.GetLocalizedMessage("Public key notFound"),
17386
+ message: this.chargy.GetMultilanguageText("Public key notFound"),
17327
17387
  certainty: 0
17328
17388
  };
17329
17389
  if (plainText !== "" && chargingSession.signature != null && chargingSession.signature !== "") {
@@ -17398,7 +17458,7 @@ var ChargePointCrypt01 = class extends ACrypt {
17398
17458
  if (measurementValue.result?.status !== "ValidSignature" /* ValidSignature */ && measurementValue.result?.status !== "NoOperation" /* NoOperation */) {
17399
17459
  return {
17400
17460
  status: "InvalidSignature" /* InvalidSignature */,
17401
- message: this.chargy.GetLocalizedMessage("InvalidSignature"),
17461
+ message: this.chargy.GetMultilanguageText("InvalidSignature"),
17402
17462
  certainty: 0
17403
17463
  };
17404
17464
  }
@@ -17417,6 +17477,8 @@ var ChargePointCrypt01 = class extends ACrypt {
17417
17477
  case "InvalidSignature" /* InvalidSignature */:
17418
17478
  currentResult.status = "InvalidStartValue" /* InvalidStartValue */;
17419
17479
  break;
17480
+ default:
17481
+ break;
17420
17482
  }
17421
17483
  } else if (i == measurement.values.length - 1) {
17422
17484
  switch (currentResult.status) {
@@ -17429,6 +17491,8 @@ var ChargePointCrypt01 = class extends ACrypt {
17429
17491
  case "InvalidSignature" /* InvalidSignature */:
17430
17492
  currentResult.status = "InvalidStopValue" /* InvalidStopValue */;
17431
17493
  break;
17494
+ default:
17495
+ break;
17432
17496
  }
17433
17497
  } else {
17434
17498
  switch (currentResult.status) {
@@ -17441,6 +17505,8 @@ var ChargePointCrypt01 = class extends ACrypt {
17441
17505
  case "InvalidSignature" /* InvalidSignature */:
17442
17506
  currentResult.status = "InvalidStopValue" /* InvalidStopValue */;
17443
17507
  break;
17508
+ default:
17509
+ break;
17444
17510
  }
17445
17511
  }
17446
17512
  }
@@ -17455,7 +17521,7 @@ var ChargePointCrypt01 = class extends ACrypt {
17455
17521
  } catch (exception) {
17456
17522
  return {
17457
17523
  status: "InvalidSignature" /* InvalidSignature */,
17458
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
17524
+ message: this.chargy.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
17459
17525
  certainty: 0
17460
17526
  };
17461
17527
  }
@@ -17470,9 +17536,9 @@ var ChargePointCrypt01 = class extends ACrypt {
17470
17536
  const cryptoResult = {
17471
17537
  status: "NoOperation" /* NoOperation */
17472
17538
  };
17473
- return await Promise.resolve(setResult("NoOperation" /* NoOperation */));
17539
+ return Promise.resolve(setResult("NoOperation" /* NoOperation */));
17474
17540
  }
17475
- async ViewMeasurement(measurementValue, errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
17541
+ async ViewMeasurement(measurementValue, _errorDiv, introDiv, _infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
17476
17542
  if (measurementValue.measurement?.chargingSession === void 0)
17477
17543
  return new Error("Invalid measurement!");
17478
17544
  const chargingSession = measurementValue.measurement.chargingSession;
@@ -17480,8 +17546,8 @@ var ChargePointCrypt01 = class extends ACrypt {
17480
17546
  const algorithmName = typeof chargingSession.publicKey?.algorithm === "object" ? chargingSession.publicKey.algorithm.name : chargingSession.publicKey?.algorithm ?? "";
17481
17547
  const algorithmType = typeof chargingSession.publicKey?.type === "object" ? chargingSession.publicKey.type.name : chargingSession.publicKey?.type;
17482
17548
  introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "ChargePointCrypt01").replace("{cryptoAlgorithm}", algorithmName);
17483
- if (PlainTextDiv.parentElement != void 0 && PlainTextDiv.parentElement.children[0] != void 0) {
17484
- PlainTextDiv.parentElement.children[0].innerHTML = "Plain text (secrrct)";
17549
+ if (PlainTextDiv.parentElement) {
17550
+ getArrayLikeElement(PlainTextDiv.parentElement.children, 0, "Missing plain text header").innerHTML = "Plain text (secrrct)";
17485
17551
  }
17486
17552
  PlainTextDiv.innerText = atob(chargingSession.original ?? "");
17487
17553
  PlainTextDiv.style.fontFamily = "monospace";
@@ -17503,22 +17569,23 @@ var ChargePointCrypt01 = class extends ACrypt {
17503
17569
  hashInfo = "(SHA512, 512 Bits, hex)";
17504
17570
  break;
17505
17571
  }
17506
- if (HashedPlainTextDiv.parentElement != void 0 && HashedPlainTextDiv.parentElement.children[0] != void 0) {
17507
- HashedPlainTextDiv.parentElement.children[0].innerHTML = "Hashed plain text " + hashInfo;
17572
+ if (HashedPlainTextDiv.parentElement) {
17573
+ getArrayLikeElement(HashedPlainTextDiv.parentElement.children, 0, "Missing hashed plain text header").innerHTML = "Hashed plain text " + hashInfo;
17508
17574
  }
17509
17575
  HashedPlainTextDiv.innerHTML = chargingSession.hashValue?.match(/.{1,8}/g)?.join(" ") ?? "0x00000000000000000000000000000000000";
17510
17576
  if (chargingSession.publicKey != null) {
17511
- if (PublicKeyDiv.parentElement != void 0 && PublicKeyDiv.parentElement.children[0] != void 0) {
17512
- PublicKeyDiv.parentElement.children[0].innerHTML = "Public Key (" + (algorithmType ? algorithmType + ", " : "") + (algorithmName ? algorithmName + ", " : "") + "hex)";
17577
+ if (PublicKeyDiv.parentElement) {
17578
+ getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = "Public Key (" + (algorithmType != null && algorithmType.length > 0 ? algorithmType + ", " : "") + (algorithmName.length > 0 ? algorithmName + ", " : "") + "hex)";
17513
17579
  }
17514
17580
  PublicKeyDiv.innerHTML = chargingSession.publicKey.value.startsWith("04") ? '<span class="leadingFour">04</span> ' + (chargingSession.publicKey.value.substring(2).match(/.{1,8}/g)?.join(" ") ?? "") : chargingSession.publicKey.value.match(/.{1,8}/g)?.join(" ") ?? "";
17515
- if (PublicKeyDiv.parentElement != void 0 && PublicKeyDiv.parentElement.children[3] != void 0) {
17516
- PublicKeyDiv.parentElement.children[3].innerHTML = "";
17581
+ const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
17582
+ if (publicKeySignatureContainer !== void 0) {
17583
+ publicKeySignatureContainer.innerHTML = "";
17517
17584
  }
17518
17585
  if (result.publicKeySignatures) {
17519
17586
  for (const signature of result.publicKeySignatures) {
17520
17587
  try {
17521
- const signatureDiv = PublicKeyDiv.parentElement?.children[3]?.appendChild(document.createElement("div"));
17588
+ const signatureDiv = publicKeySignatureContainer?.appendChild(document.createElement("div"));
17522
17589
  if (signatureDiv != null)
17523
17590
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
17524
17591
  measurementValue.measurement.chargingSession.chargingStation,
@@ -17533,8 +17600,8 @@ var ChargePointCrypt01 = class extends ACrypt {
17533
17600
  }
17534
17601
  }
17535
17602
  if (chargingSession.signature != null) {
17536
- if (SignatureExpectedDiv.parentElement != void 0 && SignatureExpectedDiv.parentElement.children[0] != void 0) {
17537
- SignatureExpectedDiv.parentElement.children[0].innerHTML = "Erwartete Signatur (secrrct.sign, rs, hex)";
17603
+ if (SignatureExpectedDiv.parentElement) {
17604
+ getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (secrrct.sign, rs, hex)";
17538
17605
  }
17539
17606
  if (typeof chargingSession.signature != "string")
17540
17607
  SignatureExpectedDiv.innerHTML = "r: " + (chargingSession.signature.r?.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (chargingSession.signature.s?.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "");
@@ -17566,6 +17633,7 @@ var ChargePointCrypt01 = class extends ACrypt {
17566
17633
  break;
17567
17634
  }
17568
17635
  }
17636
+ return void 0;
17569
17637
  }
17570
17638
  };
17571
17639
 
@@ -17589,8 +17657,7 @@ function IsAChargeTransparencyRecord(data) {
17589
17657
  function IsASessionCryptoResult(data) {
17590
17658
  if (!isMandatoryJSONObject(data))
17591
17659
  return false;
17592
- const sessionCryptoResult = data;
17593
- return sessionCryptoResult.status !== void 0;
17660
+ return true;
17594
17661
  }
17595
17662
  function CloneCTR(CTR) {
17596
17663
  const clonedCTR = JSON.parse(JSON.stringify(CTR));
@@ -17769,8 +17836,10 @@ async function imageDataFromNodeCanvas(data) {
17769
17836
  if (!isCanvasModule(canvasLib))
17770
17837
  return void 0;
17771
17838
  const image = await canvasLib.loadImage(import_buffer.Buffer.from(toUint8Array(data)));
17772
- const width = image.naturalWidth || image.width;
17773
- const height = image.naturalHeight || image.height;
17839
+ const naturalWidth = image.naturalWidth ?? 0;
17840
+ const naturalHeight = image.naturalHeight ?? 0;
17841
+ const width = naturalWidth > 0 ? naturalWidth : image.width;
17842
+ const height = naturalHeight > 0 ? naturalHeight : image.height;
17774
17843
  if (width <= 0 || height <= 0)
17775
17844
  return void 0;
17776
17845
  const canvas = canvasLib.createCanvas(width, height);
@@ -17841,22 +17910,22 @@ async function importOptionalNodeModule(moduleName) {
17841
17910
  }
17842
17911
  async function readQRCodeTextFromImage(data, mimeType) {
17843
17912
  const imageDataSources = typeof document === "undefined" ? [
17844
- () => imageDataFromNodeCanvas(data),
17845
- () => imageDataFromPNGOrJPEG(data, mimeType),
17846
- () => imageDataFromBrowserCanvas(data, mimeType),
17847
- () => imageDataFromBrowserImageElement(data, mimeType)
17913
+ async () => imageDataFromNodeCanvas(data),
17914
+ async () => imageDataFromPNGOrJPEG(data, mimeType),
17915
+ async () => imageDataFromBrowserCanvas(data, mimeType),
17916
+ async () => imageDataFromBrowserImageElement(data, mimeType)
17848
17917
  ] : [
17849
- () => imageDataFromBrowserCanvas(data, mimeType),
17850
- () => imageDataFromBrowserImageElement(data, mimeType),
17851
- () => imageDataFromNodeCanvas(data),
17852
- () => imageDataFromPNGOrJPEG(data, mimeType)
17918
+ async () => imageDataFromBrowserCanvas(data, mimeType),
17919
+ async () => imageDataFromBrowserImageElement(data, mimeType),
17920
+ async () => imageDataFromNodeCanvas(data),
17921
+ async () => imageDataFromPNGOrJPEG(data, mimeType)
17853
17922
  ];
17854
17923
  for (const imageDataSource of imageDataSources) {
17855
17924
  const imageData = await imageDataSource();
17856
17925
  if (imageData == null)
17857
17926
  continue;
17858
17927
  const qrText = readQRCodeTextFromImageData(imageData);
17859
- if (qrText && qrText.length > 0)
17928
+ if (qrText != null && qrText.length > 0)
17860
17929
  return qrText;
17861
17930
  }
17862
17931
  return void 0;
@@ -17869,7 +17938,7 @@ function readQRCodeTextFromImageData(imageData) {
17869
17938
  { inversionAttempts: "attemptBoth" }
17870
17939
  );
17871
17940
  const qrText = qrCode?.data.trim();
17872
- return qrText && qrText.length > 0 ? qrText : void 0;
17941
+ return qrText != null && qrText.length > 0 ? qrText : void 0;
17873
17942
  }
17874
17943
 
17875
17944
  // src/pdfjs/browser.ts
@@ -17890,10 +17959,15 @@ var validationRules_default = {
17890
17959
  }
17891
17960
  }
17892
17961
  };
17962
+ function isPdfAttachment(value) {
17963
+ if (!isMandatoryJSONObject(value))
17964
+ return false;
17965
+ return typeof value["filename"] === "string" && (value["content"] instanceof ArrayBuffer || ArrayBuffer.isView(value["content"]));
17966
+ }
17893
17967
  var Chargy = class {
17894
17968
  //#region Data
17895
17969
  i18n;
17896
- UILanguage;
17970
+ uiLanguages;
17897
17971
  elliptic;
17898
17972
  moment;
17899
17973
  asn1;
@@ -17906,14 +17980,12 @@ var Chargy = class {
17906
17980
  EVSEs = new Array();
17907
17981
  meters = new Array();
17908
17982
  chargingSessions = new Array();
17909
- eMobilityProviders = new Array();
17910
- mediationServices = new Array();
17911
17983
  currentCTR = {};
17912
17984
  internalCTR = {};
17913
17985
  //#endregion
17914
- constructor(i18n, UILanguage, elliptic, moment2, asn1, base32Decode, ShowPKIDetails, validationRules = validationRules_default) {
17986
+ constructor(i18n, UILanguages, elliptic, moment2, asn1, base32Decode, ShowPKIDetails, validationRules = validationRules_default) {
17915
17987
  this.i18n = i18n;
17916
- this.UILanguage = UILanguage;
17988
+ this.uiLanguages = this.NormalizeUILanguages(UILanguages);
17917
17989
  this.elliptic = elliptic;
17918
17990
  this.moment = moment2;
17919
17991
  this.asn1 = asn1;
@@ -17921,11 +17993,41 @@ var Chargy = class {
17921
17993
  this.showPKIDetails = ShowPKIDetails;
17922
17994
  this.validationRules = validationRules;
17923
17995
  }
17924
- SetUILanguage(UILanguage) {
17925
- this.UILanguage = UILanguage;
17996
+ SetUILanguages(UILanguages) {
17997
+ this.uiLanguages = this.NormalizeUILanguages(UILanguages);
17998
+ }
17999
+ NormalizeUILanguages(UILanguages) {
18000
+ const languages = new Array();
18001
+ for (const language of UILanguages) {
18002
+ const normalized = language.trim();
18003
+ if (normalized.length > 0 && !languages.includes(normalized)) {
18004
+ languages.push(normalized);
18005
+ }
18006
+ }
18007
+ return languages.length > 0 ? languages : ["en"];
18008
+ }
18009
+ FindBestMultilanguageText(Text) {
18010
+ for (const language of this.uiLanguages) {
18011
+ const localLanguage = Text[language];
18012
+ if (localLanguage !== void 0)
18013
+ return localLanguage;
18014
+ }
18015
+ const english = Text["en"];
18016
+ if (english !== void 0)
18017
+ return english;
18018
+ return Object.values(Text).find((value) => value !== void 0);
18019
+ }
18020
+ CompleteMultilanguageText(Text, fallbackText) {
18021
+ const result = {
18022
+ ...Text ?? {}
18023
+ };
18024
+ const fallback = this.FindBestMultilanguageText(result) ?? fallbackText;
18025
+ for (const language of this.uiLanguages)
18026
+ result[language] ??= fallback;
18027
+ return result;
17926
18028
  }
17927
18029
  PublicKeyIdFromFileName(fileName) {
17928
- return (fileName.indexOf(".") > -1 ? fileName.substring(0, fileName.indexOf(".")) : fileName).replace(/[-_]?public[-_]?key/i, "");
18030
+ return (fileName.includes(".") ? fileName.substring(0, fileName.indexOf(".")) : fileName).replace(/[-_]?public[-_]?key/i, "");
17929
18031
  }
17930
18032
  TryToParseDERPublicKey(keyId, publicKeyBuffer) {
17931
18033
  const ASN1_OIDs = this.asn1.define("OIDs", function() {
@@ -18101,27 +18203,36 @@ var Chargy = class {
18101
18203
  GetLocalizedMessage(Text) {
18102
18204
  const multiLanguage = this.i18n[Text];
18103
18205
  if (multiLanguage !== void 0) {
18104
- const localLanguage = multiLanguage[this.UILanguage];
18105
- if (localLanguage !== void 0)
18106
- return localLanguage;
18107
- const english = multiLanguage["en"];
18108
- if (english !== void 0)
18109
- return english;
18206
+ const localizedMessage = this.FindBestMultilanguageText(multiLanguage);
18207
+ if (localizedMessage !== void 0)
18208
+ return localizedMessage;
18110
18209
  }
18111
18210
  return Text;
18112
18211
  }
18212
+ GetMultilanguageText(Text) {
18213
+ const multiLanguage = this.i18n[Text];
18214
+ return this.CompleteMultilanguageText(multiLanguage, Text);
18215
+ }
18113
18216
  GetLocalizedMessageWithParameter(Text, Parameter) {
18114
18217
  const multiLanguage = this.i18n[Text];
18115
18218
  if (multiLanguage !== void 0) {
18116
- const localLanguage = multiLanguage[this.UILanguage];
18117
- if (localLanguage !== void 0)
18118
- return localLanguage.replace("%p", String(Parameter));
18119
- const english = multiLanguage["en"];
18120
- if (english !== void 0)
18121
- return english.replace("%p", String(Parameter));
18219
+ const localizedMessage = this.FindBestMultilanguageText(multiLanguage);
18220
+ if (localizedMessage !== void 0)
18221
+ return localizedMessage.replace("%p", String(Parameter));
18122
18222
  }
18123
18223
  return Text.replace("%p", String(Parameter));
18124
18224
  }
18225
+ GetMultilanguageTextWithParameter(Text, Parameter) {
18226
+ const multiLanguage = this.i18n[Text];
18227
+ const parameterizedText = {};
18228
+ if (multiLanguage !== void 0) {
18229
+ for (const [language, message] of Object.entries(multiLanguage)) {
18230
+ if (message !== void 0)
18231
+ parameterizedText[language] = message.replace("%p", String(Parameter));
18232
+ }
18233
+ }
18234
+ return this.CompleteMultilanguageText(parameterizedText, Text.replace("%p", String(Parameter)));
18235
+ }
18125
18236
  //#endregion
18126
18237
  //#region GetDevices...
18127
18238
  GetChargingPool = (Id) => {
@@ -18272,7 +18383,7 @@ var Chargy = class {
18272
18383
  if (compressedFiles.length == 0)
18273
18384
  continue;
18274
18385
  archiveFound = true;
18275
- if (compressedFiles.length == 1 && compressedFiles[0]?.path == null) {
18386
+ if (compressedFiles.length == 1) {
18276
18387
  expandedFileInfos.push({
18277
18388
  name: FileInfo.name.substring(0, FileInfo.name.lastIndexOf(".")),
18278
18389
  data: compressedFiles[0]?.data
@@ -18309,9 +18420,12 @@ var Chargy = class {
18309
18420
  }
18310
18421
  if (dataFile.length > 0 && signatureFile.length > 0) {
18311
18422
  try {
18312
- CTRfile = JSON.parse(dataFile);
18313
- CTRfile.original = btoa(dataFile);
18314
- CTRfile.signature = signatureFile;
18423
+ const parsedCTRFile = JSON.parse(dataFile);
18424
+ if (!isMandatoryJSONObject(parsedCTRFile))
18425
+ throw new Error("Invalid chargepoint 'secrrct' JSON file!");
18426
+ CTRfile = parsedCTRFile;
18427
+ CTRfile["original"] = btoa(dataFile);
18428
+ CTRfile["signature"] = signatureFile;
18315
18429
  expandedFileInfos.push({
18316
18430
  name: FileInfo.name,
18317
18431
  data: new TextEncoder().encode(JSON.stringify(CTRfile))
@@ -18354,7 +18468,7 @@ var Chargy = class {
18354
18468
  async extractArchive(fileName, data, mimeType) {
18355
18469
  const archiveData = this.toUint8Array(data);
18356
18470
  if (mimeType === "application/zip")
18357
- return await this.extractZipArchive(archiveData);
18471
+ return this.extractZipArchive(archiveData);
18358
18472
  if (mimeType === "application/x-tar")
18359
18473
  return this.extractTarArchive(archiveData);
18360
18474
  if (mimeType === "application/gzip") {
@@ -18393,7 +18507,7 @@ var Chargy = class {
18393
18507
  break;
18394
18508
  const prefix = this.readTarString(header, 345, 155);
18395
18509
  const path = prefix.length > 0 ? prefix + "/" + name : name;
18396
- const typeFlag = String.fromCharCode(header[156] ?? 0);
18510
+ const typeFlag = String.fromCharCode(getArrayElement(header, 156, "Missing tar header type flag"));
18397
18511
  const dataStart = offset + 512;
18398
18512
  const dataEnd = dataStart + size;
18399
18513
  if (dataEnd > data.byteLength)
@@ -18493,7 +18607,7 @@ var Chargy = class {
18493
18607
  async DetectAndConvertContentFormat(FileInfos) {
18494
18608
  if (FileInfos.length == 0) return {
18495
18609
  status: "NoChargeTransparencyRecordsFound" /* NoChargeTransparencyRecordsFound */,
18496
- message: this.GetLocalizedMessage("No charge transparency records found!"),
18610
+ message: this.GetMultilanguageText("No charge transparency records found!"),
18497
18611
  certainty: 0
18498
18612
  };
18499
18613
  let expandedFiles = new Array();
@@ -18502,45 +18616,48 @@ var Chargy = class {
18502
18616
  for (const fileInfo of FileInfos) {
18503
18617
  if (fileInfo.type === "application/pdf" || fileInfo.name.endsWith(".pdf")) {
18504
18618
  const pdfjsLib = await importPdfJs();
18505
- const pdfDocument = fileInfo.data ? await pdfjsLib.getDocument({ data: fileInfo.data }).promise : fileInfo.path ? await pdfjsLib.getDocument({ url: fileInfo.path }).promise : null;
18506
- if (pdfDocument) {
18619
+ const pdfDocument = fileInfo.data ? await pdfjsLib.getDocument({ data: fileInfo.data }).promise : fileInfo.path != null && fileInfo.path.length > 0 ? await pdfjsLib.getDocument({ url: fileInfo.path }).promise : null;
18620
+ if (pdfDocument !== null) {
18507
18621
  try {
18508
- const attachments = await pdfDocument.getAttachments();
18509
- Object.keys(attachments).forEach((fileName) => {
18510
- const attachment = attachments[fileName];
18511
- if (attachment.filename.endsWith(".chargy"))
18512
- expandedFiles.push({
18513
- name: attachment.filename,
18514
- path: FileInfos[0]?.path,
18515
- type: "application/chargy",
18516
- data: attachment.content,
18517
- info: "A CHARGY file extracted from a PDF/A-3 or newer attachment"
18518
- });
18519
- else if (attachment.filename.endsWith(".xml"))
18520
- expandedFiles.push({
18521
- name: attachment.filename,
18522
- path: FileInfos[0]?.path,
18523
- type: "application/xml",
18524
- data: attachment.content,
18525
- info: "A XML file extracted from a PDF/A-3 or newer attachment"
18526
- });
18527
- else if (attachment.filename.endsWith(".json"))
18528
- expandedFiles.push({
18529
- name: attachment.filename,
18530
- path: FileInfos[0]?.path,
18531
- type: "application/json",
18532
- data: attachment.content,
18533
- info: "A JSON file extracted from a PDF/A-3 or newer attachment"
18534
- });
18535
- else if (attachment.filename.endsWith(".csv"))
18536
- expandedFiles.push({
18537
- name: attachment.filename,
18538
- path: FileInfos[0]?.path,
18539
- type: "text/csv",
18540
- data: attachment.content,
18541
- info: "A CSV file extracted from a PDF/A-3 or newer attachment"
18542
- });
18543
- });
18622
+ const attachmentsUnknown = await pdfDocument.getAttachments();
18623
+ if (isMandatoryJSONObject(attachmentsUnknown))
18624
+ Object.values(attachmentsUnknown).forEach((attachmentUnknown) => {
18625
+ if (!isPdfAttachment(attachmentUnknown))
18626
+ return;
18627
+ const attachment = attachmentUnknown;
18628
+ if (attachment.filename.endsWith(".chargy"))
18629
+ expandedFiles.push({
18630
+ name: attachment.filename,
18631
+ path: FileInfos[0]?.path,
18632
+ type: "application/chargy",
18633
+ data: attachment.content,
18634
+ info: "A CHARGY file extracted from a PDF/A-3 or newer attachment"
18635
+ });
18636
+ else if (attachment.filename.endsWith(".xml"))
18637
+ expandedFiles.push({
18638
+ name: attachment.filename,
18639
+ path: FileInfos[0]?.path,
18640
+ type: "application/xml",
18641
+ data: attachment.content,
18642
+ info: "A XML file extracted from a PDF/A-3 or newer attachment"
18643
+ });
18644
+ else if (attachment.filename.endsWith(".json"))
18645
+ expandedFiles.push({
18646
+ name: attachment.filename,
18647
+ path: FileInfos[0]?.path,
18648
+ type: "application/json",
18649
+ data: attachment.content,
18650
+ info: "A JSON file extracted from a PDF/A-3 or newer attachment"
18651
+ });
18652
+ else if (attachment.filename.endsWith(".csv"))
18653
+ expandedFiles.push({
18654
+ name: attachment.filename,
18655
+ path: FileInfos[0]?.path,
18656
+ type: "text/csv",
18657
+ data: attachment.content,
18658
+ info: "A CSV file extracted from a PDF/A-3 or newer attachment"
18659
+ });
18660
+ });
18544
18661
  } catch (error) {
18545
18662
  console.error(`Error extracting PDF/A-3 attachments: ${String(error)}`);
18546
18663
  }
@@ -18586,7 +18703,7 @@ var Chargy = class {
18586
18703
  break;
18587
18704
  }
18588
18705
  processedFile.result = await new SAFEXML(this).tryToParseSAFEXML(XMLDocument);
18589
- if (processedFile.result.status && processedFile.result.status !== "Unvalidated" /* Unvalidated */ && getElementsByLocalName(XMLDocument, "chargingStation").length === 0) {
18706
+ if (processedFile.result.status != null && processedFile.result.status !== "Unvalidated" /* Unvalidated */ && getElementsByLocalName(XMLDocument, "chargingStation").length === 0) {
18590
18707
  processedFile.result = new XMLContainer(this).tryToParseXMLContainer(XMLDocument);
18591
18708
  }
18592
18709
  break;
@@ -18603,7 +18720,7 @@ var Chargy = class {
18603
18720
  } catch (exception) {
18604
18721
  processedFile.result = {
18605
18722
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
18606
- message: this.GetLocalizedMessage("UnknownOrInvalidXMLChargeTransparencyFormat"),
18723
+ message: this.GetMultilanguageText("UnknownOrInvalidXMLChargeTransparencyFormat"),
18607
18724
  exception,
18608
18725
  certainty: 0
18609
18726
  };
@@ -18643,7 +18760,7 @@ var Chargy = class {
18643
18760
  } catch (exception) {
18644
18761
  processedFile.result = {
18645
18762
  status: "InvalidPublicKey" /* InvalidPublicKey */,
18646
- message: this.GetLocalizedMessage("UnknownOrInvalidPublicKeyFormat"),
18763
+ message: this.GetMultilanguageText("UnknownOrInvalidPublicKeyFormat"),
18647
18764
  exception,
18648
18765
  certainty: 0
18649
18766
  };
@@ -18657,7 +18774,7 @@ var Chargy = class {
18657
18774
  } catch (exception) {
18658
18775
  processedFile.result = {
18659
18776
  status: "InvalidPublicKey" /* InvalidPublicKey */,
18660
- message: this.GetLocalizedMessage("UnknownOrInvalidPublicKeyFormat"),
18777
+ message: this.GetMultilanguageText("UnknownOrInvalidPublicKeyFormat"),
18661
18778
  exception,
18662
18779
  certainty: 0
18663
18780
  };
@@ -18670,8 +18787,7 @@ var Chargy = class {
18670
18787
  if (isMandatoryJSONObject(JSONContent)) {
18671
18788
  const JSONContext = JSONContent["@context"];
18672
18789
  if (IsAChargeTransparencyLiveLink(JSONContent)) {
18673
- if (JSONContent.timestamp == null)
18674
- JSONContent.timestamp = (/* @__PURE__ */ new Date()).toISOString();
18790
+ JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
18675
18791
  processedFile.result = JSONContent;
18676
18792
  } else if (isMandatoryString(JSONContext)) {
18677
18793
  if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
@@ -18706,7 +18822,7 @@ var Chargy = class {
18706
18822
  } catch (exception) {
18707
18823
  processedFile.result = {
18708
18824
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
18709
- message: this.GetLocalizedMessage("UnknownOrInvalidJSONChargeTransparencyFormat"),
18825
+ message: this.GetMultilanguageText("UnknownOrInvalidJSONChargeTransparencyFormat"),
18710
18826
  exception,
18711
18827
  certainty: 0
18712
18828
  };
@@ -18715,25 +18831,18 @@ var Chargy = class {
18715
18831
  processedFiles.push(processedFile);
18716
18832
  }
18717
18833
  if (processedFiles.length == 1) {
18718
- const processedFile = processedFiles[0];
18719
- if (processedFile) {
18720
- if (IsAChargeTransparencyRecord(processedFile.result))
18721
- return this.processChargeTransparencyRecord(processedFile.result);
18722
- if (IsAChargeTransparencyLiveLink(processedFile.result))
18723
- return processedFile.result;
18724
- if (IsAPublicKeyLookup(processedFile.result))
18725
- return {
18726
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
18727
- message: this.GetLocalizedMessage("UnknownOrInvalidChargeTransparencyRecord"),
18728
- certainty: 0
18729
- };
18834
+ const processedFile = getFirstArrayElement(processedFiles, "Missing processed file");
18835
+ if (IsAChargeTransparencyRecord(processedFile.result))
18836
+ return this.processChargeTransparencyRecord(processedFile.result);
18837
+ if (IsAChargeTransparencyLiveLink(processedFile.result))
18730
18838
  return processedFile.result;
18731
- }
18732
- return {
18733
- status: "InvalidSessionFormat" /* InvalidSessionFormat */,
18734
- message: this.GetLocalizedMessage("UnknownOrInvalidChargeTransparencyRecord"),
18735
- certainty: 0
18736
- };
18839
+ if (IsAPublicKeyLookup(processedFile.result))
18840
+ return {
18841
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
18842
+ message: this.GetMultilanguageText("UnknownOrInvalidChargeTransparencyRecord"),
18843
+ certainty: 0
18844
+ };
18845
+ return processedFile.result;
18737
18846
  } else if (processedFiles.length > 1) {
18738
18847
  const mergedCTR = {
18739
18848
  "@id": "",
@@ -18747,14 +18856,12 @@ var Chargy = class {
18747
18856
  mergedCTR["@id"] = processedFileResult["@id"];
18748
18857
  if (mergedCTR["@context"] === "")
18749
18858
  mergedCTR["@context"] = processedFileResult["@context"];
18750
- if (!mergedCTR.begin || mergedCTR.begin && processedFileResult.begin && mergedCTR.begin > processedFileResult.begin)
18859
+ if (processedFileResult.begin != null && processedFileResult.begin.length > 0 && (mergedCTR.begin == null || mergedCTR.begin.length === 0 || mergedCTR.begin > processedFileResult.begin))
18751
18860
  mergedCTR.begin = processedFileResult.begin;
18752
- if (!mergedCTR.end || mergedCTR.end && processedFileResult.end && mergedCTR.end < processedFileResult.end)
18861
+ if (processedFileResult.end != null && processedFileResult.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < processedFileResult.end))
18753
18862
  mergedCTR.end = processedFileResult.end;
18754
- if (!mergedCTR.description)
18755
- mergedCTR.description = processedFileResult.description;
18756
- if (!mergedCTR.contract)
18757
- mergedCTR.contract = processedFileResult.contract;
18863
+ mergedCTR.description ??= processedFileResult.description;
18864
+ mergedCTR.contract ??= processedFileResult.contract;
18758
18865
  if (!mergedCTR.chargingStationOperators)
18759
18866
  mergedCTR.chargingStationOperators = processedFileResult.chargingStationOperators;
18760
18867
  else if (processedFileResult.chargingStationOperators)
@@ -18786,17 +18893,14 @@ var Chargy = class {
18786
18893
  for (const mediationService of processedFileResult.mediationServices)
18787
18894
  mergedCTR.mediationServices.push(mediationService);
18788
18895
  } else if (IsAPublicKeyInfo(processedFileResult)) {
18789
- if (!mergedCTR.publicKeys)
18790
- mergedCTR.publicKeys = new Array();
18896
+ mergedCTR.publicKeys ??= new Array();
18791
18897
  mergedCTR.publicKeys.push(processedFileResult);
18792
18898
  } else if (IsAPublicKeyLookup(processedFileResult)) {
18793
- if (!mergedCTR.publicKeys)
18794
- mergedCTR.publicKeys = new Array();
18899
+ mergedCTR.publicKeys ??= new Array();
18795
18900
  for (const publicKey of processedFileResult.publicKeys)
18796
18901
  mergedCTR.publicKeys.push(publicKey);
18797
18902
  } else {
18798
- if (mergedCTR.invalidDataSets === void 0)
18799
- mergedCTR.invalidDataSets = new Array();
18903
+ mergedCTR.invalidDataSets ??= new Array();
18800
18904
  mergedCTR.invalidDataSets.push(processedFile);
18801
18905
  }
18802
18906
  }
@@ -18805,7 +18909,7 @@ var Chargy = class {
18805
18909
  }
18806
18910
  return {
18807
18911
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
18808
- message: this.GetLocalizedMessage("No charge transparency records found!"),
18912
+ message: this.GetMultilanguageText("No charge transparency records found!"),
18809
18913
  certainty: 0
18810
18914
  };
18811
18915
  }
@@ -18815,7 +18919,7 @@ var Chargy = class {
18815
18919
  if (!IsAChargeTransparencyRecord(CTR))
18816
18920
  return {
18817
18921
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
18818
- message: this.GetLocalizedMessage("UnknownOrInvalidJSONChargeTransparencyFormat"),
18922
+ message: this.GetMultilanguageText("UnknownOrInvalidJSONChargeTransparencyFormat"),
18819
18923
  certainty: 0
18820
18924
  };
18821
18925
  this.chargingStationOperators = [];
@@ -18824,8 +18928,6 @@ var Chargy = class {
18824
18928
  this.EVSEs = [];
18825
18929
  this.meters = [];
18826
18930
  this.chargingSessions = [];
18827
- this.eMobilityProviders = [];
18828
- this.mediationServices = [];
18829
18931
  try {
18830
18932
  this.internalCTR = CloneCTR(CTR);
18831
18933
  this.currentCTR = CTR;
@@ -18940,7 +19042,7 @@ var Chargy = class {
18940
19042
  } catch (exception) {
18941
19043
  return {
18942
19044
  status: "InvalidSessionFormat" /* InvalidSessionFormat */,
18943
- message: "Exception occured: " + (exception instanceof Error ? exception.message : String(exception)),
19045
+ message: this.GetMultilanguageText("Exception occured: " + (exception instanceof Error ? exception.message : String(exception))),
18944
19046
  certainty: 0
18945
19047
  };
18946
19048
  }
@@ -18952,9 +19054,9 @@ var Chargy = class {
18952
19054
  if (measurement.name !== "ENERGY_TOTAL" || measurement.values.length < 2) {
18953
19055
  continue;
18954
19056
  }
18955
- const firstValue2 = measurement.values[0];
18956
- const lastValue = measurement.values[measurement.values.length - 1];
18957
- if (firstValue2 == null || lastValue == null) {
19057
+ const firstValue2 = measurement.values.at(0);
19058
+ const lastValue = measurement.values.at(-1);
19059
+ if (firstValue2 === void 0 || lastValue === void 0) {
18958
19060
  continue;
18959
19061
  }
18960
19062
  const firstValueKWh = this.measurementValueInKWh(measurement, firstValue2);
@@ -19071,7 +19173,7 @@ var Chargy = class {
19071
19173
  default:
19072
19174
  verificationResult2 = {
19073
19175
  status: "UnknownSessionFormat" /* UnknownSessionFormat */,
19074
- message: this.GetLocalizedMessage("UnknownOrInvalidChargingSessionFormat"),
19176
+ message: this.GetMultilanguageText("UnknownOrInvalidChargingSessionFormat"),
19075
19177
  certainty: 0
19076
19178
  };
19077
19179
  break;
@@ -19081,7 +19183,7 @@ var Chargy = class {
19081
19183
  chargingSession.ctr,
19082
19184
  {
19083
19185
  level: this.getChargingSessionTotalEnergyWarningLevel(),
19084
- message: this.GetLocalizedMessage("InplausibleTotalEnergyMeasurementWarning")
19186
+ message: this.GetMultilanguageText("InplausibleTotalEnergyMeasurementWarning")
19085
19187
  }
19086
19188
  );
19087
19189
  return {
@@ -19103,14 +19205,12 @@ var Chargy = class {
19103
19205
  mergedCTR["@id"] = ctr["@id"];
19104
19206
  if (mergedCTR["@context"] === "")
19105
19207
  mergedCTR["@context"] = ctr["@context"];
19106
- if (!mergedCTR.begin || mergedCTR.begin && ctr.begin && mergedCTR.begin > ctr.begin)
19208
+ if (ctr.begin != null && ctr.begin.length > 0 && (mergedCTR.begin == null || mergedCTR.begin.length === 0 || mergedCTR.begin > ctr.begin))
19107
19209
  mergedCTR.begin = ctr.begin;
19108
- if (!mergedCTR.end || mergedCTR.end && ctr.end && mergedCTR.end < ctr.end)
19210
+ if (ctr.end != null && ctr.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < ctr.end))
19109
19211
  mergedCTR.end = ctr.end;
19110
- if (!mergedCTR.description)
19111
- mergedCTR.description = ctr.description;
19112
- if (!mergedCTR.contract)
19113
- mergedCTR.contract = ctr.contract;
19212
+ mergedCTR.description ??= ctr.description;
19213
+ mergedCTR.contract ??= ctr.contract;
19114
19214
  if (!mergedCTR.chargingStationOperators)
19115
19215
  mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
19116
19216
  else if (ctr.chargingStationOperators)
@@ -19147,7 +19247,7 @@ var Chargy = class {
19147
19247
  };
19148
19248
 
19149
19249
  // src/verificationResults.ts
19150
- function toSessionVerificationResults(CTR, noRecordsMessage = "No charge transparency records found!") {
19250
+ function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
19151
19251
  const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
19152
19252
  if (verificationResults.length > 0)
19153
19253
  return verificationResults;
@@ -19171,6 +19271,6 @@ buffer/index.js:
19171
19271
  *)
19172
19272
  */
19173
19273
 
19174
- export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EMHCrypt01, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKeyInfo, IsAPublicKeyLookup, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFTransactionTypes, OCMFv1_x, OCPI, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, TimeStatusTypes, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, buf2hex, buildMennekesSignatureData, bytesToHex2 as bytesToHex, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createHexString, dateToMennekesLocalEpochSeconds, extractMennekesChargingProcesses, firstKey, firstValue, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isGeoLocation, isICryptoResult, isIFileInfo, isIPublicKeyXY, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isMultilanguageText, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalURL, isPCDFText, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, secp224k1, setUILocale, sha256, sha384, sha512, signJSONMessage, signMessage, stripPCDFControlCharacters, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, unquotePCDFText, validatePCDFFields, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
19274
+ export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKeyInfo, IsAPublicKeyLookup, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFTransactionTypes, OCMFv1_x, OCPI, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, TimeStatusTypes, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, buf2hex, buildMennekesSignatureData, bytesToHex2 as bytesToHex, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createHexString, dateToMennekesLocalEpochSeconds, extractMennekesChargingProcesses, firstKey, firstValue, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isGeoLocation, isICryptoResult, isIFileInfo, isIPublicKeyXY, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isMultilanguageText, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalURL, isPCDFText, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, secp224k1, setUILocale, sha256, sha384, sha512, signJSONMessage, signMessage, stripPCDFControlCharacters, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, unquotePCDFText, validatePCDFFields, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
19175
19275
  //# sourceMappingURL=index.js.map
19176
19276
  //# sourceMappingURL=index.js.map