@open-charging-cloud/chargy-core 0.6.4 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +1 -1
  2. package/dist/ACrypt.d.ts +2 -2
  3. package/dist/ACrypt.d.ts.map +1 -1
  4. package/dist/Alfen.d.ts +3 -3
  5. package/dist/Alfen.d.ts.map +1 -1
  6. package/dist/BSMCrypt01.d.ts +1 -1
  7. package/dist/BSMCrypt01.d.ts.map +1 -1
  8. package/dist/EMHCrypt01.d.ts +1 -1
  9. package/dist/EMHCrypt01.d.ts.map +1 -1
  10. package/dist/GDFCrypt01.d.ts +1 -1
  11. package/dist/GDFCrypt01.d.ts.map +1 -1
  12. package/dist/Mennekes.d.ts +0 -3
  13. package/dist/Mennekes.d.ts.map +1 -1
  14. package/dist/OCMF.d.ts +8 -7
  15. package/dist/OCMF.d.ts.map +1 -1
  16. package/dist/OCPI.d.ts +2 -1
  17. package/dist/OCPI.d.ts.map +1 -1
  18. package/dist/PCDF.d.ts +5 -4
  19. package/dist/PCDF.d.ts.map +1 -1
  20. package/dist/QIDigital_DCC.d.ts +20 -19
  21. package/dist/QIDigital_DCC.d.ts.map +1 -1
  22. package/dist/SAFE_XML.d.ts +1 -26
  23. package/dist/SAFE_XML.d.ts.map +1 -1
  24. package/dist/browser/index.js +1010 -800
  25. package/dist/browser/index.js.map +1 -1
  26. package/dist/chargeIT.d.ts +2 -2
  27. package/dist/chargeIT.d.ts.map +1 -1
  28. package/dist/chargePoint.d.ts +1 -1
  29. package/dist/chargePoint.d.ts.map +1 -1
  30. package/dist/chargy.d.ts +14 -12
  31. package/dist/chargy.d.ts.map +1 -1
  32. package/dist/index.d.ts +3 -4
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/{CryptoUtils.d.ts → interfaces/CryptoUtils.d.ts} +7 -2
  35. package/dist/interfaces/CryptoUtils.d.ts.map +1 -0
  36. package/dist/interfaces/IChargeTransparencyLiveLink.d.ts +2 -2
  37. package/dist/interfaces/IChargeTransparencyLiveLink.d.ts.map +1 -1
  38. package/dist/interfaces/IChargeTransparencyRecord.d.ts +43 -19
  39. package/dist/interfaces/IChargeTransparencyRecord.d.ts.map +1 -1
  40. package/dist/interfaces/IPublicKeyInfo.d.ts +49 -18
  41. package/dist/interfaces/IPublicKeyInfo.d.ts.map +1 -1
  42. package/dist/interfaces/chargyInterfaces.d.ts +113 -97
  43. package/dist/interfaces/chargyInterfaces.d.ts.map +1 -1
  44. package/dist/{chargyLib.d.ts → interfaces/chargyLib.d.ts} +50 -20
  45. package/dist/interfaces/chargyLib.d.ts.map +1 -0
  46. package/dist/interfaces/secp224k1.d.ts.map +1 -0
  47. package/dist/node/index.js +1010 -800
  48. package/dist/node/index.js.map +1 -1
  49. package/dist/verificationResults.d.ts +1 -17
  50. package/dist/verificationResults.d.ts.map +1 -1
  51. package/i18n.json +30 -0
  52. package/package.json +1 -1
  53. package/dist/CanonicalJSON.d.ts +0 -14
  54. package/dist/CanonicalJSON.d.ts.map +0 -1
  55. package/dist/CryptoUtils.d.ts.map +0 -1
  56. package/dist/chargyLib.d.ts.map +0 -1
  57. package/dist/secp224k1.d.ts.map +0 -1
  58. /package/dist/{secp224k1.d.ts → interfaces/secp224k1.d.ts} +0 -0
@@ -7992,124 +7992,11 @@ var require_elliptic = __commonJS({
7992
7992
  }
7993
7993
  });
7994
7994
 
7995
- // src/secp224k1.ts
7996
- var secp224k1 = class {
7997
- // Pcurve = 2**224 - 2**32 - 2**12 - 2**11 - 2**9 - 2**7 - 2**4 - 2**1 - 1 or
7998
- // FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D
7999
- Zero = BigInt("0");
8000
- One = BigInt("1");
8001
- Two = BigInt("2");
8002
- Three = BigInt("3");
8003
- Pcurve = BigInt("26959946667150639794667015087019630673637144422540572481099315275117");
8004
- // The proven prime
8005
- N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
8006
- // Number of points in the field
8007
- Acurve = BigInt(0);
8008
- // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
8009
- Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
8010
- Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
8011
- GPoint = [this.Gx, this.Gy];
8012
- // This is our generator point. Trillions of dif ones possible
8013
- Sign(hash, RandomNumber, privateKey) {
8014
- const RandSignPoint = this.ECmultiply(this.GPoint, RandomNumber);
8015
- if (RandSignPoint.length >= 1 && RandSignPoint[0] != null) {
8016
- const r = this.modulo(RandSignPoint[0], this.N);
8017
- const s = this.modulo((hash + r * privateKey) * this.modInv(RandomNumber, this.N), this.N);
8018
- return [r, s];
8019
- }
8020
- return null;
8021
- }
8022
- validate(hash, signatureR, signatureS, PublicKey) {
8023
- if (signatureR == this.Zero || signatureR >= this.N)
8024
- throw new Error("Invalid R");
8025
- if (signatureS == this.Zero || signatureS >= this.N)
8026
- throw new Error("Invalid S");
8027
- const w = this.modInv(signatureS, this.N);
8028
- const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
8029
- const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
8030
- const validation = this.ECadd(u1, u2);
8031
- return validation[0] == signatureR;
8032
- }
8033
- modulo(n, m) {
8034
- return (n % m + m) % m;
8035
- }
8036
- zfill(s) {
8037
- while (s.length < 56) {
8038
- s = "0" + s;
8039
- }
8040
- return s;
8041
- }
8042
- modInv(a, n = this.Pcurve) {
8043
- let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
8044
- while (low > 1) {
8045
- const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
8046
- hm = lm;
8047
- lm = nm;
8048
- high = low;
8049
- low = newm;
8050
- }
8051
- return this.modulo(lm, n);
8052
- }
8053
- ECadd(a, b) {
8054
- if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
8055
- const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
8056
- const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
8057
- const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
8058
- return [x, y];
8059
- }
8060
- throw new Error("Invalid EC Point Addition!");
8061
- }
8062
- ECdouble(a) {
8063
- if (a[0] != void 0 && a[1] != void 0) {
8064
- const Lam = this.modulo((a[0] * a[0] * this.Three + this.Acurve) * this.modInv(a[1] * this.Two), this.Pcurve);
8065
- const x = this.modulo(Lam * Lam - a[0] * this.Two, this.Pcurve);
8066
- const y = this.modulo(Lam * (a[0] - x) - a[1], this.Pcurve);
8067
- return [x, y];
8068
- }
8069
- throw new Error("Invalid EC Point Doubling!");
8070
- }
8071
- ECmultiply(GenPoint, ScalarHex) {
8072
- if (ScalarHex == this.Zero || ScalarHex >= this.N)
8073
- throw new Error("Invalid Scalar/Private Key");
8074
- const ScalarBinary = ScalarHex.toString(2);
8075
- let Q = GenPoint;
8076
- for (let i = 1; i < ScalarBinary.length; i++) {
8077
- Q = this.ECdouble(Q);
8078
- if (ScalarBinary[i] === "1") {
8079
- Q = this.ECadd(Q, GenPoint);
8080
- }
8081
- }
8082
- return Q;
8083
- }
8084
- // uncompressed is the accumulation of both the x and y points
8085
- // compressed is the public key to share in transactions
8086
- // address is the public address tho whom someone can send coin
8087
- PublicKeyGenerate(PrivateKey) {
8088
- if (typeof PrivateKey === "number")
8089
- PrivateKey = BigInt(PrivateKey);
8090
- if (typeof PrivateKey === "string")
8091
- PrivateKey = BigInt(PrivateKey);
8092
- const publicKey = this.ECmultiply(this.GPoint, PrivateKey);
8093
- if (publicKey[0] !== void 0 && publicKey[1] !== void 0) {
8094
- const Px = this.zfill(publicKey[0].toString(16));
8095
- const Py = this.zfill(publicKey[1].toString(16));
8096
- return {
8097
- x: publicKey[0],
8098
- y: publicKey[1],
8099
- xy: [Px, Py],
8100
- uncompressed: publicKey[0].toString(16) + publicKey[1].toString(16),
8101
- compressed: "04" + Px + Py,
8102
- address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
8103
- };
8104
- }
8105
- return void 0;
8106
- }
8107
- };
8108
-
8109
7995
  // src/interfaces/chargyInterfaces.ts
8110
7996
  var chargyInterfaces_exports = {};
8111
7997
  __export(chargyInterfaces_exports, {
8112
7998
  CreateError: () => CreateError,
7999
+ CreateWarning: () => CreateWarning,
8113
8000
  CryptoAlgorithms: () => CryptoAlgorithms,
8114
8001
  CryptoHashAlgorithms: () => CryptoHashAlgorithms,
8115
8002
  DayOfWeek: () => DayOfWeek,
@@ -8118,7 +8005,7 @@ __export(chargyInterfaces_exports, {
8118
8005
  IECCurves: () => IECCurves,
8119
8006
  IEncoding: () => IEncoding,
8120
8007
  InformationRelevance: () => InformationRelevance,
8121
- PublicKeyFormats: () => PublicKeyFormats,
8008
+ OIDInfo: () => OIDInfo,
8122
8009
  SessionVerificationResult: () => SessionVerificationResult,
8123
8010
  SignatureFormats: () => SignatureFormats,
8124
8011
  VerificationResult: () => VerificationResult,
@@ -8126,23 +8013,9 @@ __export(chargyInterfaces_exports, {
8126
8013
  isGeoLocation: () => isGeoLocation,
8127
8014
  isICryptoResult: () => isICryptoResult,
8128
8015
  isIFileInfo: () => isIFileInfo,
8129
- isIPublicKeyXY: () => isIPublicKeyXY,
8130
8016
  isISessionCryptoResult1: () => isISessionCryptoResult1,
8131
- isISessionCryptoResult2: () => isISessionCryptoResult2,
8132
- isMultilanguageText: () => isMultilanguageText,
8133
- isOIDInfo: () => isOIDInfo,
8134
- isObject: () => isObject,
8135
- isString: () => isString,
8136
- isStringArray: () => isStringArray,
8137
- isStringOrOIDInfo: () => isStringOrOIDInfo,
8138
- isStringOrStringArray: () => isStringOrStringArray
8017
+ isISessionCryptoResult2: () => isISessionCryptoResult2
8139
8018
  });
8140
- function isObject(data) {
8141
- return typeof data === "object" && data !== null;
8142
- }
8143
- function isMultilanguageText(data) {
8144
- return isObject(data) && Object.values(data).every((value) => typeof value === "string");
8145
- }
8146
8019
  function isGeoLocation(data) {
8147
8020
  if (!isObject(data))
8148
8021
  return false;
@@ -8150,26 +8023,6 @@ function isGeoLocation(data) {
8150
8023
  const longitude = data["lng"];
8151
8024
  return (latitude === void 0 || typeof latitude === "number") && (longitude === void 0 || typeof longitude === "number");
8152
8025
  }
8153
- function isString(value) {
8154
- return typeof value === "string";
8155
- }
8156
- function isStringArray(value) {
8157
- return Array.isArray(value) && value.every((item) => typeof item === "string");
8158
- }
8159
- function isStringOrStringArray(value) {
8160
- return typeof value === "string" || isStringArray(value);
8161
- }
8162
- function isOIDInfo(data) {
8163
- if (!isObject(data))
8164
- return false;
8165
- return typeof data["oid"] === "string" && typeof data["name"] === "string";
8166
- }
8167
- function isStringOrOIDInfo(value) {
8168
- return typeof value === "string" || isOIDInfo(value);
8169
- }
8170
- function isIPublicKeyXY(obj) {
8171
- return typeof obj === "object" && obj !== null && typeof obj.x === "string" && typeof obj.y === "string";
8172
- }
8173
8026
  var IECCurves = /* @__PURE__ */ ((IECCurves2) => {
8174
8027
  IECCurves2["secp192r1"] = "secp192r1";
8175
8028
  IECCurves2["secp224k1"] = "secp224k1";
@@ -8184,11 +8037,6 @@ var IEncoding = /* @__PURE__ */ ((IEncoding2) => {
8184
8037
  IEncoding2["base64"] = "base64";
8185
8038
  return IEncoding2;
8186
8039
  })(IEncoding || {});
8187
- var PublicKeyFormats = /* @__PURE__ */ ((PublicKeyFormats2) => {
8188
- PublicKeyFormats2["DER"] = "DER";
8189
- PublicKeyFormats2["XY"] = "XY";
8190
- return PublicKeyFormats2;
8191
- })(PublicKeyFormats || {});
8192
8040
  var SignatureFormats = /* @__PURE__ */ ((SignatureFormats2) => {
8193
8041
  SignatureFormats2["DER"] = "DER";
8194
8042
  SignatureFormats2["RS"] = "RS";
@@ -8224,6 +8072,12 @@ var ErrorLevel = /* @__PURE__ */ ((ErrorLevel2) => {
8224
8072
  ErrorLevel2["high"] = "high";
8225
8073
  return ErrorLevel2;
8226
8074
  })(ErrorLevel || {});
8075
+ function CreateWarning(message, level = "low" /* low */) {
8076
+ return {
8077
+ level,
8078
+ message
8079
+ };
8080
+ }
8227
8081
  function CreateError(message, level = "high" /* high */) {
8228
8082
  return {
8229
8083
  level,
@@ -8310,12 +8164,19 @@ var DayOfWeek = /* @__PURE__ */ ((DayOfWeek2) => {
8310
8164
  DayOfWeek2[DayOfWeek2["Saturday"] = 6] = "Saturday";
8311
8165
  return DayOfWeek2;
8312
8166
  })(DayOfWeek || {});
8167
+ function OIDInfo(data) {
8168
+ if (typeof data === "string")
8169
+ return data;
8170
+ if (isOIDInfo(data))
8171
+ return data.name;
8172
+ return "";
8173
+ }
8313
8174
  function isJSONLDObject(value) {
8314
8175
  if (typeof value !== "object" || value === null) {
8315
8176
  return false;
8316
8177
  }
8317
8178
  const obj = value;
8318
- return typeof obj["@context"] === "string";
8179
+ return typeof obj["@context"] === "string" || Array.isArray(obj["@context"]);
8319
8180
  }
8320
8181
  function toArrayBuffer(data) {
8321
8182
  if (data instanceof ArrayBuffer)
@@ -8775,36 +8636,6 @@ function pad(text, paddingValue) {
8775
8636
  text ??= "";
8776
8637
  return (text + Array(2 * paddingValue).join("0")).substring(0, 2 * paddingValue);
8777
8638
  }
8778
- async function sha256(message) {
8779
- let hashBuffer;
8780
- if (typeof message === "string")
8781
- hashBuffer = await crypto.subtle.digest("SHA-256", Buffer.from(message, "utf8"));
8782
- else
8783
- hashBuffer = await crypto.subtle.digest("SHA-256", message);
8784
- const hashArray = Array.from(new Uint8Array(hashBuffer));
8785
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
8786
- return hashHex;
8787
- }
8788
- async function sha384(message) {
8789
- let hashBuffer;
8790
- if (typeof message === "string")
8791
- hashBuffer = await crypto.subtle.digest("SHA-384", Buffer.from(message, "utf8"));
8792
- else
8793
- hashBuffer = await crypto.subtle.digest("SHA-384", message);
8794
- const hashArray = Array.from(new Uint8Array(hashBuffer));
8795
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
8796
- return hashHex;
8797
- }
8798
- async function sha512(message) {
8799
- let hashBuffer;
8800
- if (typeof message === "string")
8801
- hashBuffer = await crypto.subtle.digest("SHA-512", Buffer.from(message, "utf8"));
8802
- else
8803
- hashBuffer = await crypto.subtle.digest("SHA-512", message);
8804
- const hashArray = Array.from(new Uint8Array(hashBuffer));
8805
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
8806
- return hashHex;
8807
- }
8808
8639
  function asJSONObject(value) {
8809
8640
  return isMandatoryJSONObject(value) ? value : void 0;
8810
8641
  }
@@ -8901,6 +8732,48 @@ function parseNumber(value) {
8901
8732
  }
8902
8733
  return null;
8903
8734
  }
8735
+ function isObject(data) {
8736
+ return typeof data === "object" && data !== null;
8737
+ }
8738
+ function isI18NString(data) {
8739
+ return isObject(data) && Object.values(data).every((value) => typeof value === "string");
8740
+ }
8741
+ function isString(value) {
8742
+ return typeof value === "string";
8743
+ }
8744
+ function isStringArray(value) {
8745
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
8746
+ }
8747
+ function isStringOrStringArray(value) {
8748
+ return typeof value === "string" || isStringArray(value);
8749
+ }
8750
+ function isOIDInfo(data) {
8751
+ if (!isObject(data))
8752
+ return false;
8753
+ return typeof data["oid"] === "string" && typeof data["name"] === "string";
8754
+ }
8755
+ function isStringOrOIDInfo(value) {
8756
+ return typeof value === "string" || isOIDInfo(value);
8757
+ }
8758
+ function isOptionalStringArray(data) {
8759
+ return data === void 0 || Array.isArray(data) && data.every(isString);
8760
+ }
8761
+ function isOptionalStringOrOIDInfo(data) {
8762
+ return data === void 0 || isStringOrOIDInfo(data);
8763
+ }
8764
+ function isEncodedValue(data) {
8765
+ if (isString(data))
8766
+ return true;
8767
+ if (!isMandatoryJSONObject(data))
8768
+ return false;
8769
+ if (!isString(data["value"]))
8770
+ return false;
8771
+ if (!isOptionalString(data["format"]))
8772
+ return false;
8773
+ if (!isOptionalString(data["encoding"]))
8774
+ return false;
8775
+ return true;
8776
+ }
8904
8777
  function InformationRelevanceToString(InfoRelevance) {
8905
8778
  switch (InfoRelevance) {
8906
8779
  case "Ignored" /* Ignored */:
@@ -8961,6 +8834,187 @@ function _jsonPrettyPrinter(value, indentLevel, path, keyLookup) {
8961
8834
  html += String(value);
8962
8835
  return html;
8963
8836
  }
8837
+ function base64ToBytes(value) {
8838
+ if (typeof Buffer !== "undefined")
8839
+ return Uint8Array.from(Buffer.from(value, "base64"));
8840
+ const binary = atob(value);
8841
+ const bytes = new Uint8Array(binary.length);
8842
+ for (let i = 0; i < binary.length; i++)
8843
+ bytes[i] = binary.charCodeAt(i);
8844
+ return bytes;
8845
+ }
8846
+ function bytesToBase64(bytes) {
8847
+ if (typeof Buffer !== "undefined")
8848
+ return Buffer.from(bytes).toString("base64");
8849
+ let binary = "";
8850
+ for (const byte of bytes)
8851
+ binary += String.fromCharCode(byte);
8852
+ return btoa(binary);
8853
+ }
8854
+ function cleanHex(hex) {
8855
+ return hex.replace(/\s+/g, "");
8856
+ }
8857
+ function hexToBytes(hex) {
8858
+ const cleanedHex = cleanHex(hex);
8859
+ if (cleanedHex.length % 2 !== 0)
8860
+ throw new Error("Hex strings must have even length!");
8861
+ if (!/^[0-9a-fA-F]*$/.test(cleanedHex))
8862
+ throw new Error("Invalid hexadecimal string!");
8863
+ const bytes = new Uint8Array(cleanedHex.length / 2);
8864
+ for (let index = 0; index < cleanedHex.length; index += 2)
8865
+ bytes[index / 2] = Number.parseInt(cleanedHex.substring(index, index + 2), 16);
8866
+ return bytes;
8867
+ }
8868
+ function bytesToHex(bytes) {
8869
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
8870
+ }
8871
+ async function sha256(message) {
8872
+ return bytesToHex(await sha256____(message));
8873
+ }
8874
+ async function sha384(message) {
8875
+ return bytesToHex(await sha384____(message));
8876
+ }
8877
+ async function sha512(message) {
8878
+ return bytesToHex(await sha512____(message));
8879
+ }
8880
+ async function sha256____(message) {
8881
+ let hashBuffer;
8882
+ if (typeof message === "string")
8883
+ hashBuffer = await crypto.subtle.digest("SHA-256", Buffer.from(message, "utf8"));
8884
+ else
8885
+ hashBuffer = await crypto.subtle.digest("SHA-256", message);
8886
+ return new Uint8Array(hashBuffer);
8887
+ }
8888
+ async function sha384____(message) {
8889
+ let hashBuffer;
8890
+ if (typeof message === "string")
8891
+ hashBuffer = await crypto.subtle.digest("SHA-384", Buffer.from(message, "utf8"));
8892
+ else
8893
+ hashBuffer = await crypto.subtle.digest("SHA-384", message);
8894
+ return new Uint8Array(hashBuffer);
8895
+ }
8896
+ async function sha512____(message) {
8897
+ let hashBuffer;
8898
+ if (typeof message === "string")
8899
+ hashBuffer = await crypto.subtle.digest("SHA-512", Buffer.from(message, "utf8"));
8900
+ else
8901
+ hashBuffer = await crypto.subtle.digest("SHA-512", message);
8902
+ return new Uint8Array(hashBuffer);
8903
+ }
8904
+
8905
+ // src/interfaces/secp224k1.ts
8906
+ var secp224k1 = class {
8907
+ // Pcurve = 2**224 - 2**32 - 2**12 - 2**11 - 2**9 - 2**7 - 2**4 - 2**1 - 1 or
8908
+ // FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D
8909
+ Zero = BigInt("0");
8910
+ One = BigInt("1");
8911
+ Two = BigInt("2");
8912
+ Three = BigInt("3");
8913
+ Pcurve = BigInt("26959946667150639794667015087019630673637144422540572481099315275117");
8914
+ // The proven prime
8915
+ N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
8916
+ // Number of points in the field
8917
+ Acurve = BigInt(0);
8918
+ // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
8919
+ Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
8920
+ Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
8921
+ GPoint = [this.Gx, this.Gy];
8922
+ // This is our generator point. Trillions of dif ones possible
8923
+ Sign(hash, RandomNumber, privateKey) {
8924
+ const RandSignPoint = this.ECmultiply(this.GPoint, RandomNumber);
8925
+ if (RandSignPoint.length >= 1 && RandSignPoint[0] != null) {
8926
+ const r = this.modulo(RandSignPoint[0], this.N);
8927
+ const s = this.modulo((hash + r * privateKey) * this.modInv(RandomNumber, this.N), this.N);
8928
+ return [r, s];
8929
+ }
8930
+ return null;
8931
+ }
8932
+ validate(hash, signatureR, signatureS, PublicKey) {
8933
+ if (signatureR == this.Zero || signatureR >= this.N)
8934
+ throw new Error("Invalid R");
8935
+ if (signatureS == this.Zero || signatureS >= this.N)
8936
+ throw new Error("Invalid S");
8937
+ const w = this.modInv(signatureS, this.N);
8938
+ const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
8939
+ const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
8940
+ const validation = this.ECadd(u1, u2);
8941
+ return validation[0] == signatureR;
8942
+ }
8943
+ modulo(n, m) {
8944
+ return (n % m + m) % m;
8945
+ }
8946
+ zfill(s) {
8947
+ while (s.length < 56) {
8948
+ s = "0" + s;
8949
+ }
8950
+ return s;
8951
+ }
8952
+ modInv(a, n = this.Pcurve) {
8953
+ let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
8954
+ while (low > 1) {
8955
+ const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
8956
+ hm = lm;
8957
+ lm = nm;
8958
+ high = low;
8959
+ low = newm;
8960
+ }
8961
+ return this.modulo(lm, n);
8962
+ }
8963
+ ECadd(a, b) {
8964
+ if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
8965
+ const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
8966
+ const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
8967
+ const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
8968
+ return [x, y];
8969
+ }
8970
+ throw new Error("Invalid EC Point Addition!");
8971
+ }
8972
+ ECdouble(a) {
8973
+ if (a[0] != void 0 && a[1] != void 0) {
8974
+ const Lam = this.modulo((a[0] * a[0] * this.Three + this.Acurve) * this.modInv(a[1] * this.Two), this.Pcurve);
8975
+ const x = this.modulo(Lam * Lam - a[0] * this.Two, this.Pcurve);
8976
+ const y = this.modulo(Lam * (a[0] - x) - a[1], this.Pcurve);
8977
+ return [x, y];
8978
+ }
8979
+ throw new Error("Invalid EC Point Doubling!");
8980
+ }
8981
+ ECmultiply(GenPoint, ScalarHex) {
8982
+ if (ScalarHex == this.Zero || ScalarHex >= this.N)
8983
+ throw new Error("Invalid Scalar/Private Key");
8984
+ const ScalarBinary = ScalarHex.toString(2);
8985
+ let Q = GenPoint;
8986
+ for (let i = 1; i < ScalarBinary.length; i++) {
8987
+ Q = this.ECdouble(Q);
8988
+ if (ScalarBinary[i] === "1") {
8989
+ Q = this.ECadd(Q, GenPoint);
8990
+ }
8991
+ }
8992
+ return Q;
8993
+ }
8994
+ // uncompressed is the accumulation of both the x and y points
8995
+ // compressed is the public key to share in transactions
8996
+ // address is the public address tho whom someone can send coin
8997
+ PublicKeyGenerate(PrivateKey) {
8998
+ if (typeof PrivateKey === "number")
8999
+ PrivateKey = BigInt(PrivateKey);
9000
+ if (typeof PrivateKey === "string")
9001
+ PrivateKey = BigInt(PrivateKey);
9002
+ const publicKey = this.ECmultiply(this.GPoint, PrivateKey);
9003
+ if (publicKey[0] !== void 0 && publicKey[1] !== void 0) {
9004
+ const Px = this.zfill(publicKey[0].toString(16));
9005
+ const Py = this.zfill(publicKey[1].toString(16));
9006
+ return {
9007
+ x: publicKey[0],
9008
+ y: publicKey[1],
9009
+ xy: [Px, Py],
9010
+ uncompressed: publicKey[0].toString(16) + publicKey[1].toString(16),
9011
+ compressed: "04" + Px + Py,
9012
+ address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
9013
+ };
9014
+ }
9015
+ return void 0;
9016
+ }
9017
+ };
8964
9018
 
8965
9019
  // src/ACrypt.ts
8966
9020
  var ACrypt = class {
@@ -9192,8 +9246,8 @@ var Alfen = class {
9192
9246
  "Signature": this.bufferToHex(Signature)
9193
9247
  });
9194
9248
  }
9195
- const evseId = asString(containerInfos["EVSEId"]) ?? "DE*GEF*EVSE*CHARGY*1";
9196
- const chargingStationId = asString(containerInfos["ChargingStationId"]) ?? "DE*GEF*STATION*CHARGY*1";
9249
+ const evseId = ContainerInfos.chargingStations?.[0]?.EVSEs?.[0]?.["@id"] ?? "DE*GEF*EVSE*CHARGY*1";
9250
+ const chargingStationId = ContainerInfos.chargingStations?.[0]?.["@id"] ?? "DE*GEF*STATION*CHARGY*1";
9197
9251
  const chargingSessionId = asString(chargingSession?.["@id"]);
9198
9252
  const firstDataSet = getFirstArrayElement(common.dataSets, "Missing first Alfen data set");
9199
9253
  const lastDataSet = getLastArrayElement(common.dataSets, "Missing last Alfen data set");
@@ -9218,10 +9272,18 @@ var Alfen = class {
9218
9272
  "@id": chargingStationId,
9219
9273
  // ToDo: The container infos are not validated yet!
9220
9274
  "description": asJSONObject(chargingStation?.["description"]),
9221
- "manufacturer": asString(chargingStation?.["manufacturer"]),
9222
- "model": asString(chargingStation?.["type"]),
9223
- "serialNumber": asString(chargingStation?.["serialNumber"]),
9224
- "firmwareVersion": asString(chargingStation?.["softwareVersion"]),
9275
+ "manufacturer": {
9276
+ "name": asString(chargingStation?.["manufacturer"])
9277
+ },
9278
+ "model": {
9279
+ "name": asString(chargingStation?.["type"])
9280
+ },
9281
+ "hardware": {
9282
+ "serialNumber": asString(chargingStation?.["serialNumber"])
9283
+ },
9284
+ "firmware": {
9285
+ "version": asString(chargingStation?.["softwareVersion"])
9286
+ },
9225
9287
  "legalCompliance": asJSONObject(chargingStation?.["legalCompliance"]),
9226
9288
  "geoLocation": asJSONObject(chargingStation?.["geoLocation"]),
9227
9289
  "address": asJSONObject(chargingStation?.["address"]),
@@ -9231,18 +9293,29 @@ var Alfen = class {
9231
9293
  "description": asJSONObject(evse?.["description"]),
9232
9294
  "connectors": [{
9233
9295
  "type": asString(connector?.["type"]) ?? "",
9234
- "looses": asNumber(connector?.["looses"]) ?? 0
9296
+ "cable": {
9297
+ "length": asNumber(connector?.["cableLength"]) ?? 0,
9298
+ "looses": asNumber(connector?.["cableLooses"]) ?? 0
9299
+ }
9235
9300
  }],
9236
- "meters": [
9301
+ "energyMeters": [
9237
9302
  {
9238
9303
  "@id": common.MeterId,
9239
- "manufacturer": asString(energyMeter?.["manufacturer"]),
9240
- "manufacturerURL": asString(energyMeter?.["manufacturerURL"]),
9241
- "model": asString(energyMeter?.["model"]),
9242
- "modelURL": asString(energyMeter?.["modelURL"]),
9243
- "hardwareVersion": asString(energyMeter?.["hardwareVersion"]),
9244
- "firmwareVersion": common.AdapterFWVersion,
9245
- "firmwareChecksum": common.AdapterFWChecksum,
9304
+ "manufacturer": {
9305
+ "name": asString(energyMeter?.["manufacturer"]),
9306
+ "contact": { "web": asString(energyMeter?.["manufacturerURL"]) }
9307
+ },
9308
+ "model": {
9309
+ "name": asString(energyMeter?.["model"]),
9310
+ "url": asString(energyMeter?.["modelURL"])
9311
+ },
9312
+ "hardware": {
9313
+ "revision": asString(energyMeter?.["hardwareVersion"])
9314
+ },
9315
+ "firmware": {
9316
+ "version": common.AdapterFWVersion,
9317
+ "checksum": common.AdapterFWChecksum
9318
+ },
9246
9319
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/AlfenCrypt01",
9247
9320
  "publicKeys": [
9248
9321
  {
@@ -9322,6 +9395,8 @@ var Alfen = class {
9322
9395
  );
9323
9396
  }
9324
9397
  _CTR["status"] = "Unvalidated" /* Unvalidated */;
9398
+ if (ContainerInfos.warnings !== void 0)
9399
+ _CTR.warnings = [..._CTR.warnings ?? [], ...ContainerInfos.warnings];
9325
9400
  return _CTR;
9326
9401
  } catch (exception) {
9327
9402
  return {
@@ -9342,23 +9417,21 @@ var AlfenCrypt01 = class extends ACrypt {
9342
9417
  }
9343
9418
  async VerifyChargingSession(chargingSession) {
9344
9419
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
9345
- {
9346
- for (const measurement of chargingSession.measurements) {
9347
- measurement.chargingSession = chargingSession;
9348
- if (measurement.values.length > 1) {
9349
- for (const measurementValue of measurement.values) {
9350
- measurementValue.measurement = measurement;
9351
- await this.VerifyMeasurement(measurementValue);
9352
- }
9353
- sessionResult = "ValidSignature" /* ValidSignature */;
9354
- for (const measurementValue of measurement.values) {
9355
- if (sessionResult == "ValidSignature" /* ValidSignature */ && measurementValue.result?.status != "ValidSignature" /* ValidSignature */) {
9356
- sessionResult = "InvalidSignature" /* InvalidSignature */;
9357
- }
9420
+ for (const measurement of chargingSession.measurements ?? []) {
9421
+ measurement.chargingSession = chargingSession;
9422
+ if (measurement.values.length > 1) {
9423
+ for (const measurementValue of measurement.values) {
9424
+ measurementValue.measurement = measurement;
9425
+ await this.VerifyMeasurement(measurementValue);
9426
+ }
9427
+ sessionResult = "ValidSignature" /* ValidSignature */;
9428
+ for (const measurementValue of measurement.values) {
9429
+ if (sessionResult == "ValidSignature" /* ValidSignature */ && measurementValue.result?.status != "ValidSignature" /* ValidSignature */) {
9430
+ sessionResult = "InvalidSignature" /* InvalidSignature */;
9358
9431
  }
9359
- } else
9360
- sessionResult = "AtLeastTwoMeasurementsRequired" /* AtLeastTwoMeasurementsRequired */;
9361
- }
9432
+ }
9433
+ } else
9434
+ sessionResult = "AtLeastTwoMeasurementsRequired" /* AtLeastTwoMeasurementsRequired */;
9362
9435
  }
9363
9436
  return {
9364
9437
  status: sessionResult,
@@ -9388,7 +9461,7 @@ var AlfenCrypt01 = class extends ACrypt {
9388
9461
  unitEncoded: SetInt8(cryptoBuffer, measurementValue.measurement.unitEncoded ?? 0, 44),
9389
9462
  scalar: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 45),
9390
9463
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 46, true),
9391
- uid: SetText(cryptoBuffer, measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "", 54),
9464
+ uid: SetText(cryptoBuffer, measurementValue.measurement.chargingSession?.authorizationStart?.["@id"] ?? "", 54),
9392
9465
  sessionId: SetUInt32(cryptoBuffer, parseInt(measurementValue.measurement.chargingSession?.internalSessionId ?? ""), 74, true),
9393
9466
  paging: SetUInt32(cryptoBuffer, measurementValue.paginationId, 78, true)
9394
9467
  };
@@ -9426,8 +9499,8 @@ var AlfenCrypt01 = class extends ACrypt {
9426
9499
  cryptoResult.hashValue = hashValue224k1;
9427
9500
  result = this.curve224k1.validate(
9428
9501
  hashValue224k1,
9429
- BigInt(signatureExpected.r !== void 0 ? "0x" + signatureExpected.r : "0x0"),
9430
- BigInt(signatureExpected.s !== void 0 ? "0x" + signatureExpected.s : "0x0"),
9502
+ BigInt("0x" + signatureExpected.r),
9503
+ BigInt("0x" + signatureExpected.s),
9431
9504
  [
9432
9505
  BigInt("0x" + publicKey.substring(2, 58)),
9433
9506
  BigInt("0x" + publicKey.substring(58))
@@ -9514,7 +9587,7 @@ var AlfenCrypt01 = class extends ACrypt {
9514
9587
  this.CreateLocalizedLine("Unit (encoded)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded ?? "", infoDiv, PlainTextDiv);
9515
9588
  this.CreateLocalizedLine("Scaling", measurementValue.measurement.scale, result.scalar ?? "", infoDiv, PlainTextDiv);
9516
9589
  this.CreateLocalizedLine("Measurement Value", measurementValue.value.toString() + " Wh", result.value ?? "", infoDiv, PlainTextDiv);
9517
- this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
9590
+ this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart?.["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
9518
9591
  this.CreateLocalizedLine("SessionId", measurementValue.measurement.chargingSession?.["@id"] ?? "", result.sessionId ?? "", infoDiv, PlainTextDiv);
9519
9592
  this.CreateLocalizedLine("Pagination counter", measurementValue.paginationId, result.paging ?? "", infoDiv, PlainTextDiv);
9520
9593
  }
@@ -9541,8 +9614,8 @@ var AlfenCrypt01 = class extends ACrypt {
9541
9614
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
9542
9615
  measurementValue.measurement.chargingSession?.chargingStation,
9543
9616
  measurementValue.measurement.chargingSession?.EVSE,
9544
- measurementValue.measurement.chargingSession?.EVSE?.meters[0],
9545
- measurementValue.measurement.chargingSession?.EVSE?.meters[0]?.publicKeys?.[0],
9617
+ measurementValue.measurement.chargingSession?.EVSE?.energyMeters?.[0],
9618
+ measurementValue.measurement.chargingSession?.EVSE?.energyMeters?.[0]?.publicKeys?.[0],
9546
9619
  signature
9547
9620
  );
9548
9621
  } catch {
@@ -9554,7 +9627,7 @@ var AlfenCrypt01 = class extends ACrypt {
9554
9627
  if (SignatureExpectedDiv.parentElement) {
9555
9628
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (" + (result.signature.format ?? "") + ", hex)";
9556
9629
  }
9557
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0) {
9630
+ if (result.signature.r.length > 0 && result.signature.s.length > 0) {
9558
9631
  const signatureR = result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
9559
9632
  const signatureS = result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
9560
9633
  SignatureExpectedDiv.innerHTML = "r: " + signatureR + "<br />s: " + signatureS;
@@ -10059,7 +10132,7 @@ var BSMCrypt01 = class extends ACrypt {
10059
10132
  "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/bsm-ws36a-v0+json",
10060
10133
  "begin": firstDataSet.time,
10061
10134
  "end": lastDataSet.time,
10062
- "EVSEId": CTR.chargingStationOperators?.[0]?.["chargingStations"]?.[0]?.["EVSEs"][0]?.["@id"],
10135
+ "EVSEId": CTR.chargingStationOperators?.[0]?.["chargingStations"]?.[0]?.["EVSEs"]?.[0]?.["@id"],
10063
10136
  "authorizationStart": {
10064
10137
  "@id": common.contract_id,
10065
10138
  "@context": common.contract_type
@@ -10166,7 +10239,7 @@ var BSMCrypt01 = class extends ACrypt {
10166
10239
  {
10167
10240
  const firstChargingSession = getFirstArrayElement(CTR.chargingSessions, "Missing first BSM charging session");
10168
10241
  const lastChargingSession = getLastArrayElement(CTR.chargingSessions, "Missing last BSM charging session");
10169
- if (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin) {
10242
+ if (firstChargingSession.begin !== void 0 && (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin)) {
10170
10243
  CTR.begin = firstChargingSession.begin;
10171
10244
  }
10172
10245
  if (lastChargingSession.end !== void 0) {
@@ -10174,21 +10247,22 @@ var BSMCrypt01 = class extends ACrypt {
10174
10247
  CTR.end = lastChargingSession.end;
10175
10248
  }
10176
10249
  }
10177
- if (CTR.contract == null)
10178
- CTR.contract = {
10179
- "@id": common.contract_id,
10180
- "@context": common.contract_type
10181
- };
10182
- else {
10183
- CTR.contract["@id"] = common.contract_id;
10184
- CTR.contract["@context"] = common.contract_type;
10185
- }
10186
- CTR.chargingStationOperators?.[0]?.chargingStations?.[0]?.EVSEs[0]?.meters?.push({
10250
+ CTR.contracts = [{
10251
+ "@id": common.contract_id,
10252
+ "@context": common.contract_type
10253
+ }];
10254
+ CTR.chargingStationOperators?.[0]?.chargingStations?.[0]?.EVSEs?.[0]?.energyMeters?.push({
10187
10255
  "@id": common.meterInfo_meterId,
10188
- model: common.meterInfo_type,
10189
- manufacturer: common.meterInfo_manufacturer,
10190
- manufacturerURL: "https://www.bzr-bauer.de",
10191
- firmwareVersion: common.meterInfo_firmwareVersion,
10256
+ model: { name: common.meterInfo_type },
10257
+ manufacturer: {
10258
+ name: common.meterInfo_manufacturer,
10259
+ contact: {
10260
+ web: "https://www.bzr-bauer.de"
10261
+ }
10262
+ },
10263
+ firmware: {
10264
+ version: common.meterInfo_firmwareVersion
10265
+ },
10192
10266
  //hardwareVersion?: string;
10193
10267
  signatureInfos: {
10194
10268
  hash: "SHA256" /* SHA256 */,
@@ -10223,7 +10297,7 @@ var BSMCrypt01 = class extends ACrypt {
10223
10297
  async VerifyChargingSession(chargingSession) {
10224
10298
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
10225
10299
  {
10226
- for (const measurement of chargingSession.measurements) {
10300
+ for (const measurement of chargingSession.measurements ?? []) {
10227
10301
  measurement.chargingSession = chargingSession;
10228
10302
  if (measurement.values.length > 1) {
10229
10303
  for (const measurementValue of measurement.values) {
@@ -10390,13 +10464,13 @@ var BSMCrypt01 = class extends ACrypt {
10390
10464
  const signatureDiv = publicKeySignatureContainer?.appendChild(document.createElement("div"));
10391
10465
  const chargingSession = measurementValue.measurement.chargingSession;
10392
10466
  const evse = chargingSession?.EVSE;
10393
- const meter = evse?.meters.at(0);
10394
- const publicKey = meter?.publicKeys?.at(0);
10395
- if (signatureDiv != null && chargingSession != null && evse != null && meter != null && publicKey != null) {
10467
+ const energyMeter = evse?.energyMeters?.at(0);
10468
+ const publicKey = energyMeter?.publicKeys?.at(0);
10469
+ if (signatureDiv != null && chargingSession != null && evse != null && energyMeter != null && publicKey != null) {
10396
10470
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
10397
10471
  chargingSession.chargingStation,
10398
10472
  evse,
10399
- meter,
10473
+ energyMeter,
10400
10474
  publicKey,
10401
10475
  signature
10402
10476
  );
@@ -10411,7 +10485,7 @@ var BSMCrypt01 = class extends ACrypt {
10411
10485
  if (SignatureExpectedDiv.parentElement) {
10412
10486
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
10413
10487
  }
10414
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
10488
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
10415
10489
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-");
10416
10490
  else if (result.signature.value != null && result.signature.value.length > 0)
10417
10491
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -10549,97 +10623,7 @@ var BSMCrypt01 = class extends ACrypt {
10549
10623
  // //#endregion
10550
10624
  };
10551
10625
 
10552
- // src/CanonicalJSON.ts
10553
- var CanonicalJSONError = class extends TypeError {
10554
- constructor(message) {
10555
- super(message);
10556
- this.name = "CanonicalJSONError";
10557
- }
10558
- };
10559
- function canonicalJSONStringify(value) {
10560
- return serializeJSONValue(value, "$", /* @__PURE__ */ new WeakSet());
10561
- }
10562
- function canonicalJSONBytes(value) {
10563
- return new TextEncoder().encode(canonicalJSONStringify(value));
10564
- }
10565
- function serializeJSONValue(value, path, seen) {
10566
- switch (typeof value) {
10567
- case "string":
10568
- return JSON.stringify(value);
10569
- case "number":
10570
- if (!Number.isFinite(value))
10571
- throw new CanonicalJSONError(`Non-finite number at ${path} is not valid JSON.`);
10572
- return JSON.stringify(value);
10573
- case "boolean":
10574
- return value ? "true" : "false";
10575
- case "object":
10576
- if (value === null)
10577
- return "null";
10578
- return Array.isArray(value) ? serializeJSONArray(value, path, seen) : serializeJSONObject(value, path, seen);
10579
- case "bigint":
10580
- throw new CanonicalJSONError(`BigInt at ${path} is not valid JSON.`);
10581
- case "undefined":
10582
- throw new CanonicalJSONError(`Undefined value at ${path} is not valid JSON.`);
10583
- case "function":
10584
- throw new CanonicalJSONError(`Function at ${path} is not valid JSON.`);
10585
- case "symbol":
10586
- throw new CanonicalJSONError(`Symbol at ${path} is not valid JSON.`);
10587
- }
10588
- }
10589
- function serializeJSONArray(value, path, seen) {
10590
- if (seen.has(value))
10591
- throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
10592
- seen.add(value);
10593
- const indexedKeys = /* @__PURE__ */ new Set();
10594
- for (let i = 0; i < value.length; i++) {
10595
- if (!Object.prototype.hasOwnProperty.call(value, i))
10596
- throw new CanonicalJSONError(`Sparse array slot at ${path}[${String(i)}] is not valid JSON.`);
10597
- indexedKeys.add(String(i));
10598
- }
10599
- for (const key of Object.keys(value)) {
10600
- if (!indexedKeys.has(key))
10601
- throw new CanonicalJSONError(`Non-index array property ${formatPathProperty(key)} at ${path} is not valid JSON.`);
10602
- }
10603
- rejectEnumerableSymbolProperties(value, path);
10604
- const serializedItems = value.map(
10605
- (item, index) => serializeJSONValue(item, `${path}[${String(index)}]`, seen)
10606
- );
10607
- seen.delete(value);
10608
- return `[${serializedItems.join(",")}]`;
10609
- }
10610
- function serializeJSONObject(value, path, seen) {
10611
- if (Object.prototype.toString.call(value) !== "[object Object]")
10612
- throw new CanonicalJSONError(`Unsupported object at ${path} is not valid JSON.`);
10613
- if (seen.has(value))
10614
- throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
10615
- seen.add(value);
10616
- rejectEnumerableSymbolProperties(value, path);
10617
- const serializedProperties = Object.keys(value).sort(compareOrdinal).map((key) => {
10618
- const serializedKey = JSON.stringify(key);
10619
- const serializedValue = serializeJSONValue(
10620
- value[key],
10621
- `${path}${formatPathProperty(key)}`,
10622
- seen
10623
- );
10624
- return `${serializedKey}:${serializedValue}`;
10625
- });
10626
- seen.delete(value);
10627
- return `{${serializedProperties.join(",")}}`;
10628
- }
10629
- function rejectEnumerableSymbolProperties(value, path) {
10630
- for (const symbol of Object.getOwnPropertySymbols(value)) {
10631
- if (Object.prototype.propertyIsEnumerable.call(value, symbol))
10632
- throw new CanonicalJSONError(`Symbol property at ${path} is not valid JSON.`);
10633
- }
10634
- }
10635
- function compareOrdinal(left, right) {
10636
- return left < right ? -1 : left > right ? 1 : 0;
10637
- }
10638
- function formatPathProperty(propertyName) {
10639
- return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName) ? `.${propertyName}` : `[${JSON.stringify(propertyName)}]`;
10640
- }
10641
-
10642
- // src/CryptoUtils.ts
10626
+ // src/interfaces/CryptoUtils.ts
10643
10627
  var import_elliptic = __toESM(require_elliptic());
10644
10628
  var JSONSignatureVerificationStatus = /* @__PURE__ */ ((JSONSignatureVerificationStatus2) => {
10645
10629
  JSONSignatureVerificationStatus2["True"] = "True";
@@ -10680,7 +10664,7 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
10680
10664
  continue;
10681
10665
  const messageJSON = cloneMessageWithoutSignatures(JSONMessage);
10682
10666
  const plainText = canonicalJSONBytes(messageJSON);
10683
- const sha256Hash = await sha2562(plainText);
10667
+ const sha256Hash = await sha256____(plainText);
10684
10668
  JSONMessage.signatures ??= [];
10685
10669
  const publicKeyBytes = Uint8Array.from(KeyPair.getPublic(false, "array"));
10686
10670
  const signature = KeyPair.sign(sha256Hash, {
@@ -10727,7 +10711,7 @@ async function verifyJSONSignatureResult(JSONMessage, signature, options) {
10727
10711
  try {
10728
10712
  const messageJSON = cloneMessageWithoutSignatures(JSONMessage);
10729
10713
  const plainText = canonicalJSONBytes(messageJSON);
10730
- sha256Hash = await sha2562(plainText);
10714
+ sha256Hash = await sha256____(plainText);
10731
10715
  } catch (exception) {
10732
10716
  return verificationResult(
10733
10717
  "InvalidCanonicalJSON" /* InvalidCanonicalJSON */,
@@ -10835,7 +10819,7 @@ function parseSignedJSONMessage(JSONMessage) {
10835
10819
  };
10836
10820
  }
10837
10821
  }
10838
- if (!isJSONRecord(parsedMessage))
10822
+ if (!isMandatoryJSONObject(parsedMessage))
10839
10823
  return {
10840
10824
  result: verificationResult(
10841
10825
  "InvalidJSON" /* InvalidJSON */,
@@ -10854,7 +10838,7 @@ function parseSignedJSONMessage(JSONMessage) {
10854
10838
  };
10855
10839
  }
10856
10840
  function isJSONSignature(value) {
10857
- return isJSONRecord(value) && typeof value["publicKey"] === "string" && typeof value["publicKeyHEX"] === "string" && typeof value["signature"] === "string" && typeof value["signatureHEX"] === "string";
10841
+ return isMandatoryJSONObject(value) && typeof value["publicKey"] === "string" && typeof value["publicKeyHEX"] === "string" && typeof value["signature"] === "string" && typeof value["signatureHEX"] === "string";
10858
10842
  }
10859
10843
  function signatureEncodingsMatch(signature) {
10860
10844
  try {
@@ -10878,32 +10862,93 @@ function verificationResult(status, description) {
10878
10862
  function isVerificationTrue(result) {
10879
10863
  return (typeof result === "string" ? result : result.status) === "True" /* True */;
10880
10864
  }
10881
- function isJSONRecord(value) {
10882
- return value != null && typeof value === "object" && !Array.isArray(value);
10865
+ var CanonicalJSONError = class extends TypeError {
10866
+ constructor(message) {
10867
+ super(message);
10868
+ this.name = "CanonicalJSONError";
10869
+ }
10870
+ };
10871
+ function canonicalJSONStringify(value) {
10872
+ return serializeJSONValue(value, "$", /* @__PURE__ */ new WeakSet());
10883
10873
  }
10884
- async function sha2562(data) {
10885
- const digest = await crypto.subtle.digest("SHA-256", data);
10886
- return new Uint8Array(digest);
10874
+ function canonicalJSONBytes(value) {
10875
+ return new TextEncoder().encode(canonicalJSONStringify(value));
10887
10876
  }
10888
- function bytesToHex(bytes) {
10889
- return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
10877
+ function serializeJSONValue(value, path, seen) {
10878
+ switch (typeof value) {
10879
+ case "string":
10880
+ return JSON.stringify(value);
10881
+ case "number":
10882
+ if (!Number.isFinite(value))
10883
+ throw new CanonicalJSONError(`Non-finite number at ${path} is not valid JSON.`);
10884
+ return JSON.stringify(value);
10885
+ case "boolean":
10886
+ return value ? "true" : "false";
10887
+ case "object":
10888
+ if (value === null)
10889
+ return "null";
10890
+ return Array.isArray(value) ? serializeJSONArray(value, path, seen) : serializeJSONObject(value, path, seen);
10891
+ case "bigint":
10892
+ throw new CanonicalJSONError(`BigInt at ${path} is not valid JSON.`);
10893
+ case "undefined":
10894
+ throw new CanonicalJSONError(`Undefined value at ${path} is not valid JSON.`);
10895
+ case "function":
10896
+ throw new CanonicalJSONError(`Function at ${path} is not valid JSON.`);
10897
+ case "symbol":
10898
+ throw new CanonicalJSONError(`Symbol at ${path} is not valid JSON.`);
10899
+ }
10890
10900
  }
10891
- function base64ToBytes(value) {
10892
- if (typeof Buffer !== "undefined")
10893
- return Uint8Array.from(Buffer.from(value, "base64"));
10894
- const binary = atob(value);
10895
- const bytes = new Uint8Array(binary.length);
10896
- for (let i = 0; i < binary.length; i++)
10897
- bytes[i] = binary.charCodeAt(i);
10898
- return bytes;
10901
+ function serializeJSONArray(value, path, seen) {
10902
+ if (seen.has(value))
10903
+ throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
10904
+ seen.add(value);
10905
+ const indexedKeys = /* @__PURE__ */ new Set();
10906
+ for (let i = 0; i < value.length; i++) {
10907
+ if (!Object.prototype.hasOwnProperty.call(value, i))
10908
+ throw new CanonicalJSONError(`Sparse array slot at ${path}[${String(i)}] is not valid JSON.`);
10909
+ indexedKeys.add(String(i));
10910
+ }
10911
+ for (const key of Object.keys(value)) {
10912
+ if (!indexedKeys.has(key))
10913
+ throw new CanonicalJSONError(`Non-index array property ${formatPathProperty(key)} at ${path} is not valid JSON.`);
10914
+ }
10915
+ rejectEnumerableSymbolProperties(value, path);
10916
+ const serializedItems = value.map(
10917
+ (item, index) => serializeJSONValue(item, `${path}[${String(index)}]`, seen)
10918
+ );
10919
+ seen.delete(value);
10920
+ return `[${serializedItems.join(",")}]`;
10899
10921
  }
10900
- function bytesToBase64(bytes) {
10901
- if (typeof Buffer !== "undefined")
10902
- return Buffer.from(bytes).toString("base64");
10903
- let binary = "";
10904
- for (const byte of bytes)
10905
- binary += String.fromCharCode(byte);
10906
- return btoa(binary);
10922
+ function serializeJSONObject(value, path, seen) {
10923
+ if (Object.prototype.toString.call(value) !== "[object Object]")
10924
+ throw new CanonicalJSONError(`Unsupported object at ${path} is not valid JSON.`);
10925
+ if (seen.has(value))
10926
+ throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
10927
+ seen.add(value);
10928
+ rejectEnumerableSymbolProperties(value, path);
10929
+ const serializedProperties = Object.keys(value).sort(compareOrdinal).map((key) => {
10930
+ const serializedKey = JSON.stringify(key);
10931
+ const serializedValue = serializeJSONValue(
10932
+ value[key],
10933
+ `${path}${formatPathProperty(key)}`,
10934
+ seen
10935
+ );
10936
+ return `${serializedKey}:${serializedValue}`;
10937
+ });
10938
+ seen.delete(value);
10939
+ return `{${serializedProperties.join(",")}}`;
10940
+ }
10941
+ function rejectEnumerableSymbolProperties(value, path) {
10942
+ for (const symbol of Object.getOwnPropertySymbols(value)) {
10943
+ if (Object.prototype.propertyIsEnumerable.call(value, symbol))
10944
+ throw new CanonicalJSONError(`Symbol property at ${path} is not valid JSON.`);
10945
+ }
10946
+ }
10947
+ function compareOrdinal(left, right) {
10948
+ return left < right ? -1 : left > right ? 1 : 0;
10949
+ }
10950
+ function formatPathProperty(propertyName) {
10951
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName) ? `.${propertyName}` : `[${JSON.stringify(propertyName)}]`;
10907
10952
  }
10908
10953
 
10909
10954
  // src/EMHCrypt01.ts
@@ -10918,7 +10963,7 @@ var EMHCrypt01 = class extends ACrypt {
10918
10963
  async VerifyChargingSession(chargingSession) {
10919
10964
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
10920
10965
  {
10921
- for (const measurement of chargingSession.measurements) {
10966
+ for (const measurement of chargingSession.measurements ?? []) {
10922
10967
  measurement.chargingSession = chargingSession;
10923
10968
  if (measurement.values.length > 1) {
10924
10969
  for (const measurementValue of measurement.values) {
@@ -10966,8 +11011,8 @@ var EMHCrypt01 = class extends ACrypt {
10966
11011
  scale: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 30),
10967
11012
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 31, true),
10968
11013
  logBookIndex: SetHex(cryptoBuffer, measurementValue.logBookIndex, 39, false),
10969
- authorizationStart: SetText(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart["@id"], 41),
10970
- authorizationStartTimestamp: SetTimestamp32(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart.timestamp, 169)
11014
+ authorizationStart: SetText(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.["@id"] ?? "", 41),
11015
+ authorizationStartTimestamp: SetTimestamp32(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.timestamp ?? measurementValue.timestamp, 169)
10971
11016
  };
10972
11017
  const firstSignature = measurementValue.signatures?.[0];
10973
11018
  if (firstSignature != null) {
@@ -10986,7 +11031,7 @@ var EMHCrypt01 = class extends ACrypt {
10986
11031
  if (meter.publicKeys != null && meter.publicKeys.length > 0) {
10987
11032
  try {
10988
11033
  const publicKey = meter.publicKeys.at(0);
10989
- cryptoResult.publicKey = publicKey?.value?.toLowerCase();
11034
+ cryptoResult.publicKey = publicKey?.value.toLowerCase();
10990
11035
  cryptoResult.publicKeyFormat = publicKey?.format;
10991
11036
  cryptoResult.publicKeySignatures = publicKey?.signatures;
10992
11037
  try {
@@ -11014,7 +11059,7 @@ var EMHCrypt01 = class extends ACrypt {
11014
11059
  return {};
11015
11060
  }
11016
11061
  async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
11017
- if (measurementValue.measurement?.chargingSession?.authorizationStart.timestamp === void 0) {
11062
+ if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
11018
11063
  return new Error("Invalid measurement!");
11019
11064
  }
11020
11065
  const result = measurementValue.result;
@@ -11065,8 +11110,8 @@ var EMHCrypt01 = class extends ACrypt {
11065
11110
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
11066
11111
  measurementValue.measurement.chargingSession.chargingStation,
11067
11112
  measurementValue.measurement.chargingSession.EVSE,
11068
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
11069
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
11113
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
11114
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
11070
11115
  signature
11071
11116
  );
11072
11117
  signatureDiv.onclick = () => {
@@ -11083,7 +11128,7 @@ var EMHCrypt01 = class extends ACrypt {
11083
11128
  if (SignatureExpectedDiv.parentElement) {
11084
11129
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
11085
11130
  }
11086
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
11131
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
11087
11132
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
11088
11133
  else if (result.signature.value != null && result.signature.value.length > 0)
11089
11134
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -11154,7 +11199,7 @@ var GDFCrypt01 = class extends ACrypt {
11154
11199
  async VerifyChargingSession(chargingSession) {
11155
11200
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
11156
11201
  {
11157
- for (const measurement of chargingSession.measurements) {
11202
+ for (const measurement of chargingSession.measurements ?? []) {
11158
11203
  measurement.chargingSession = chargingSession;
11159
11204
  if (measurement.values.length > 1) {
11160
11205
  for (const measurementValue of measurement.values) {
@@ -11198,8 +11243,8 @@ var GDFCrypt01 = class extends ACrypt {
11198
11243
  unitEncoded: SetInt8(cryptoBuffer, measurementValue.measurement.unitEncoded ?? 0, 29),
11199
11244
  scale: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 30),
11200
11245
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 31, true),
11201
- authorizationStart: SetHex(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart["@id"], 41),
11202
- authorizationStartTimestamp: SetTimestamp(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart.timestamp, 169)
11246
+ authorizationStart: SetHex(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.["@id"] ?? "", 41),
11247
+ authorizationStartTimestamp: SetTimestamp(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.timestamp, 169)
11203
11248
  };
11204
11249
  const firstSignature = measurementValue.signatures?.[0];
11205
11250
  if (firstSignature != null) {
@@ -11218,7 +11263,7 @@ var GDFCrypt01 = class extends ACrypt {
11218
11263
  if (meter.publicKeys != null && meter.publicKeys.length > 0) {
11219
11264
  try {
11220
11265
  const publicKey = meter.publicKeys.at(0);
11221
- cryptoResult.publicKey = publicKey?.value?.toLowerCase();
11266
+ cryptoResult.publicKey = publicKey?.value.toLowerCase();
11222
11267
  cryptoResult.publicKeyFormat = publicKey?.format;
11223
11268
  cryptoResult.publicKeySignatures = publicKey?.signatures;
11224
11269
  try {
@@ -11246,7 +11291,7 @@ var GDFCrypt01 = class extends ACrypt {
11246
11291
  return {};
11247
11292
  }
11248
11293
  async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
11249
- if (measurementValue.measurement?.chargingSession?.authorizationStart.timestamp === void 0) {
11294
+ if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
11250
11295
  return new Error("Invalid measurement!");
11251
11296
  }
11252
11297
  const result = measurementValue.result;
@@ -11292,8 +11337,8 @@ var GDFCrypt01 = class extends ACrypt {
11292
11337
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
11293
11338
  measurementValue.measurement.chargingSession.chargingStation,
11294
11339
  measurementValue.measurement.chargingSession.EVSE,
11295
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
11296
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
11340
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
11341
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
11297
11342
  signature
11298
11343
  );
11299
11344
  } catch (exception) {
@@ -11306,7 +11351,7 @@ var GDFCrypt01 = class extends ACrypt {
11306
11351
  if (SignatureExpectedDiv.parentElement) {
11307
11352
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
11308
11353
  }
11309
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
11354
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
11310
11355
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
11311
11356
  else if (result.signature.value != null && result.signature.value.length > 0)
11312
11357
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -11338,7 +11383,118 @@ var GDFCrypt01 = class extends ACrypt {
11338
11383
  }
11339
11384
  return void 0;
11340
11385
  }
11341
- };
11386
+ };
11387
+
11388
+ // src/interfaces/IPublicKeyInfo.ts
11389
+ var IPublicKeyInfo_exports = {};
11390
+ __export(IPublicKeyInfo_exports, {
11391
+ IsAPublicKey: () => IsAPublicKey,
11392
+ IsAPublicKeyLookup: () => IsAPublicKeyLookup,
11393
+ IsAPublicKeySignature: () => IsAPublicKeySignature,
11394
+ IsAPublicKeyXY: () => IsAPublicKeyXY,
11395
+ PublicKeyFormats: () => PublicKeyFormats,
11396
+ isPublicKeySubject: () => isPublicKeySubject
11397
+ });
11398
+ var PublicKeyFormats = /* @__PURE__ */ ((PublicKeyFormats2) => {
11399
+ PublicKeyFormats2["DER"] = "DER";
11400
+ PublicKeyFormats2["XY"] = "XY";
11401
+ return PublicKeyFormats2;
11402
+ })(PublicKeyFormats || {});
11403
+ function IsAPublicKeyLookup(data) {
11404
+ if (!isMandatoryJSONObject(data))
11405
+ return false;
11406
+ return Array.isArray(data["publicKeys"]);
11407
+ }
11408
+ function IsAPublicKey(data) {
11409
+ if (!isMandatoryJSONObject(data))
11410
+ return false;
11411
+ if (data["@context"] !== void 0 && !isStringOrStringArray(data["@context"])) {
11412
+ return false;
11413
+ }
11414
+ if (!isPublicKeySubject(data["subject"]))
11415
+ return false;
11416
+ if (data["value"] !== void 0 && !isString(data["value"])) {
11417
+ return false;
11418
+ }
11419
+ if (data["value"] === void 0 && (data["x"] === void 0 || data["y"] === void 0)) {
11420
+ return false;
11421
+ }
11422
+ if (data["value"] !== void 0 && !isStringOrOIDInfo(data["algorithm"])) {
11423
+ return false;
11424
+ }
11425
+ if (data["certainty"] !== void 0 && (typeof data["certainty"] !== "number" || !Number.isFinite(data["certainty"]))) {
11426
+ return false;
11427
+ }
11428
+ if (data["type"] !== void 0 && !isStringOrOIDInfo(data["type"])) {
11429
+ return false;
11430
+ }
11431
+ if (data["encoding"] !== void 0 && typeof data["encoding"] !== "string") {
11432
+ return false;
11433
+ }
11434
+ if (data["signatures"] !== void 0 && (!Array.isArray(data["signatures"]) || !data["signatures"].every(IsAPublicKeySignature))) {
11435
+ return false;
11436
+ }
11437
+ return true;
11438
+ }
11439
+ function isPublicKeySubject(data) {
11440
+ if (data === void 0)
11441
+ return true;
11442
+ if (isStringOrStringArray(data))
11443
+ return true;
11444
+ if (!isMandatoryJSONObject(data))
11445
+ return false;
11446
+ return Object.values(data).every(
11447
+ (value) => typeof value === "string" || isStringOrStringArray(value)
11448
+ );
11449
+ }
11450
+ function IsAPublicKeySignature(data) {
11451
+ if (!isMandatoryJSONObject(data))
11452
+ return false;
11453
+ if (!isOptionalString(data["@id"]))
11454
+ return false;
11455
+ if (data["@context"] !== void 0 && !isStringOrStringArray(data["@context"]))
11456
+ return false;
11457
+ if (!isOptionalStringOrOIDInfo(data["algorithm"]))
11458
+ return false;
11459
+ if (!isOptionalString(data["format"]))
11460
+ return false;
11461
+ if (!isOptionalString(data["encoding"]))
11462
+ return false;
11463
+ if (data["value"] !== void 0 && !isString(data["value"]))
11464
+ return false;
11465
+ if (data["publicKey"] !== void 0 && !isEncodedValue(data["publicKey"]))
11466
+ return false;
11467
+ if (data["signature"] !== void 0 && !isEncodedValue(data["signature"]))
11468
+ return false;
11469
+ if (!isOptionalString(data["timestamp"]))
11470
+ return false;
11471
+ if (!isOptionalString(data["issuer"]))
11472
+ return false;
11473
+ if (!isOptionalString(data["signer"]))
11474
+ return false;
11475
+ if (!isOptionalString(data["notBefore"]))
11476
+ return false;
11477
+ if (!isOptionalString(data["notAfter"]))
11478
+ return false;
11479
+ if (!isOptionalStringArray(data["keyUsage"]))
11480
+ return false;
11481
+ if (data["operations"] !== void 0 && !isMandatoryJSONObject(data["operations"]))
11482
+ return false;
11483
+ if (data["comment"] !== void 0 && !isMandatoryJSONObject(data["comment"]))
11484
+ return false;
11485
+ return data["value"] !== void 0 || data["signature"] !== void 0 || data["algorithm"] !== void 0 || data["timestamp"] !== void 0 || data["issuer"] !== void 0 || data["signer"] !== void 0 || data["keyUsage"] !== void 0;
11486
+ }
11487
+ function IsAPublicKeyXY(data) {
11488
+ if (!IsAPublicKey(data))
11489
+ return false;
11490
+ if (!isString(data["x"])) {
11491
+ return false;
11492
+ }
11493
+ if (!isString(data["y"])) {
11494
+ return false;
11495
+ }
11496
+ return true;
11497
+ }
11342
11498
  var MENNEKES_EDL40_XMLNS = "http://www.mennekes.de/Mennekes.EdlVerification.xsd";
11343
11499
  var MENNEKES_EDL40_OBIS = "1-0:1.17.0*255";
11344
11500
  var Mennekes = class {
@@ -11400,15 +11556,15 @@ var Mennekes = class {
11400
11556
  return {
11401
11557
  "@id": chargingStationId,
11402
11558
  "description": { "en": "Mennekes EDL40 charging station" },
11403
- "manufacturer": "MENNEKES",
11559
+ "manufacturer": { "name": "MENNEKES" },
11404
11560
  "address": chargingProcess.siteAddress,
11405
11561
  "EVSEs": [
11406
11562
  {
11407
11563
  "@id": evseId,
11408
- "meters": [
11564
+ "energyMeters": [
11409
11565
  {
11410
11566
  "@id": meterId,
11411
- "manufacturer": "MENNEKES",
11567
+ "manufacturer": { "name": "MENNEKES" },
11412
11568
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/MennekesCrypt01",
11413
11569
  "publicKeys": [
11414
11570
  {
@@ -11486,7 +11642,7 @@ var MennekesCrypt01 = class extends ACrypt {
11486
11642
  }
11487
11643
  async VerifyChargingSession(chargingSession) {
11488
11644
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
11489
- for (const measurement of chargingSession.measurements) {
11645
+ for (const measurement of chargingSession.measurements ?? []) {
11490
11646
  measurement.chargingSession = chargingSession;
11491
11647
  if (measurement.values.length >= 2) {
11492
11648
  sessionResult = "ValidSignature" /* ValidSignature */;
@@ -11553,8 +11709,6 @@ var MennekesCrypt01 = class extends ACrypt {
11553
11709
  if (meter.publicKeys == null || meter.publicKeys.length === 0)
11554
11710
  return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
11555
11711
  const signatureExpected = measurementValue.signatures?.[0];
11556
- if (signatureExpected.r == null || signatureExpected.s == null)
11557
- return setResult("InvalidSignature" /* InvalidSignature */);
11558
11712
  const signedData = buildMennekesSignatureData(
11559
11713
  {
11560
11714
  serverId: measurement.serverId,
@@ -11576,7 +11730,7 @@ var MennekesCrypt01 = class extends ACrypt {
11576
11730
  secondIndex: measurementValue.secondsIndex ?? 0
11577
11731
  }
11578
11732
  );
11579
- cryptoResult.signedData = bytesToHex2(signedData);
11733
+ cryptoResult.signedData = bytesToHex(signedData);
11580
11734
  cryptoResult.logBytes = cryptoResult.signedData.substring(78, 82);
11581
11735
  const signedDataBuffer = signedData.buffer.slice(
11582
11736
  signedData.byteOffset,
@@ -11614,7 +11768,7 @@ var MennekesCrypt01 = class extends ACrypt {
11614
11768
  PublicKeyDiv.innerHTML = result.publicKey?.match(/.{1,8}/g)?.join(" ") ?? "";
11615
11769
  if (SignatureExpectedDiv.parentElement?.children[0])
11616
11770
  SignatureExpectedDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
11617
- 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(" ") ?? "") : "";
11771
+ SignatureExpectedDiv.innerHTML = result.signature != null && result.signature.r.length > 0 && 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(" ") ?? "") : "";
11618
11772
  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>";
11619
11773
  return Promise.resolve(void 0);
11620
11774
  }
@@ -11676,23 +11830,6 @@ function dateToMennekesLocalEpochSeconds(isoTimestamp) {
11676
11830
  const offsetSeconds = sign * (Number(offsetMatch[2]) * 3600 + Number(offsetMatch[3]) * 60);
11677
11831
  return Math.floor(date.getTime() / 1e3) + offsetSeconds;
11678
11832
  }
11679
- function cleanHex(hex) {
11680
- return hex.replace(/\s+/g, "");
11681
- }
11682
- function hexToBytes(hex) {
11683
- const cleanedHex = cleanHex(hex);
11684
- if (cleanedHex.length % 2 !== 0)
11685
- throw new Error("Hex strings must have even length!");
11686
- if (!/^[0-9a-fA-F]*$/.test(cleanedHex))
11687
- throw new Error("Invalid hexadecimal string!");
11688
- const bytes = new Uint8Array(cleanedHex.length / 2);
11689
- for (let index = 0; index < cleanedHex.length; index += 2)
11690
- bytes[index / 2] = Number.parseInt(cleanedHex.substring(index, index + 2), 16);
11691
- return bytes;
11692
- }
11693
- function bytesToHex2(bytes) {
11694
- return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
11695
- }
11696
11833
  function parseChargingProcessElement(chargingProcessElement) {
11697
11834
  const siteAddressElement = child(chargingProcessElement, "SiteAddress");
11698
11835
  return {
@@ -11830,7 +11967,7 @@ var OCMFv1_x = class extends ACrypt {
11830
11967
  async VerifyChargingSession(chargingSession) {
11831
11968
  let sessionResult = "Unvalidated" /* Unvalidated */;
11832
11969
  {
11833
- for (const measurement of chargingSession.measurements) {
11970
+ for (const measurement of chargingSession.measurements ?? []) {
11834
11971
  measurement.chargingSession = chargingSession;
11835
11972
  if (measurement.values.length > 1) {
11836
11973
  for (const measurementValue of measurement.values) {
@@ -11978,7 +12115,7 @@ var OCMFv1_x = class extends ACrypt {
11978
12115
  return new Error("Invalid measurement!");
11979
12116
  }
11980
12117
  {
11981
- 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 + ") " : "");
12118
+ 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" ? "(" + OIDInfo(measurementValue.ocmfDocument.publicKey.algorithm) + ") " : "");
11982
12119
  }
11983
12120
  {
11984
12121
  if (PlainTextDiv.parentElement) {
@@ -12021,9 +12158,9 @@ var OCMFv1_x = class extends ACrypt {
12021
12158
  }
12022
12159
  if (measurementValue.ocmfDocument.publicKey != null) {
12023
12160
  if (PublicKeyDiv.parentElement) {
12024
- 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 + ")";
12161
+ 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") + " (" + OIDInfo(measurementValue.ocmfDocument.publicKey.algorithm) + ", " + (measurementValue.ocmfDocument.publicKey.encoding ?? "-") + ")";
12025
12162
  }
12026
- 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(" ") ?? "-");
12163
+ 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(" ") ?? "-");
12027
12164
  }
12028
12165
  const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
12029
12166
  if (publicKeySignatureContainer !== void 0) {
@@ -12036,8 +12173,8 @@ var OCMFv1_x = class extends ACrypt {
12036
12173
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
12037
12174
  measurementValue.measurement.chargingSession.chargingStation,
12038
12175
  measurementValue.measurement.chargingSession.EVSE,
12039
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
12040
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
12176
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
12177
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
12041
12178
  signature
12042
12179
  );
12043
12180
  } catch {
@@ -12050,7 +12187,7 @@ var OCMFv1_x = class extends ACrypt {
12050
12187
  if (SignatureExpectedDiv.parentElement) {
12051
12188
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
12052
12189
  }
12053
- 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(" ") ?? "-");
12190
+ 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(" ") ?? "-");
12054
12191
  }
12055
12192
  if (measurementValue.measurement.chargingSession.verificationResult) {
12056
12193
  switch (measurementValue.measurement.chargingSession.verificationResult.status) {
@@ -12095,15 +12232,6 @@ var OCMF = class {
12095
12232
  //#region (private) tryToParseOCMFv1_0(OCMFDataList, ContainerInfos?)
12096
12233
  tryToParseOCMFv1_0(OCMFJSONDocuments, ContainerInfos) {
12097
12234
  try {
12098
- const containerInfos = asJSONObject(ContainerInfos) ?? {};
12099
- const chargingStationInfo = asJSONObject(containerInfos["chargingStation"]);
12100
- const evseInfo = asJSONObject(containerInfos["EVSE"]);
12101
- const connectorInfo = asJSONObject(containerInfos["connector"]);
12102
- const energyMeterInfo = asJSONObject(containerInfos["energyMeter"]);
12103
- const chargingStationId = asString(containerInfos["ChargingStationId"]) ?? asString(chargingStationInfo?.["@id"]) ?? "DE*GEF*STATION*CHARGY*1";
12104
- const evseId = asString(containerInfos["EVSEId"]) ?? asString(evseInfo?.["@id"]) ?? "DE*GEF*EVSE*CHARGY*1";
12105
- const stationDescription = asJSONObject(chargingStationInfo?.["description"]);
12106
- const evseDescription = asJSONObject(evseInfo?.["description"]);
12107
12235
  const firstOCMDJSONDocument = getFirstArrayElement(OCMFJSONDocuments, "Missing first OCMF JSON document");
12108
12236
  const formatVersion = firstOCMDJSONDocument.payload.FV;
12109
12237
  const gatewayInformation = firstOCMDJSONDocument.payload.GI ?? firstOCMDJSONDocument.payload.VI;
@@ -12176,49 +12304,71 @@ var OCMF = class {
12176
12304
  "gatewayVersion": gatewayVersion
12177
12305
  },
12178
12306
  // "chargingStationOperators": [{
12179
- "chargingPools": [{
12180
- "@id": "DE*GEF*POOL*CHARGY*1",
12181
- "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
12182
- "chargingStations": [{
12183
- "@id": chargingStationId,
12184
- "description": stationDescription && Object.keys(stationDescription).length > 0 ? stationDescription : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
12185
- "firmwareVersion": asString(chargingStationInfo?.["softwareVersion"]) ?? asString(chargingStationInfo?.["firmwareVersion"]),
12186
- "geoLocation": asJSONObject(chargingStationInfo?.["geoLocation"]),
12187
- "address": asJSONObject(chargingStationInfo?.["address"]),
12188
- "EVSEs": [{
12189
- "@id": evseId,
12190
- "description": evseDescription && Object.keys(evseDescription).length > 0 ? evseDescription : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
12191
- "connectors": connectorInfo ? [{
12192
- "type": asString(connectorInfo["type"]) ?? "",
12193
- "looses": asNumber(connectorInfo["looses"]) ?? 0
12194
- }] : void 0,
12195
- "meters": [{
12196
- "@id": effectiveMeterSerial,
12197
- // The signed OCMF payload values always win,
12198
- // the container infos only fill the gaps!
12199
- "manufacturer": meterVendor ?? asString(energyMeterInfo?.["manufacturer"]),
12200
- "manufacturerURL": asString(energyMeterInfo?.["manufacturerURL"]),
12201
- "model": meterModel ?? asString(energyMeterInfo?.["model"]),
12202
- "modelURL": asString(energyMeterInfo?.["modelURL"]),
12203
- "hardwareVersion": asString(energyMeterInfo?.["hardwareVersion"]),
12204
- "firmwareVersion": meterFirmware ?? asString(energyMeterInfo?.["firmwareVersion"]),
12205
- "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
12206
- "publicKeys": [{
12207
- "algorithm": "?",
12208
- "encoding": "?",
12209
- "format": "?",
12210
- "value": "?"
12211
- }]
12212
- }]
12213
- }]
12214
- }]
12215
- }],
12307
+ // "chargingPools": [{
12308
+ // "@id": "DE*GEF*POOL*CHARGY*1",
12309
+ // "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
12310
+ // "chargingStations": [{
12311
+ // "@id": chargingStationId,
12312
+ // "description": stationDescription && Object.keys(stationDescription).length > 0
12313
+ // ? stationDescription
12314
+ // : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
12315
+ // // "firmware": {
12316
+ // // "version": chargyLib.asString(chargingStationInfo?.["softwareVersion"])
12317
+ // // ?? chargyLib.asString(chargingStationInfo?.["firmwareVersion"])
12318
+ // // },
12319
+ // "geoLocation": chargyLib.asJSONObject(chargingStationInfo?.["geoLocation"]) as chargyInterfaces.IGeoLocation | undefined,
12320
+ // "address": chargyLib.asJSONObject(chargingStationInfo?.["address"]) as chargyInterfaces.IAddress | undefined,
12321
+ // "EVSEs": [{
12322
+ // "@id": evseId,
12323
+ // "description": evseDescription && Object.keys(evseDescription).length > 0
12324
+ // ? evseDescription
12325
+ // : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
12326
+ // "connectors": connectorInfo
12327
+ // ? [{
12328
+ // "type": chargyLib.asString(connectorInfo["type"]) ?? "",
12329
+ // "cable": {
12330
+ // "length": chargyLib.asNumber(connectorInfo["length"]) ?? 0,
12331
+ // "looses": chargyLib.asNumber(connectorInfo["looses"]) ?? 0
12332
+ // }
12333
+ // }]
12334
+ // : [],
12335
+ // "energyMeters": [{
12336
+ // "@id": effectiveMeterSerial,
12337
+ // // The signed OCMF payload values always win,
12338
+ // // the container infos only fill the gaps!
12339
+ // "manufacturer": {
12340
+ // "name": meterVendor ?? chargyLib.asString(energyMeterInfo?.["manufacturer"]),
12341
+ // "contact": {
12342
+ // "web": chargyLib.asString(energyMeterInfo?.["manufacturerURL"])
12343
+ // }
12344
+ // },
12345
+ // "model": {
12346
+ // "name": meterModel ?? chargyLib.asString(energyMeterInfo?.["model"]),
12347
+ // "url": chargyLib.asString(energyMeterInfo?.["modelURL"])
12348
+ // },
12349
+ // "hardware": {
12350
+ // "revision": chargyLib.asString(energyMeterInfo?.["hardwareVersion"])
12351
+ // },
12352
+ // "firmware": {
12353
+ // "version": meterFirmware ?? chargyLib.asString(energyMeterInfo?.["firmwareVersion"])
12354
+ // },
12355
+ // "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
12356
+ // "publicKeys": [{
12357
+ // "algorithm": "?",
12358
+ // "encoding": "?",
12359
+ // "format": "?",
12360
+ // "value": "?",
12361
+ // }]
12362
+ // }]
12363
+ // }],
12364
+ // }]
12365
+ // }],
12216
12366
  "chargingSessions": [{
12217
12367
  "@id": "1554181214441:-1965658344385548683:2",
12218
12368
  "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
12219
12369
  "begin": "?",
12220
12370
  "end": "?",
12221
- "EVSEId": evseId,
12371
+ //"EVSEId": evseId,
12222
12372
  "authorizationStart": {
12223
12373
  "@id": identificationData ?? "?",
12224
12374
  "type": identificationType ?? "?",
@@ -12231,6 +12381,8 @@ var OCMF = class {
12231
12381
  }],
12232
12382
  "certainty": 1
12233
12383
  };
12384
+ if (ContainerInfos?.chargingStations !== void 0)
12385
+ CTR.chargingStations = ContainerInfos.chargingStations;
12234
12386
  const measurementsByKey = /* @__PURE__ */ new Map();
12235
12387
  for (const ocmfJSONDocument of OCMFJSONDocuments) {
12236
12388
  let inheritedReading = {};
@@ -12363,6 +12515,10 @@ var OCMF = class {
12363
12515
  }
12364
12516
  }
12365
12517
  }
12518
+ if (ContainerInfos?.chargingStations !== void 0)
12519
+ CTR.chargingStations = ContainerInfos.chargingStations;
12520
+ if (ContainerInfos?.warnings !== void 0)
12521
+ CTR.warnings = [...CTR.warnings ?? [], ...ContainerInfos.warnings];
12366
12522
  CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
12367
12523
  if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0]) {
12368
12524
  CTR.begin = CTR.chargingSessions[0].begin;
@@ -12609,7 +12765,7 @@ var OCMF = class {
12609
12765
  x: publicKeyXY.x,
12610
12766
  y: publicKeyXY.y
12611
12767
  };
12612
- } else if (isIPublicKeyXY(OCMFJSONDocument.publicKey)) {
12768
+ } else if (IsAPublicKeyXY(OCMFJSONDocument.publicKey)) {
12613
12769
  publicKey = curve.keyFromPublic({
12614
12770
  x: OCMFJSONDocument.publicKey.x,
12615
12771
  y: OCMFJSONDocument.publicKey.y
@@ -12719,17 +12875,17 @@ var OCMF = class {
12719
12875
  // Not an OCMF standard!
12720
12876
  case "ECDSA-secp384r1-SHA384":
12721
12877
  hashAlgorithm = "SHA384, 384 Bits, hex";
12722
- hashValue = await sha256(plaintext);
12878
+ hashValue = await sha384(plaintext);
12723
12879
  break;
12724
12880
  // Not an OCMF standard!
12725
12881
  case "ECDSA-brainpool384r1-SHA384":
12726
12882
  hashAlgorithm = "SHA384, 384 Bits, hex";
12727
- hashValue = await sha256(plaintext);
12883
+ hashValue = await sha384(plaintext);
12728
12884
  break;
12729
12885
  // Not an OCMF standard!
12730
12886
  case "ECDSA-secp521r1-SHA512":
12731
12887
  hashAlgorithm = "SHA512, 512 Bits, hex";
12732
- hashValue = await sha256(plaintext);
12888
+ hashValue = await sha512(plaintext);
12733
12889
  break;
12734
12890
  // ECDSA-secp256r1-SHA256
12735
12891
  default:
@@ -12811,7 +12967,12 @@ var OCMF = class {
12811
12967
  //#endregion
12812
12968
  //#region TryToParseOCMFDocument (OCMFDocument, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
12813
12969
  async TryToParseOCMFDocument(OCMFDocument, PublicKey, PublicKeyEncoding, ContainerInfos) {
12814
- return this.TryToParseOCMFDocuments([OCMFDocument], PublicKey, PublicKeyEncoding, ContainerInfos);
12970
+ return this.TryToParseOCMFDocuments(
12971
+ [OCMFDocument],
12972
+ PublicKey,
12973
+ PublicKeyEncoding,
12974
+ ContainerInfos
12975
+ );
12815
12976
  }
12816
12977
  //#endregion
12817
12978
  //#region TryToParseOCMFDocuments(OCMFDocuments, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
@@ -12932,13 +13093,16 @@ var OCPI = class {
12932
13093
  const firstSignedData = asString(asJSONObject(signed_values[0])?.["signed_data"]);
12933
13094
  if (firstSignedData != null && firstSignedData.length > 0) {
12934
13095
  const placeInfo = asJSONObject(SomeJSON["placeInfo"]);
13096
+ const evseId = asString(placeInfo?.["evseId"]);
13097
+ const evseIdStr = asString(evseId) ?? "";
12935
13098
  const geoLocation = asJSONObject(placeInfo?.["geoLocation"]);
12936
13099
  const address = asJSONObject(placeInfo?.["address"]);
12937
13100
  const geoLat = asNumber(geoLocation?.["lat"]);
12938
13101
  const geoLon = asNumber(geoLocation?.["lon"]);
12939
13102
  const containerInfos = {
12940
- EVSEId: asString(placeInfo?.["evseId"]),
12941
- chargingStation: {
13103
+ EVSEIds: [evseId],
13104
+ chargingStations: [{
13105
+ "@id": evseIdStr.substring(0, evseIdStr.lastIndexOf("*")),
12942
13106
  geoLocation: geoLat !== void 0 && geoLon !== void 0 ? { lat: geoLat, lng: geoLon } : void 0,
12943
13107
  address: address ? {
12944
13108
  street: asString(address["street"]),
@@ -12946,8 +13110,8 @@ var OCPI = class {
12946
13110
  city: asString(address["town"]),
12947
13111
  country: asString(address["country"]) ?? ""
12948
13112
  } : void 0
12949
- },
12950
- energyMeter: asJSONObject(SomeJSON["meterInfo"])
13113
+ }]
13114
+ //energyMeter: chargyLib.asJSONObject(SomeJSON["meterInfo"])
12951
13115
  };
12952
13116
  return new OCMF(this.chargy).TryToParseOCMFDocument(
12953
13117
  firstSignedData,
@@ -12962,7 +13126,7 @@ var OCPI = class {
12962
13126
  const numberOfFormatChecks = 81;
12963
13127
  let secondaryErrors = 0;
12964
13128
  try {
12965
- const chargingSessionId = SomeJSON["@id"];
13129
+ const chargingSessionId = asString(SomeJSON["@id"]);
12966
13130
  const chargePointInfo = asJSONObject(SomeJSON["chargePointInfo"]);
12967
13131
  const evseId = chargePointInfo?.["evseId"];
12968
13132
  const placeInfo = asJSONObject(chargePointInfo?.["placeInfo"]);
@@ -13193,7 +13357,7 @@ var OCPI = class {
13193
13357
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
13194
13358
  "signatures": [
13195
13359
  {
13196
- "keyId": "...",
13360
+ "@id": "...",
13197
13361
  "algorithm": "secp192r1",
13198
13362
  "format": "DER",
13199
13363
  "value": "????"
@@ -13258,7 +13422,7 @@ var OCPI = class {
13258
13422
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
13259
13423
  // },
13260
13424
  //"connectors": [ ],
13261
- "meters": []
13425
+ "energyMeters": []
13262
13426
  }
13263
13427
  ]
13264
13428
  }
@@ -13273,29 +13437,29 @@ var OCPI = class {
13273
13437
  return new Alfen(this.chargy).TryToParseALFENFormat(
13274
13438
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
13275
13439
  {
13276
- chargingSession: {
13277
- "@id": chargingSessionId
13278
- },
13279
- EVSEId: evseId,
13280
- chargingStation: {
13281
- manufacturer: chargingStation_manufacturer,
13282
- type: chargingStation_type,
13283
- serialNumber: chargingStation_serialNumber,
13284
- firmwareVersion: chargingStation_controllerSoftwareVersion,
13285
- legalCompliance: {
13286
- conformity: [{
13287
- freeText: chargingStation_compliance
13288
- }],
13289
- calibration: [{
13290
- freeText: chargingStation_calibration
13291
- }]
13292
- },
13293
- geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
13294
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
13295
- },
13296
- energyMeter: meterInfo,
13297
- connector: connectorInfo,
13298
- chargingCosts: chargingCostsInfo
13440
+ // chargingSessions: [{
13441
+ // "@id": chargingSessionId ?? ""
13442
+ // }],
13443
+ // // EVSEId: evseId,
13444
+ // chargingStations: [{
13445
+ // manufacturer: chargingStation_manufacturer,
13446
+ // type: chargingStation_type,
13447
+ // serialNumber: chargingStation_serialNumber,
13448
+ // firmwareVersion: chargingStation_controllerSoftwareVersion,
13449
+ // legalCompliance: {
13450
+ // conformity: [{
13451
+ // freeText: chargingStation_compliance
13452
+ // }],
13453
+ // calibration: [{
13454
+ // freeText: chargingStation_calibration
13455
+ // }]
13456
+ // },
13457
+ // geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
13458
+ // address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
13459
+ // }],
13460
+ // energyMeter: meterInfo,
13461
+ // connector: connectorInfo,
13462
+ // chargingCosts: chargingCostsInfo
13299
13463
  }
13300
13464
  );
13301
13465
  }
@@ -13546,7 +13710,7 @@ var PCDFCrypt01 = class extends ACrypt {
13546
13710
  async VerifyChargingSession(chargingSession) {
13547
13711
  let sessionResult = "ValidSignature" /* ValidSignature */;
13548
13712
  let valueCount = 0;
13549
- for (const measurement of chargingSession.measurements) {
13713
+ for (const measurement of chargingSession.measurements ?? []) {
13550
13714
  measurement.chargingSession = chargingSession;
13551
13715
  for (const measurementValue of measurement.values) {
13552
13716
  valueCount++;
@@ -13645,10 +13809,10 @@ var PCDF = class {
13645
13809
  "de": "Porsche Charging Data Format Ladevorgang",
13646
13810
  "en": "Porsche Charging Data Format charging session"
13647
13811
  },
13648
- "contract": {
13812
+ "contracts": [{
13649
13813
  "@id": data.session.idTag,
13650
13814
  "type": data.session.idTagType
13651
- },
13815
+ }],
13652
13816
  "pcdf": {
13653
13817
  "chargingSessionCounter": data.chargingSessionCounter,
13654
13818
  "timeValid": data.timeValid,
@@ -13667,11 +13831,17 @@ var PCDF = class {
13667
13831
  "EVSEs": [{
13668
13832
  "@id": virtualEVSEId,
13669
13833
  "description": { "en": "GraphDefined CHARGY Virtual EVSE 1" },
13670
- "meters": [{
13834
+ "energyMeters": [{
13671
13835
  "@id": meterId,
13672
- "manufacturer": "Porsche",
13673
- "model": data.dcMeterType === 0 ? "PES DCMeter EU" : "Unknown DC Meter",
13674
- "firmwareChecksum": data.softwareChecksum,
13836
+ "manufacturer": {
13837
+ "name": "Porsche"
13838
+ },
13839
+ "model": {
13840
+ "name": data.dcMeterType === 0 ? "PES DCMeter EU" : "Unknown DC Meter"
13841
+ },
13842
+ "firmware": {
13843
+ "checksum": data.softwareChecksum
13844
+ },
13675
13845
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/PCDF+json",
13676
13846
  "publicKeys": [{
13677
13847
  "algorithm": "secp256r1",
@@ -13870,60 +14040,101 @@ var SAFEXML = class _SAFEXML {
13870
14040
  constructor(chargy) {
13871
14041
  this.chargy = chargy;
13872
14042
  }
13873
- static ParseChargingStationContext(XMLDocument) {
13874
- const chargingStationElement = getElementsByLocalName(XMLDocument, "chargingStation").at(0);
13875
- if (chargingStationElement === void 0)
13876
- return {};
13877
- const chargingStationAttributeId = chargingStationElement.getAttribute("id")?.trim();
13878
- const chargingStationId = chargingStationAttributeId != null && chargingStationAttributeId.length > 0 ? chargingStationAttributeId : getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "id"));
13879
- const softwareVersion = getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "softwareVersion"));
13880
- const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
13881
- const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "latitude")) ?? "");
13882
- const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "longitude")) ?? "");
13883
- const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
13884
- if (getDirectChildByLocalName(chargingStationElement, "EVSEs") !== void 0)
13885
- throw new Error("The SAFE chargingStation XML element must contain EVSE directly and no EVSEs container element!");
13886
- const evseElements = getDirectChildrenByLocalName(chargingStationElement, "EVSE");
13887
- if (evseElements.length > 1)
13888
- throw new Error("The SAFE chargingStation XML element must not contain more than one EVSE element!");
13889
- const evseElement = evseElements.at(0);
13890
- const evseAttributeId = evseElement?.getAttribute("id")?.trim();
13891
- const evseTextId = getTrimmedTextContent(getDirectChildByLocalName(evseElement ?? chargingStationElement, "id"));
13892
- const evseId = evseAttributeId != null && evseAttributeId.length > 0 ? evseAttributeId : evseTextId ?? "";
13893
- const connectorElements = evseElement !== void 0 ? getDirectChildrenByLocalName(evseElement, "connector") : [];
13894
- if (connectorElements.length > 1)
13895
- throw new Error("The SAFE EVSE XML element must not contain more than one connector element!");
13896
- const connectorElement = connectorElements.at(0);
13897
- const connectorId = connectorElement?.getAttribute("id")?.trim();
13898
- const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement ?? evseElement ?? chargingStationElement, "type"));
13899
- const connector = connectorType != null && connectorType.length > 0 ? { "@id": connectorId, type: connectorType, looses: 0 } : void 0;
13900
- const parsedEVSE = evseElement !== void 0 ? {
13901
- "@id": evseId,
13902
- "description": parseDescription(evseElement),
13903
- "meters": [],
13904
- "connector": connector
13905
- } : void 0;
13906
- const chargingStation = {
13907
- "@id": chargingStationId ?? "",
13908
- "description": parseDescription(chargingStationElement),
13909
- "firmwareVersion": softwareVersion,
13910
- "softwareVersion": softwareVersion,
13911
- "geoLocation": geoLocation,
13912
- "EVSE": parsedEVSE
14043
+ static ParseContainerInfos(XMLDocument, chargy) {
14044
+ const containerInfos = {};
14045
+ const addWarning = (message) => {
14046
+ containerInfos.warnings ??= [];
14047
+ containerInfos.warnings.push(
14048
+ CreateWarning(chargy.GetMultilanguageText(message))
14049
+ );
13913
14050
  };
13914
- return {
13915
- "ChargingStationId": chargingStationId,
13916
- "EVSEId": parsedEVSE?.["@id"],
13917
- "chargingStation": chargingStation,
13918
- "EVSE": parsedEVSE,
13919
- "connector": parsedEVSE?.connector
14051
+ const chargingStationElements = getElementsByLocalName(XMLDocument, "chargingStation");
14052
+ if (chargingStationElements.length == 0)
14053
+ return containerInfos;
14054
+ if (chargingStationElements.length > 1)
14055
+ addWarning("Only one chargingStation element is allowed within the given SAFE XML container!");
14056
+ if (chargingStationElements[0] === void 0) {
14057
+ addWarning("The chargingStation element within the given SAFE XML container is invalid!");
14058
+ return containerInfos;
14059
+ }
14060
+ const chargingStationElement = chargingStationElements[0];
14061
+ const chargingStationId = chargingStationElement.getAttribute("id")?.trim();
14062
+ if (chargingStationId === void 0 || chargingStationId.length == 0) {
14063
+ addWarning("The chargingStation identifier within the given SAFE XML container is invalid!");
14064
+ return containerInfos;
14065
+ }
14066
+ const chargingStation = {
14067
+ "@id": chargingStationId
13920
14068
  };
14069
+ containerInfos.chargingStations = [chargingStation];
14070
+ const description = parseDescription(chargingStationElement);
14071
+ if (description !== void 0)
14072
+ chargingStation.description = description;
14073
+ const firmware = getDirectChildByLocalName(chargingStationElement, "firmware");
14074
+ if (firmware !== void 0) {
14075
+ chargingStation.firmware = {};
14076
+ const firmwareVersion = getTrimmedTextContent(getDirectChildByLocalName(firmware, "version"));
14077
+ if (firmwareVersion !== void 0)
14078
+ chargingStation.firmware.version = firmwareVersion;
14079
+ const firmwareChecksum = getTrimmedTextContent(getDirectChildByLocalName(firmware, "checksum"));
14080
+ if (firmwareChecksum !== void 0)
14081
+ chargingStation.firmware.checksum = firmwareChecksum;
14082
+ if (Object.keys(chargingStation.firmware).length === 0)
14083
+ delete chargingStation.firmware;
14084
+ }
14085
+ const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
14086
+ if (geoLocationElement !== void 0) {
14087
+ const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement, "latitude")) ?? "");
14088
+ const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement, "longitude")) ?? "");
14089
+ const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
14090
+ if (geoLocation !== void 0)
14091
+ chargingStation.geoLocation = geoLocation;
14092
+ }
14093
+ const evseElements = getElementsByLocalName(chargingStationElement, "EVSE");
14094
+ if (evseElements.length > 1)
14095
+ addWarning("Only one EVSE element is allowed within the given SAFE XML chargingStation element!");
14096
+ if (evseElements[0] === void 0) {
14097
+ addWarning("The EVSE element within the given SAFE XML chargingStation element is invalid!");
14098
+ return containerInfos;
14099
+ }
14100
+ const evseElement = evseElements[0];
14101
+ const evseId = evseElement.getAttribute("id")?.trim();
14102
+ if (evseId !== void 0 && evseId.length > 0) {
14103
+ const evse = {
14104
+ "@id": evseId
14105
+ };
14106
+ chargingStation.EVSEs = [evse];
14107
+ const evseDescription = parseDescription(evseElement);
14108
+ if (evseDescription !== void 0)
14109
+ evse.description = evseDescription;
14110
+ const connectorElements = getElementsByLocalName(evseElement, "connector");
14111
+ if (connectorElements.length > 1)
14112
+ addWarning("Only one connector element is allowed within the given SAFE XML EVSE element!");
14113
+ if (connectorElements[0] === void 0) {
14114
+ addWarning("The connector element within the given SAFE XML EVSE element is invalid!");
14115
+ return containerInfos;
14116
+ }
14117
+ const connectorElement = connectorElements[0];
14118
+ const connector = {};
14119
+ const connectorId = connectorElement.getAttribute("id")?.trim();
14120
+ if (connectorId != null && connectorId.length > 0)
14121
+ connector["@id"] = connectorId;
14122
+ const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement, "type"));
14123
+ if (connectorType !== void 0 && connectorType.length > 0)
14124
+ connector.type = connectorType;
14125
+ if (Object.keys(connector).length > 0)
14126
+ evse.connectors = [connector];
14127
+ }
14128
+ return containerInfos;
13921
14129
  }
13922
14130
  //#region tryToParseSAFEXML(XMLDocument)
13923
14131
  async tryToParseSAFEXML(XMLDocument) {
13924
14132
  try {
13925
14133
  if (XMLDocument.documentElement.nodeName === "values" || XMLDocument.documentElement.localName === "values") {
13926
- const safeXMLContext = _SAFEXML.ParseChargingStationContext(XMLDocument);
14134
+ const safeXMLContext = _SAFEXML.ParseContainerInfos(
14135
+ XMLDocument,
14136
+ this.chargy
14137
+ );
13927
14138
  const signedDataValues = new Array();
13928
14139
  let commonSignedDataFormat = "";
13929
14140
  let commonSignedDataEncoding = "";
@@ -14319,10 +14530,10 @@ var ChargeIT = class {
14319
14530
  CTR["@id"] = lastMeterValue["transactionId"];
14320
14531
  CTR.begin = this.chargy.moment.unix(firstMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
14321
14532
  CTR.end = this.chargy.moment.unix(lastMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
14322
- CTR.contract = {
14533
+ CTR.contracts = [{
14323
14534
  "@id": firstMeterValue["contract"]["id"],
14324
14535
  "@context": firstMeterValue["contract"]["type"]
14325
- };
14536
+ }];
14326
14537
  CTR.chargingStationOperators = [{
14327
14538
  "@id": "chargeITmobilityCSO",
14328
14539
  "description": { "de": "chargeIT mobility GmbH - Charging Station Operator Services" },
@@ -14380,7 +14591,9 @@ var ChargeIT = class {
14380
14591
  // "description": {
14381
14592
  // "de": "GraphDefined Charging Station - CI-Tests Pool 3 / Station A"
14382
14593
  // },
14383
- "firmwareVersion": firstMeterValue["chargePoint"]["softwareVersion"],
14594
+ "firmware": {
14595
+ "version": firstMeterValue["chargePoint"]["softwareVersion"]
14596
+ },
14384
14597
  "geoLocation": { "lat": asNumber(geoLocation["lat"]) ?? 0, "lng": asNumber(geoLocation["lon"]) ?? 0 },
14385
14598
  "address": {
14386
14599
  "street": asString(address["street"]),
@@ -14395,22 +14608,32 @@ var ChargeIT = class {
14395
14608
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
14396
14609
  // },
14397
14610
  // "connectors": [{ }],
14398
- "meters": [
14611
+ "energyMeters": [
14399
14612
  {
14400
14613
  "@id": firstMeterValue["meterInfo"]["meterId"],
14401
- "manufacturer": firstMeterValue["meterInfo"]["manufacturer"],
14402
- "manufacturerURL": "https://www.emh-metering.de",
14403
- "model": firstMeterValue["meterInfo"]["type"],
14404
- "hardwareVersion": "1.0",
14405
- "firmwareVersion": firstMeterValue["meterInfo"]["firmwareVersion"],
14614
+ "manufacturer": {
14615
+ "name": firstMeterValue["meterInfo"]["manufacturer"],
14616
+ "contact": {
14617
+ "web": "https://www.emh-metering.de"
14618
+ }
14619
+ },
14620
+ "model": {
14621
+ "name": firstMeterValue["meterInfo"]["type"]
14622
+ },
14623
+ "hardware": {
14624
+ "revision": "1.0"
14625
+ },
14626
+ "firmware": {
14627
+ "version": firstMeterValue["meterInfo"]["firmwareVersion"]
14628
+ },
14406
14629
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
14407
14630
  "publicKeys": [
14408
14631
  {
14409
14632
  "algorithm": "secp192r1",
14410
14633
  "format": "DER",
14411
14634
  "encoding": "hex",
14412
- "value": firstMeterValue["meterInfo"]["publicKey"].startsWith("04") ? firstMeterValue["meterInfo"]["publicKey"] : "04" + firstMeterValue["meterInfo"]["publicKey"],
14413
- "signatures": firstMeterValue["meterInfo"]["publicKeySignatures"]
14635
+ "value": firstMeterValue["meterInfo"]["publicKey"].startsWith("04") ? firstMeterValue["meterInfo"]["publicKey"] : "04" + firstMeterValue["meterInfo"]["publicKey"]
14636
+ //"signatures": firstMeterValue["meterInfo"]["publicKeySignatures"]
14414
14637
  }
14415
14638
  ]
14416
14639
  }
@@ -14719,10 +14942,10 @@ var ChargeIT = class {
14719
14942
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
14720
14943
  "signatures": [
14721
14944
  {
14722
- "keyId": "...",
14945
+ "@id": "...",
14723
14946
  "algorithm": "secp192r1",
14724
14947
  "format": "DER",
14725
- "value": "????"
14948
+ "value": "..."
14726
14949
  }
14727
14950
  ]
14728
14951
  },
@@ -14781,7 +15004,7 @@ var ChargeIT = class {
14781
15004
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
14782
15005
  // },
14783
15006
  //"connectors": [ ],
14784
- "meters": []
15007
+ "energyMeters": []
14785
15008
  }
14786
15009
  ]
14787
15010
  }
@@ -14803,11 +15026,15 @@ var ChargeIT = class {
14803
15026
  return new Alfen(this.chargy).TryToParseALFENFormat(
14804
15027
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
14805
15028
  {
14806
- EVSEId: evseId,
14807
- chargingStation: {
15029
+ chargingStations: [{
15030
+ "@id": "?",
14808
15031
  geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
14809
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
14810
- }
15032
+ address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country },
15033
+ EVSEs: [{
15034
+ "@id": evseId,
15035
+ energyMeters: []
15036
+ }]
15037
+ }]
14811
15038
  }
14812
15039
  );
14813
15040
  }
@@ -14815,11 +15042,15 @@ var ChargeIT = class {
14815
15042
  return new Alfen(this.chargy).TryToParseALFENFormat(
14816
15043
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
14817
15044
  {
14818
- EVSEId: evseId,
14819
- chargingStation: {
15045
+ chargingStations: [{
15046
+ "@id": "?",
14820
15047
  geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
14821
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
14822
- }
15048
+ address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country },
15049
+ EVSEs: [{
15050
+ "@id": evseId,
15051
+ energyMeters: []
15052
+ }]
15053
+ }]
14823
15054
  }
14824
15055
  );
14825
15056
  if (signedMeterValueContext === oldChargeITMeterValueFormat)
@@ -14894,7 +15125,6 @@ var ChargeIT = class {
14894
15125
  const connectorInfo_type = connectorInfo?.["type"];
14895
15126
  const connectorInfo_losses = connectorInfo?.["losses"];
14896
15127
  const chargingTariffs = SomeJSON["chargingTariffs"];
14897
- const chargingPeriods = SomeJSON["chargingPeriods"];
14898
15128
  const totalCosts = asJSONObject(SomeJSON["totalCosts"]);
14899
15129
  const totalCosts_total = totalCosts?.["total"];
14900
15130
  const totalCosts_currency = totalCosts?.["currency"];
@@ -15087,10 +15317,10 @@ var ChargeIT = class {
15087
15317
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
15088
15318
  "signatures": [
15089
15319
  {
15090
- "keyId": "...",
15320
+ "@id": "...",
15091
15321
  "algorithm": "secp192r1",
15092
15322
  "format": "DER",
15093
- "value": "????"
15323
+ "value": "..."
15094
15324
  }
15095
15325
  ]
15096
15326
  },
@@ -15152,7 +15382,7 @@ var ChargeIT = class {
15152
15382
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
15153
15383
  // },
15154
15384
  //"connectors": [ ],
15155
- "meters": []
15385
+ "energyMeters": []
15156
15386
  }
15157
15387
  ]
15158
15388
  }
@@ -15169,31 +15399,31 @@ var ChargeIT = class {
15169
15399
  return new Alfen(this.chargy).TryToParseALFENFormat(
15170
15400
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
15171
15401
  {
15172
- chargingSession: {
15173
- "@id": chargingSessionId
15174
- },
15175
- EVSEId: evseId,
15176
- chargingStation: {
15177
- manufacturer: chargingStation_manufacturer,
15178
- type: chargingStation_type,
15179
- serialNumber: chargingStation_serialNumber,
15180
- firmwareVersion: chargingStation_controllerSoftwareVersion,
15181
- legalCompliance: {
15182
- conformity: [{
15183
- freeText: chargingStation_compliance
15184
- }],
15185
- calibration: [{
15186
- freeText: chargingStation_calibration
15187
- }]
15188
- },
15189
- geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
15190
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
15191
- },
15192
- energyMeter: meterInfo,
15193
- connector: connectorInfo,
15194
- chargingTariffs,
15195
- chargingPeriods,
15196
- totalCosts
15402
+ // chargingSession: {
15403
+ // "@id": chargingSessionId
15404
+ // },
15405
+ // EVSEId: evseId,
15406
+ // chargingStation: {
15407
+ // manufacturer: chargingStation_manufacturer,
15408
+ // type: chargingStation_type,
15409
+ // serialNumber: chargingStation_serialNumber,
15410
+ // firmwareVersion: chargingStation_controllerSoftwareVersion,
15411
+ // legalCompliance: {
15412
+ // conformity: [{
15413
+ // freeText: chargingStation_compliance
15414
+ // }],
15415
+ // calibration: [{
15416
+ // freeText: chargingStation_calibration
15417
+ // }]
15418
+ // },
15419
+ // geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
15420
+ // address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
15421
+ // },
15422
+ // energyMeter: meterInfo,
15423
+ // connector: connectorInfo,
15424
+ // chargingTariffs: chargingTariffs,
15425
+ // chargingPeriods: chargingPeriods,
15426
+ // totalCosts: totalCosts
15197
15427
  }
15198
15428
  );
15199
15429
  }
@@ -15325,12 +15555,18 @@ var ChargePoint = class {
15325
15555
  "address": asJSONObject(SomeJSON["address"]),
15326
15556
  "EVSEs": [{
15327
15557
  "@id": evseId,
15328
- "meters": [{
15558
+ "energyMeters": [{
15329
15559
  "@id": meterSerial,
15330
- "manufacturer": "Carlo Gavazzi",
15331
- "manufacturerURL": "https://www.gavazziautomation.com",
15332
- "model": "EM340-DIN.AV2.3.X.S1.X",
15333
- "modelURL": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
15560
+ "manufacturer": {
15561
+ "name": "Carlo Gavazzi",
15562
+ "contact": {
15563
+ "web": "https://www.gavazziautomation.com"
15564
+ }
15565
+ },
15566
+ "model": {
15567
+ "name": "EM340-DIN.AV2.3.X.S1.X",
15568
+ "url": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
15569
+ }
15334
15570
  // "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
15335
15571
  // "publicKeys": [
15336
15572
  // {
@@ -15485,12 +15721,18 @@ var ChargePoint = class {
15485
15721
  "address": asJSONObject(SomeJSON["address"]),
15486
15722
  "EVSEs": [{
15487
15723
  "@id": evseId,
15488
- "meters": [{
15724
+ "energyMeters": [{
15489
15725
  "@id": meterSerial,
15490
- "manufacturer": "Carlo Gavazzi",
15491
- "manufacturerURL": "https://www.gavazziautomation.com",
15492
- "model": "EM340-DIN.AV2.3.X.S1.X",
15493
- "modelURL": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf",
15726
+ "manufacturer": {
15727
+ "name": "Carlo Gavazzi",
15728
+ "contact": {
15729
+ "web": "https://www.gavazziautomation.com"
15730
+ }
15731
+ },
15732
+ "model": {
15733
+ "name": "EM340-DIN.AV2.3.X.S1.X",
15734
+ "url": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
15735
+ },
15494
15736
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
15495
15737
  "signatureInfos": {
15496
15738
  "hash": "SHA256",
@@ -15502,7 +15744,8 @@ var ChargePoint = class {
15502
15744
  "publicKeys": [{
15503
15745
  "algorithm": "secp224k1",
15504
15746
  "format": "DER",
15505
- "encoding": "hex"
15747
+ "encoding": "hex",
15748
+ "value": "..."
15506
15749
  }]
15507
15750
  }]
15508
15751
  }]
@@ -15604,7 +15847,7 @@ var ChargePointCrypt01 = class extends ACrypt {
15604
15847
  s: ASN1Signature.s.toString(16)
15605
15848
  };
15606
15849
  }
15607
- const publicKeyId = chargingSession.EVSEId.replace(/:/g, "").replace(/-/g, "_");
15850
+ const publicKeyId = chargingSession.EVSEId?.replace(/:/g, "").replace(/-/g, "_");
15608
15851
  const publicKeys = [];
15609
15852
  if (chargingSession.ctr.publicKeys != null) {
15610
15853
  for (const publicKeyInfo of chargingSession.ctr.publicKeys) {
@@ -15635,8 +15878,8 @@ var ChargePointCrypt01 = class extends ACrypt {
15635
15878
  sha225Value = sha225Value ?? (BigInt("0x" + await sha256(plainText)) >> BigInt(31)).toString(16);
15636
15879
  sessionResult = this.curve224k1.validate(
15637
15880
  BigInt("0x" + sha225Value),
15638
- BigInt("0x" + (chargingSession.signature.r ?? "00")),
15639
- BigInt("0x" + (chargingSession.signature.s ?? "00")),
15881
+ BigInt("0x" + chargingSession.signature.r),
15882
+ BigInt("0x" + chargingSession.signature.s),
15640
15883
  [
15641
15884
  BigInt("0x" + publicKey.value.slice(2, 58)),
15642
15885
  BigInt("0x" + publicKey.value.slice(58, 114))
@@ -15684,7 +15927,7 @@ var ChargePointCrypt01 = class extends ACrypt {
15684
15927
  }
15685
15928
  }
15686
15929
  }
15687
- for (const measurement of chargingSession.measurements) {
15930
+ for (const measurement of chargingSession.measurements ?? []) {
15688
15931
  measurement.chargingSession = chargingSession;
15689
15932
  if (measurement.values.length > 1) {
15690
15933
  for (const measurementValue of measurement.values) {
@@ -15827,8 +16070,8 @@ var ChargePointCrypt01 = class extends ACrypt {
15827
16070
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
15828
16071
  measurementValue.measurement.chargingSession.chargingStation,
15829
16072
  measurementValue.measurement.chargingSession.EVSE,
15830
- measurementValue.measurement.chargingSession.EVSE?.meters[0],
15831
- measurementValue.measurement.chargingSession.EVSE?.meters[0]?.publicKeys?.[0],
16073
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.[0],
16074
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.[0]?.publicKeys?.[0],
15832
16075
  signature
15833
16076
  );
15834
16077
  } catch {
@@ -15841,7 +16084,7 @@ var ChargePointCrypt01 = class extends ACrypt {
15841
16084
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (secrrct.sign, rs, hex)";
15842
16085
  }
15843
16086
  if (typeof chargingSession.signature != "string")
15844
- 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(" ") ?? "");
16087
+ 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(" ") ?? "");
15845
16088
  else if (chargingSession.signature)
15846
16089
  SignatureExpectedDiv.innerHTML = chargingSession.signature.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
15847
16090
  }
@@ -15879,7 +16122,8 @@ var IChargeTransparencyRecord_exports = {};
15879
16122
  __export(IChargeTransparencyRecord_exports, {
15880
16123
  CloneCTR: () => CloneCTR,
15881
16124
  IsAChargeTransparencyRecord: () => IsAChargeTransparencyRecord,
15882
- IsASessionCryptoResult: () => IsASessionCryptoResult
16125
+ IsASessionCryptoResult: () => IsASessionCryptoResult,
16126
+ toSessionVerificationResults: () => toSessionVerificationResults
15883
16127
  });
15884
16128
  function IsAChargeTransparencyRecord(data) {
15885
16129
  if (!isMandatoryJSONObject(data))
@@ -15897,7 +16141,7 @@ function CloneCTR(CTR) {
15897
16141
  const clonedCTR = JSON.parse(JSON.stringify(CTR));
15898
16142
  if (clonedCTR.chargingSessions) {
15899
16143
  for (const session of clonedCTR.chargingSessions) {
15900
- for (const measurement of session.measurements) {
16144
+ for (const measurement of session.measurements ?? []) {
15901
16145
  for (const value of measurement.values) {
15902
16146
  if (typeof value.value === "string" || typeof value.value === "number")
15903
16147
  value.value = new Decimal(value.value);
@@ -15907,6 +16151,16 @@ function CloneCTR(CTR) {
15907
16151
  }
15908
16152
  return clonedCTR;
15909
16153
  }
16154
+ function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
16155
+ const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
16156
+ if (verificationResults.length > 0)
16157
+ return verificationResults;
16158
+ return {
16159
+ status: "Unvalidated" /* Unvalidated */,
16160
+ message: noRecordsMessage,
16161
+ certainty: 0
16162
+ };
16163
+ }
15910
16164
 
15911
16165
  // src/interfaces/IChargeTransparencyLiveLink.ts
15912
16166
  var IChargeTransparencyLiveLink_exports = {};
@@ -15937,43 +16191,11 @@ function isTransport(data) {
15937
16191
  function IsAChargeTransparencyLiveLink(data) {
15938
16192
  if (!isMandatoryJSONObject(data))
15939
16193
  return false;
15940
- return data["@context"] === ChargeTransparencyLiveLinkContext && (data["timestamp"] === void 0 || data["timestamp"] === null || typeof data["timestamp"] === "string") && (data["description"] === void 0 || isMultilanguageText(data["description"])) && (data["imageURLs"] === void 0 || Array.isArray(data["imageURLs"]) && data["imageURLs"].every((value) => typeof value === "string")) && (data["geoLocation"] === void 0 || isGeoLocation(data["geoLocation"])) && (data["connector"] === void 0 || isConnector(data["connector"])) && (data["transports"] === void 0 || Array.isArray(data["transports"]) && data["transports"].every(isTransport)) && (data["signatures"] === void 0 || Array.isArray(data["signatures"]));
16194
+ return data["@context"] === ChargeTransparencyLiveLinkContext && (data["timestamp"] === void 0 || data["timestamp"] === null || typeof data["timestamp"] === "string") && (data["description"] === void 0 || isI18NString(data["description"])) && (data["imageURLs"] === void 0 || Array.isArray(data["imageURLs"]) && data["imageURLs"].every((value) => typeof value === "string")) && (data["geoLocation"] === void 0 || isGeoLocation(data["geoLocation"])) && (data["connector"] === void 0 || isConnector(data["connector"])) && (data["transports"] === void 0 || Array.isArray(data["transports"]) && data["transports"].every(isTransport)) && (data["signatures"] === void 0 || Array.isArray(data["signatures"]));
15941
16195
  }
15942
16196
  function isTOTPConfig(data) {
15943
16197
  return isObject(data) && typeof data["initialSharedSecret"] === "string" && typeof data["timeStep"] === "number";
15944
16198
  }
15945
-
15946
- // src/interfaces/IPublicKeyInfo.ts
15947
- var IPublicKeyInfo_exports = {};
15948
- __export(IPublicKeyInfo_exports, {
15949
- IsAPublicKeyInfo: () => IsAPublicKeyInfo,
15950
- IsAPublicKeyLookup: () => IsAPublicKeyLookup
15951
- });
15952
- function IsAPublicKeyLookup(data) {
15953
- if (!isMandatoryJSONObject(data))
15954
- return false;
15955
- return Array.isArray(data["publicKeys"]);
15956
- }
15957
- function IsAPublicKeyInfo(data) {
15958
- if (!isMandatoryJSONObject(data))
15959
- return false;
15960
- if (!isStringOrStringArray(data["@context"])) return false;
15961
- if (!isString(data["value"])) return false;
15962
- if (!isStringOrOIDInfo(data["algorithm"])) return false;
15963
- if (data["certainty"] !== void 0 && (typeof data["certainty"] !== "number" || !Number.isFinite(data["certainty"]))) {
15964
- return false;
15965
- }
15966
- if (data["type"] !== void 0 && !isStringOrOIDInfo(data["type"])) {
15967
- return false;
15968
- }
15969
- if (data["encoding"] !== void 0 && typeof data["encoding"] !== "string") {
15970
- return false;
15971
- }
15972
- if (data["signatures"] !== void 0 && !Array.isArray(data["signatures"])) {
15973
- return false;
15974
- }
15975
- return true;
15976
- }
15977
16199
  function isRecord(value) {
15978
16200
  return typeof value === "object" && value !== null;
15979
16201
  }
@@ -16231,45 +16453,6 @@ var Chargy = class {
16231
16453
  return fileName.substring(0, lastDot);
16232
16454
  return fileName;
16233
16455
  }
16234
- tryExtractChargeTransparencyTextFromURL(qrText) {
16235
- if (!qrText.startsWith("http://") && !qrText.startsWith("https://"))
16236
- return qrText;
16237
- try {
16238
- const url = new URL(qrText);
16239
- const candidates = [
16240
- url.hash.startsWith("#") ? url.hash.substring(1) : url.hash,
16241
- url.searchParams.get("data"),
16242
- url.searchParams.get("content"),
16243
- url.searchParams.get("ctr"),
16244
- url.searchParams.get("record"),
16245
- url.searchParams.get("payload"),
16246
- url.searchParams.get("q")
16247
- ];
16248
- for (const candidate of candidates) {
16249
- const decodedCandidate = candidate != null ? decodeURIComponent(candidate).trim() : "";
16250
- if (decodedCandidate.startsWith("<?xml") || decodedCandidate.startsWith("<values") || decodedCandidate.startsWith("{") || decodedCandidate.startsWith("[") || decodedCandidate.startsWith("OCMF") || decodedCandidate.startsWith("AP;")) {
16251
- return decodedCandidate;
16252
- }
16253
- }
16254
- } catch {
16255
- console.log("Invalid URL in QR code: " + qrText);
16256
- }
16257
- return qrText;
16258
- }
16259
- tryExtractSignedDataTextFromXML(qrText) {
16260
- const trimmedQRCodeText = qrText.trim();
16261
- if (!trimmedQRCodeText.startsWith("<?xml") && !trimmedQRCodeText.startsWith("<"))
16262
- return qrText;
16263
- try {
16264
- const xmlDocument = new DOMParser().parseFromString(trimmedQRCodeText, "text/xml");
16265
- const signedDataValues = getElementsByLocalName(xmlDocument, "signedData").filter((signedData) => (signedData.getAttribute("format") ?? "").trim().toLowerCase() === "alfen").map((signedData) => signedData.textContent.trim()).filter((signedData) => signedData.startsWith("AP;"));
16266
- if (signedDataValues.length > 0)
16267
- return signedDataValues.join("\n");
16268
- } catch {
16269
- console.log("Error parsing XML content from QR code: " + qrText);
16270
- }
16271
- return qrText;
16272
- }
16273
16456
  //#region Public key methods...
16274
16457
  PublicKeyIdFromFileName(fileName) {
16275
16458
  return (fileName.includes(".") ? fileName.substring(0, fileName.indexOf(".")) : fileName).replace(/[-_]?public[-_]?key/i, "");
@@ -16355,25 +16538,70 @@ var Chargy = class {
16355
16538
  }
16356
16539
  //#endregion
16357
16540
  //#region QR code image files...
16358
- isSupportedQRCodeImageFile(fileInfo, mimeType) {
16359
- const mimeTypeToCheck = (mimeType ?? fileInfo.type ?? "").toLowerCase();
16360
- const fileName = fileInfo.name.toLowerCase();
16361
- return mimeTypeToCheck === "image/png" || mimeTypeToCheck === "image/jpeg" || mimeTypeToCheck === "image/jpg" || mimeTypeToCheck === "image/gif" || mimeTypeToCheck === "image/webp" || mimeTypeToCheck === "image/bmp" || mimeTypeToCheck === "image/svg+xml" || fileName.endsWith(".png") || fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || fileName.endsWith(".gif") || fileName.endsWith(".webp") || fileName.endsWith(".bmp") || fileName.endsWith(".svg");
16541
+ normalizeMIMEType(mimeType) {
16542
+ return mimeType?.split(";")[0]?.trim().toLowerCase();
16543
+ }
16544
+ getQRCodeImageMIMETypeFromFileName(fileName) {
16545
+ fileName = fileName.toLowerCase();
16546
+ if (fileName.endsWith(".png"))
16547
+ return "image/png";
16548
+ if (fileName.endsWith(".jpeg"))
16549
+ return "image/jpeg";
16550
+ if (fileName.endsWith(".jpg"))
16551
+ return "image/jpg";
16552
+ if (fileName.endsWith(".gif"))
16553
+ return "image/gif";
16554
+ if (fileName.endsWith(".webp"))
16555
+ return "image/webp";
16556
+ if (fileName.endsWith(".bmp"))
16557
+ return "image/bmp";
16558
+ if (fileName.endsWith(".svg"))
16559
+ return "image/svg+xml";
16560
+ return void 0;
16561
+ }
16562
+ getQRCodeImageMIMEType(fileInfo, mimeType) {
16563
+ const detectedMIMEType = this.normalizeMIMEType(mimeType);
16564
+ const declaredMIMEType = this.normalizeMIMEType(fileInfo.type);
16565
+ const fileNameMIMEType = this.getQRCodeImageMIMETypeFromFileName(fileInfo.name);
16566
+ if (this.isSupportedQRCodeImageFileType(detectedMIMEType))
16567
+ return detectedMIMEType;
16568
+ if (this.isSupportedQRCodeImageFileType(declaredMIMEType))
16569
+ return declaredMIMEType;
16570
+ if (fileNameMIMEType !== void 0)
16571
+ return fileNameMIMEType;
16572
+ return detectedMIMEType ?? declaredMIMEType;
16573
+ }
16574
+ isSupportedQRCodeImageFileType(MIMEType) {
16575
+ switch (MIMEType) {
16576
+ case void 0:
16577
+ return false;
16578
+ case "image/png":
16579
+ case "image/jpeg":
16580
+ case "image/jpg":
16581
+ case "image/gif":
16582
+ case "image/webp":
16583
+ case "image/bmp":
16584
+ case "image/svg":
16585
+ case "image/svg+xml":
16586
+ return true;
16587
+ }
16588
+ return false;
16362
16589
  }
16363
16590
  async expandQRCodeImageFiles(FileInfos) {
16364
16591
  const expandedFileInfos = new Array();
16365
16592
  for (const fileInfo of FileInfos) {
16366
- if (fileInfo.data != null && this.isSupportedQRCodeImageFile(fileInfo)) {
16367
- const qrText = await readQRCodeTextFromImage(fileInfo.data, fileInfo.type);
16593
+ const mimeType = this.getQRCodeImageMIMEType(fileInfo);
16594
+ if (fileInfo.data != null && this.isSupportedQRCodeImageFileType(mimeType)) {
16595
+ const qrText = await readQRCodeTextFromImage(
16596
+ fileInfo.data,
16597
+ mimeType
16598
+ );
16368
16599
  if (qrText != null) {
16369
- const extractedText = this.tryExtractSignedDataTextFromXML(
16370
- this.tryExtractChargeTransparencyTextFromURL(qrText)
16371
- );
16372
16600
  expandedFileInfos.push({
16373
- name: this.textFileNameForQRCodeContent(fileInfo.name, extractedText),
16601
+ name: this.textFileNameForQRCodeContent(fileInfo.name, qrText),
16374
16602
  path: fileInfo.path,
16375
16603
  type: "text/plain",
16376
- data: new TextEncoder().encode(extractedText),
16604
+ data: new TextEncoder().encode(qrText),
16377
16605
  info: "Text extracted from QR code image"
16378
16606
  });
16379
16607
  continue;
@@ -16523,11 +16751,13 @@ var Chargy = class {
16523
16751
  "@id": evse["@id"],
16524
16752
  "description": evse.description,
16525
16753
  "sockets": evseView["sockets"],
16526
- "meter": {
16754
+ "energyMeter": {
16527
16755
  "@id": meter["@id"],
16528
16756
  "vendor": meterView["vendor"],
16529
16757
  "model": meter.model,
16530
- "firmwareVersion": meter.firmwareVersion,
16758
+ "firmware": {
16759
+ "version": meter.firmware?.version
16760
+ },
16531
16761
  "signatureFormat": meter.signatureFormat,
16532
16762
  "publicKey": {
16533
16763
  "algorithm": publicKey.algorithm,
@@ -16570,55 +16800,42 @@ var Chargy = class {
16570
16800
  if (FileInfo.data != null && FileInfo.data.byteLength > 0) {
16571
16801
  try {
16572
16802
  const filetype = await fileTypeFromBuffer(FileInfo.data);
16573
- if (filetype?.mime == void 0) {
16574
- if (this.isSupportedQRCodeImageFile(FileInfo))
16575
- expandedFileInfos.push({
16576
- name: FileInfo.name,
16577
- data: FileInfo.data,
16578
- type: FileInfo.type,
16579
- info: "QR code image file"
16580
- });
16581
- else if (FileInfo.name.endsWith(".chargy"))
16582
- expandedFileInfos.push({
16583
- name: FileInfo.name,
16584
- data: FileInfo.data,
16585
- info: ".chargy file"
16586
- });
16587
- else
16588
- expandedFileInfos.push({
16589
- name: FileInfo.name,
16590
- data: FileInfo.data,
16591
- exception: "Unknown file type!"
16592
- });
16803
+ const mimeType = this.getQRCodeImageMIMEType(FileInfo, filetype?.mime);
16804
+ if (this.isSupportedQRCodeImageFileType(mimeType)) {
16805
+ expandedFileInfos.push({
16806
+ name: FileInfo.name,
16807
+ data: FileInfo.data,
16808
+ type: FileInfo.type ?? mimeType,
16809
+ info: "QR code image file"
16810
+ });
16593
16811
  continue;
16594
- } else if (filetype.mime === "text/xml" || filetype.mime === "application/xml") {
16812
+ } else if (FileInfo.name.endsWith(".chargy")) {
16595
16813
  expandedFileInfos.push({
16596
16814
  name: FileInfo.name,
16597
16815
  data: FileInfo.data,
16598
- info: "XML file"
16816
+ info: ".chargy file"
16599
16817
  });
16600
16818
  continue;
16601
- } else if (filetype.mime === "text/json" || filetype.mime === "application/json") {
16819
+ } else if (mimeType === "text/xml" || mimeType === "application/xml") {
16602
16820
  expandedFileInfos.push({
16603
16821
  name: FileInfo.name,
16604
16822
  data: FileInfo.data,
16605
- info: "JSON file"
16823
+ info: "XML file"
16606
16824
  });
16607
16825
  continue;
16608
- } else if (this.isSupportedQRCodeImageFile(FileInfo, filetype.mime)) {
16826
+ } else if (mimeType === "text/json" || mimeType === "application/json") {
16609
16827
  expandedFileInfos.push({
16610
16828
  name: FileInfo.name,
16611
16829
  data: FileInfo.data,
16612
- type: filetype.mime,
16613
- info: "QR code image file"
16830
+ info: "JSON file"
16614
16831
  });
16615
16832
  continue;
16616
- } else if (filetype.mime === "application/zip" || filetype.mime === "application/x-bzip2" || filetype.mime === "application/gzip" || filetype.mime === "application/x-tar") {
16833
+ } else if (mimeType === "application/zip" || mimeType === "application/x-bzip2" || mimeType === "application/gzip" || mimeType === "application/x-tar") {
16617
16834
  try {
16618
16835
  const compressedFiles = await this.extractArchive(
16619
16836
  FileInfo.name,
16620
16837
  FileInfo.data,
16621
- filetype.mime
16838
+ mimeType
16622
16839
  );
16623
16840
  if (compressedFiles.length == 0)
16624
16841
  continue;
@@ -16690,6 +16907,12 @@ var Chargy = class {
16690
16907
  }
16691
16908
  continue;
16692
16909
  }
16910
+ expandedFileInfos.push({
16911
+ name: FileInfo.name,
16912
+ data: FileInfo.data,
16913
+ exception: "Unknown file type!"
16914
+ });
16915
+ continue;
16693
16916
  } catch (exception) {
16694
16917
  expandedFileInfos.push({
16695
16918
  name: FileInfo.name,
@@ -16845,11 +17068,12 @@ var Chargy = class {
16845
17068
  //#endregion
16846
17069
  //#region DetectAndConvertContentFormat(FileInfos)
16847
17070
  async DetectAndConvertContentFormat(FileInfos) {
16848
- if (FileInfos.length == 0) return {
16849
- status: "NoChargeTransparencyRecordsFound" /* NoChargeTransparencyRecordsFound */,
16850
- message: this.GetMultilanguageText("No charge transparency records found!"),
16851
- certainty: 0
16852
- };
17071
+ if (FileInfos.length == 0)
17072
+ return {
17073
+ status: "NoChargeTransparencyRecordsFound" /* NoChargeTransparencyRecordsFound */,
17074
+ message: this.GetMultilanguageText("No charge transparency records found!"),
17075
+ certainty: 0
17076
+ };
16853
17077
  let expandedFiles = new Array();
16854
17078
  const processedFiles = new Array();
16855
17079
  if (FileInfos.length > 0) {
@@ -17022,42 +17246,40 @@ var Chargy = class {
17022
17246
  } else if (textContent.startsWith("{") && textContent.endsWith("}")) {
17023
17247
  try {
17024
17248
  const JSONContent = JSON.parse(textContent);
17025
- if (typeof JSONContent !== "object" || JSONContent === null)
17026
- throw new Error("Parsed JSON content is not an object or array!");
17027
- if (isMandatoryJSONObject(JSONContent)) {
17028
- const JSONContext = JSONContent["@context"];
17029
- if (IsAChargeTransparencyLiveLink(JSONContent)) {
17030
- JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
17249
+ if (JSONContent === null || typeof JSONContent !== "object" || !isMandatoryJSONObject(JSONContent))
17250
+ throw new Error("Parsed JSON content is not a JSON object!");
17251
+ const JSONContext = JSONContent["@context"];
17252
+ if (IsAChargeTransparencyLiveLink(JSONContent)) {
17253
+ JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
17254
+ processedFile.result = JSONContent;
17255
+ } else if (isMandatoryString(JSONContext)) {
17256
+ if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
17031
17257
  processedFile.result = JSONContent;
17032
- } else if (isMandatoryString(JSONContext)) {
17033
- if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
17034
- processedFile.result = JSONContent;
17035
- else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
17036
- processedFile.result = JSONContent;
17037
- else if (JSONContext.startsWith("https://www.lichtblick.de/contexts/charging-station-json") || JSONContext.startsWith("https://www.eneco.com/contexts/charging-station-json") || JSONContext.startsWith("https://www.chargeit-mobility.com/contexts/charging-station-json")) {
17038
- processedFile.result = new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent);
17039
- }
17040
- } else {
17041
- const results = [
17042
- new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent),
17043
- new ChargePoint(this).TryToParseChargepointFormat(JSONContent),
17044
- await new OCPI(this).tryToParseOCPIFormat(JSONContent)
17045
- ];
17046
- const filteredResults = results.filter((ctr) => {
17047
- return isISessionCryptoResult1(ctr);
17048
- });
17049
- const sortedResults = filteredResults.sort((ctr1, ctr2) => {
17050
- if (ctr1.certainty > ctr2.certainty) {
17051
- return -1;
17052
- }
17053
- if (ctr1.certainty < ctr2.certainty) {
17054
- return 1;
17055
- }
17056
- return 0;
17057
- });
17058
- if (sortedResults.length >= 1 && sortedResults[0])
17059
- processedFile.result = sortedResults[0];
17258
+ else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
17259
+ processedFile.result = JSONContent;
17260
+ else if (JSONContext.startsWith("https://www.lichtblick.de/contexts/charging-station-json") || JSONContext.startsWith("https://www.eneco.com/contexts/charging-station-json") || JSONContext.startsWith("https://www.chargeit-mobility.com/contexts/charging-station-json")) {
17261
+ processedFile.result = new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent);
17060
17262
  }
17263
+ } else {
17264
+ const results = [
17265
+ new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent),
17266
+ new ChargePoint(this).TryToParseChargepointFormat(JSONContent),
17267
+ await new OCPI(this).tryToParseOCPIFormat(JSONContent)
17268
+ ];
17269
+ const filteredResults = results.filter((ctr) => {
17270
+ return isISessionCryptoResult1(ctr);
17271
+ });
17272
+ const sortedResults = filteredResults.sort((ctr1, ctr2) => {
17273
+ if (ctr1.certainty > ctr2.certainty) {
17274
+ return -1;
17275
+ }
17276
+ if (ctr1.certainty < ctr2.certainty) {
17277
+ return 1;
17278
+ }
17279
+ return 0;
17280
+ });
17281
+ if (sortedResults.length >= 1 && sortedResults[0])
17282
+ processedFile.result = sortedResults[0];
17061
17283
  }
17062
17284
  } catch (exception) {
17063
17285
  processedFile.result = {
@@ -17101,7 +17323,7 @@ var Chargy = class {
17101
17323
  if (processedFileResult.end != null && processedFileResult.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < processedFileResult.end))
17102
17324
  mergedCTR.end = processedFileResult.end;
17103
17325
  mergedCTR.description ??= processedFileResult.description;
17104
- mergedCTR.contract ??= processedFileResult.contract;
17326
+ mergedCTR.contracts ??= processedFileResult.contracts;
17105
17327
  if (!mergedCTR.chargingStationOperators)
17106
17328
  mergedCTR.chargingStationOperators = processedFileResult.chargingStationOperators;
17107
17329
  else if (processedFileResult.chargingStationOperators)
@@ -17132,7 +17354,7 @@ var Chargy = class {
17132
17354
  else if (processedFileResult.mediationServices)
17133
17355
  for (const mediationService of processedFileResult.mediationServices)
17134
17356
  mergedCTR.mediationServices.push(mediationService);
17135
- } else if (IsAPublicKeyInfo(processedFileResult)) {
17357
+ } else if (IsAPublicKey(processedFileResult)) {
17136
17358
  mergedCTR.publicKeys ??= new Array();
17137
17359
  mergedCTR.publicKeys.push(processedFileResult);
17138
17360
  } else if (IsAPublicKeyLookup(processedFileResult)) {
@@ -17180,11 +17402,11 @@ var Chargy = class {
17180
17402
  if (chargingPool.chargingStations) {
17181
17403
  for (const chargingStation of chargingPool.chargingStations) {
17182
17404
  this.chargingStations.push(chargingStation);
17183
- for (const EVSE of chargingStation.EVSEs) {
17405
+ for (const EVSE of chargingStation.EVSEs ?? []) {
17184
17406
  EVSE.chargingStation = chargingStation;
17185
17407
  EVSE.chargingStationId = chargingStation["@id"];
17186
17408
  this.EVSEs.push(EVSE);
17187
- for (const meter of EVSE.meters) {
17409
+ for (const meter of EVSE.energyMeters ?? []) {
17188
17410
  meter.EVSE = EVSE;
17189
17411
  meter.EVSEId = EVSE["@id"];
17190
17412
  meter.chargingStation = chargingStation;
@@ -17199,11 +17421,11 @@ var Chargy = class {
17199
17421
  if (chargingStationOperator.chargingStations) {
17200
17422
  for (const chargingStation of chargingStationOperator.chargingStations) {
17201
17423
  this.chargingStations.push(chargingStation);
17202
- for (const EVSE of chargingStation.EVSEs) {
17424
+ for (const EVSE of chargingStation.EVSEs ?? []) {
17203
17425
  EVSE.chargingStation = chargingStation;
17204
17426
  EVSE.chargingStationId = chargingStation["@id"];
17205
17427
  this.EVSEs.push(EVSE);
17206
- for (const meter of EVSE.meters) {
17428
+ for (const meter of EVSE.energyMeters ?? []) {
17207
17429
  meter.EVSE = EVSE;
17208
17430
  meter.EVSEId = EVSE["@id"];
17209
17431
  meter.chargingStation = chargingStation;
@@ -17216,7 +17438,7 @@ var Chargy = class {
17216
17438
  if (chargingStationOperator.EVSEs) {
17217
17439
  for (const EVSE of chargingStationOperator.EVSEs) {
17218
17440
  this.EVSEs.push(EVSE);
17219
- for (const meter of EVSE.meters) {
17441
+ for (const meter of EVSE.energyMeters ?? []) {
17220
17442
  meter.EVSE = EVSE;
17221
17443
  meter.EVSEId = EVSE["@id"];
17222
17444
  this.meters.push(meter);
@@ -17231,11 +17453,11 @@ var Chargy = class {
17231
17453
  if (chargingPool.chargingStations) {
17232
17454
  for (const chargingStation of chargingPool.chargingStations) {
17233
17455
  this.chargingStations.push(chargingStation);
17234
- for (const EVSE of chargingStation.EVSEs) {
17456
+ for (const EVSE of chargingStation.EVSEs ?? []) {
17235
17457
  EVSE.chargingStation = chargingStation;
17236
17458
  EVSE.chargingStationId = chargingStation["@id"];
17237
17459
  this.EVSEs.push(EVSE);
17238
- for (const meter of EVSE.meters) {
17460
+ for (const meter of EVSE.energyMeters ?? []) {
17239
17461
  meter.EVSE = EVSE;
17240
17462
  meter.EVSEId = EVSE["@id"];
17241
17463
  meter.chargingStation = chargingStation;
@@ -17250,11 +17472,11 @@ var Chargy = class {
17250
17472
  if (this.internalCTR.chargingStations) {
17251
17473
  for (const chargingStation of this.internalCTR.chargingStations) {
17252
17474
  this.chargingStations.push(chargingStation);
17253
- for (const EVSE of chargingStation.EVSEs) {
17475
+ for (const EVSE of chargingStation.EVSEs ?? []) {
17254
17476
  EVSE.chargingStation = chargingStation;
17255
17477
  EVSE.chargingStationId = chargingStation["@id"];
17256
17478
  this.EVSEs.push(EVSE);
17257
- for (const meter of EVSE.meters) {
17479
+ for (const meter of EVSE.energyMeters ?? []) {
17258
17480
  meter.EVSE = EVSE;
17259
17481
  meter.EVSEId = EVSE["@id"];
17260
17482
  meter.chargingStation = chargingStation;
@@ -17262,8 +17484,8 @@ var Chargy = class {
17262
17484
  this.meters.push(meter);
17263
17485
  }
17264
17486
  }
17265
- if (chargingStation.meters) {
17266
- for (const meter of chargingStation.meters) {
17487
+ if (chargingStation.energyMeters) {
17488
+ for (const meter of chargingStation.energyMeters ?? []) {
17267
17489
  meter.chargingStation = chargingStation;
17268
17490
  meter.chargingStationId = chargingStation["@id"];
17269
17491
  this.meters.push(meter);
@@ -17290,7 +17512,7 @@ var Chargy = class {
17290
17512
  //#endregion
17291
17513
  //#region (private) hasInplausibleChargingSessionTotalEnergyMeasurement(chargingSession)
17292
17514
  hasInplausibleChargingSessionTotalEnergyMeasurement(chargingSession) {
17293
- for (const measurement of chargingSession.measurements) {
17515
+ for (const measurement of chargingSession.measurements ?? []) {
17294
17516
  if (measurement.name !== "ENERGY_TOTAL" || measurement.values.length < 2) {
17295
17517
  continue;
17296
17518
  }
@@ -17450,7 +17672,7 @@ var Chargy = class {
17450
17672
  if (ctr.end != null && ctr.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < ctr.end))
17451
17673
  mergedCTR.end = ctr.end;
17452
17674
  mergedCTR.description ??= ctr.description;
17453
- mergedCTR.contract ??= ctr.contract;
17675
+ mergedCTR.contracts ??= ctr.contracts;
17454
17676
  if (!mergedCTR.chargingStationOperators)
17455
17677
  mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
17456
17678
  else if (ctr.chargingStationOperators)
@@ -17486,18 +17708,6 @@ var Chargy = class {
17486
17708
  }
17487
17709
  };
17488
17710
 
17489
- // src/verificationResults.ts
17490
- function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
17491
- const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
17492
- if (verificationResults.length > 0)
17493
- return verificationResults;
17494
- return {
17495
- status: "Unvalidated" /* Unvalidated */,
17496
- message: noRecordsMessage,
17497
- certainty: 0
17498
- };
17499
- }
17500
-
17501
- 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 };
17711
+ 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, CreateWarning, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFTransactionTypes, OCMFv1_x, OCPI, OIDInfo, 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, base64ToBytes, buf2hex, buildMennekesSignatureData, bytesToBase64, 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, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, 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, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, unquotePCDFText, validatePCDFFields, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
17502
17712
  //# sourceMappingURL=index.js.map
17503
17713
  //# sourceMappingURL=index.js.map